]> Cypherpunks.ru repositories - goredo.git/blob - README
beb668858a62b617a044dec7ebad675ca1824c85
[goredo.git] / README
1 *goredo* redo implementation on pure Go
2
3 OVERVIEW                                               *goredo-overview*
4
5 This is pure Go implementation of DJB's redo (http://cr.yp.to/redo.html)
6 build system proposal. Originally it was just a rewrite of redo-c
7 (https://github.com/leahneukirchen/redo-c), but later most features of
8 apenwarr/redo (https://redo.readthedocs.io/en/latest/) were also
9 implemented. Why yet another implementation? It is feature full and has
10 better performance comparing to shell and Python implementation.
11
12 It passes tests from dieweltistgarnichtso.net's redo-sh.tests and
13 implementation-neutral from apenwarr/redo.
14
15 goredo is free software: see the file COPYING for copying conditions.
16 Home page: http://www.goredo.cypherpunks.ru/
17
18 INSTALL                                                 *goredo-install*
19  >
20     $ go get go.cypherpunks.ru/goredo
21     $ goredo -symlinks
22     $ export PATH=`pwd`:$PATH
23
24 If you have problems with *.golang.org's inability to verify
25 authenticity of go.cypherpunks.ru TLS connection, then you can disable
26 their usage by setting GOPRIVATE=go.cypherpunks.ru. If you still have
27 problems with the authenticity on your side, then build it manually: >
28
29     $ git clone git://git.cypherpunks.ru/goredo.git
30     $ cd goredo
31     $ git tag -v v0.7.1
32     $ git clone git://git.cypherpunks.ru/gorecfile.git
33     $ ( cd gorecfile ; git tag -v v0.4.0 )
34     $ echo "replace go.cypherpunks.ru/recfile => `pwd`/gorecfile" >> go.mod
35     $ git clone git://git.cypherpunks.ru/gotai64n.git
36     $ ( cd gotai64n ; git tag -v v0.2.0 )
37     $ echo "replace go.cypherpunks.ru/tai64n => `pwd`/gotai64n" >> go.mod
38     $ go build
39     $ ./goredo -symlinks
40     $ export PATH=`pwd`:$PATH
41
42 NOTES                                                     *goredo-notes*
43
44 * "all" target is default
45 * stdout is always captured, but no target is created if it was empty
46 * empty targets are considered always out of date
47 * .do's $3 is relative path to the file in target directory
48 * .do search goes up to / by default, but can be limited with either
49   $REDO_TOP_DIR environment variable, or by having .redo/top file in it
50 * target's completion messages are written after they finish
51 * executable .do is run as is, non-executable is run with /bin/sh -e[x]
52 * tracing (-x) can be obviously done only for non-executable .do
53 * parallizable build is done only during redo-ifchange for human
54   convenience: you can globally enable REDO_JOBS, but still do for
55   example: redo htmls infos index upload
56
57 FEATURES                                               *goredo-features*
58
59 * explicit useful and convenient checks from apenwarr/redo:
60     * check that $1 was not touched during .do execution
61     * check that stdout and $3 are not written simultaneously
62     * check that generated target was not modified "externally" outside
63       the redo, preventing its overwriting, but continuing the build
64 * targets, dependency information and their directories are explicitly
65   synced (can be disabled, should work faster)
66 * file's change is detected by comparing its ctime and BLAKE2b hash
67 * files creation is umask-friendly (unlike mkstemp() used in redo-c)
68 * parallel build with jobs limit, optionally in infinite mode
69 * coloured messages (can be disabled)
70 * verbose debug messages, including out-of-date determination, PIDs,
71   lock and jobserver acquirings/releases
72 * displaying of each target's execution time
73 * each target's stderr can be prefixed with the PID
74 * optional statusline with currently running/waiting/done jobs
75 * target's stderr can be stored on the disk with TAI64N timestamp
76   prefixes for each line. To convert them to localtime you can use either
77   tai64nlocal utility from daemontools (http://cr.yp.to/daemontools.html),
78   or similar one: >
79     $ go get go.cypherpunks.ru/tai64n/cmd/tai64nlocal
80
81 COMMANDS                                               *goredo-commands*
82
83 * redo-ifchange, redo-ifcreate, redo-always
84 * redo -- same as redo-ifchange, but forcefully and sequentially run
85   specified targets
86 * redo-log -- display TAI64N timestamped last stderr of the target
87 * redo-stamp -- record stamp dependency. Nothing more, dummy
88 * redo-cleanup -- removes either temporary, log files, or everything
89   related to goredo
90 * redo-whichdo -- .do search paths for specified target (similar to
91   apenwarr/redo): >
92     $ redo-whichdo x/y/a.b.o
93     x/y/a.b.o.do
94     x/y/default.b.o.do
95     x/y/default.o.do
96     x/y/default.do
97     x/default.b.o.do
98     x/default.o.do
99     x/default.do
100     default.b.o.do
101     default.o.do
102     default.do
103     ../default.b.o.do
104     ../default.o.do
105     ../default.do
106 * redo-dot -- dependency DOT graph generator. For example to visualize
107   your dependencies with GraphViz: >
108     $ redo target [...] # to assure that **/.redo/*.dep are filled up
109     $ redo-dot target [...] > whatever.dot
110     $ dot -Tpng whatever.dot > whatever.png # possibly add -Gsplines=ortho
111
112 FAQ                                                         *goredo-faq*
113
114     Hashing and stamping~
115
116 All targets are checksummed if their ctime differs from the previous
117 one. apenwarr/redo gives many reasons why every time checksumming is
118 bad, but in my opinion in practice all of them do not apply.
119
120 * Aggregate targets and willing to be out-of-date ones just must not
121   produce empty output files. apenwarr/*, redo-c and goredo
122   implementations consider non existing file as an out-of-date target
123 * If you really wish to produce an empty target file, just touch $3
124
125 DJB's proposal with both stdout and $3 gives that ability to control
126 your desired behaviour. Those who does not capture stdout -- failed.
127 Those who creates an empty file if no stdout was written -- failed.
128
129 redo is a tool to help people. Literally all targets can be safely
130 "redo-stamp < $3"-ed, reducing false positive out-of-dates. Of course,
131 with the correct stdout/$3 working and placing necessary results in $3,
132 instead of just silently feeding them in redo-stamp.
133
134 redo implementations are already automatically record -ifchange on .do
135 files and -ifcreate on non-existing .do files. So why they can not
136 record redo-stamp the same way implicitly? No, Zen of Python does not
137 applicable there, because -ifchange/-ifcreate contradict it already.
138
139 Modern cryptographic hash algorithms and CPUs are so fast, that even all
140 read and writes to or from hard drive arrays can be easily checksummed
141 and transparently compressed, as ZFS with LZ4 and Skein/BLAKE[23]
142 algorithms demonstrate us.
143
144 goredo includes redo-stamp, that really records the stamp in the .dep
145 file, but it does not play any role later. It is stayed just for
146 compatibility.
147
148     Can removed .do lead to permanent errors of its non existence?~
149
150 Yes, because dependency on it was recorded previously. Is it safe to
151 assume that .do-less target now is an ordinary source-file? I have no
152 confidence in such behaviour. So it is user's decision how to deal with
153 it, probably it was just his inaccuracy mistake. If you really want to
154 get rid of that dependency knowledge for foo/bar target, then just
155 remove foo/.redo/bar.dep.
156
157     Does redo-always always rebuilds target?~
158
159 goredo, together with apenwarr/redo, rebuilds target once per run.
160 Always rebuilds during every redo invocation, but only once during it
161 building. http://news.dieweltistgarnichtso.net/bin/redo-sh.html#why-built-twice
162 has other opinion, that is why its redo-sh.tests/always_rebuild_1 will
163 fail. Rebuilding of always-ed targets even during the same build process
164 ruins any redo's usability in practice.
165
166 For example if my .h file contains source code's version number, that is
167 git-describe's output and all my other files depends on that header,
168 then any redo-ifchange of .o will lead to git-describe execution, that
169 is rather heavy. Of course, because of either hashing or possible
170 redo-stamp-ing its dependants won't be rebuilt further, but build time
171 will be already ruined. If you need to rebuild TeX documents (case
172 mentioned in redo-sh's FAQ) until all references and numbers are ready,
173 then you must naturally expectedly explicitly use while cycle in your
174 .do, as apenwarr/redo already suggests.
175
176 STATE                                                     *goredo-state*
177
178 Dependency and build state is kept inside .redo subdirectory in each
179 directory related the build. Each corresponding target has its own,
180 recreated with every rebuild, .dep file. It is recfile
181 (https://www.gnu.org/software/recutils/), that could have various
182 dependency information (dep.rec with the schema included): >
183
184     Build: 80143f04-bfff-4673-950c-081d712f573d
185
186     Type: ifcreate
187     Target: foo.o.do
188
189     Type: ifchange
190     Target: default.o.do
191     Ctime: 1605721341.253305000
192     Hash: f4929732f96f11e6d4ebe94536b5edef426d00ed0146853e37a87f4295e18eda
193
194     Type: always
195
196     Type: stamp
197     Hash: 5bbdf635932cb16b9127e69b6f3872577efed338f0a4ab6f2c7ca3df6ce50cc9
198
199 USAGE                                                     *goredo-usage*
200
201 Run any of the command above with the -help.
202
203 LICENCE~
204
205 This program is free software: you can redistribute it and/or modify
206 it under the terms of the GNU General Public License as published by
207 the Free Software Foundation, version 3 of the License.
208
209 This program is distributed in the hope that it will be useful,
210 but WITHOUT ANY WARRANTY; without even the implied warranty of
211 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
212 GNU General Public License for more details.
213
214  vim: filetype=help