* .do's arguments are relative paths
* .do search goes up to / by default, but can be limited with either
REDO_TOP_DIR environment variable, or by having .redo/top file in it
-* executable .do is run as is
-* shebangless .do is run with /bin/sh -e[x]
+* target's completion messages are written after they finish
+* executable .do is run as is, non-executable is run with /bin/sh -e[x]
+* tracing (-x) can be done only for non-executable .do
FEATURES *goredo-features*
-* explicit check that stdout and $3 are not written simultaneously
-* explicit check (similar to apenwarr/redo's one) that generated target
- was not modified "externally" outside the redo, preventing its
- overwriting, but continuing the build
+* explicit useful and convenient checks from apenwarr/redo:
+ * check that $1 was not touched during .do execution
+ * check that stdout and $3 are not written simultaneously
+ * check that generated target was not modified "externally" outside
+ the redo, preventing its overwriting, but continuing the build
* targets, dependency information and their directories are explicitly
synced (can be disabled, should work faster)
-* file's change is detected by comparing its ctime and, if it differs,
- its BLAKE2b hash. Hash checking is done to prevent false positives
- (can be disabled, will work faster)
+* file's change is detected by comparing its ctime and BLAKE2b hash
* files creation is umask-friendly (unlike mkstemp() used in redo-c)
+* parallel build with jobs limit, optionally in infinite mode
* coloured messages (can be disabled)
* verbose debug messages, including out-of-date determination, PIDs,
- lock acquirings/releases
-* parallel build with jobs limit, optionally in infinite mode
-* optional display of each target's execution time
+ lock and jobserver acquirings/releases
+* displaying of each target's execution time
* each target's stderr can be displayed with the PID
+* optional statusline with currently running/waiting/done jobs
* target's stderr can be stored on the disk with TAI64N timestamp
- prefixes for each line (you can use tai64nlocal utility from
- daemontools (http://cr.yp.to/daemontools/tai64nlocal.html) to convert
- them to local time). Captures can be viewed any time later
-
+ prefixes for each line. To convert them to localtime you can use either
+ tai64nlocal utility from daemontools (http://cr.yp.to/daemontools.html)
+ or make a symlink, to use built-in slower decoder: >
+ $ ln -s goredo tai64nlocal
+<
COMMANDS *goredo-commands*
* redo-ifchange, redo-ifcreate, redo-always (useful with redo-stamp)
* redo -- same as redo-ifchange, but forcefully and *sequentially* run
specified targets
* redo-log -- display TAI64N timestamped last stderr of the target
-* redo-stamp -- record stamp dependency and consider it non out-of-date
- if stamp equals to the previous one
-* redo-cleanup -- removes either temporary, or log files, or
- everything related to goredo
+* redo-stamp -- record stamp dependency. Nothing more, just dummy
+* redo-cleanup -- removes either temporary, log files, or everything
+ related to goredo
* redo-whichdo -- .do search paths for specified target (similar to
apenwarr/redo): >
$ redo-whichdo x/y/a.b.o
default.do
../default.b.o.do
../default.o.do
+* redo-dot -- dependency DOT graph generator. For example to visualize
+ your dependencies with GraphViz: >
+ $ redo target [...] # to assure that .redo is filled up
+ $ redo-dot target [...] > whatever.dot
+ $ dot -Tpng whatever.dot > whatever.png # possibly add -Gsplines=ortho
<
+FAQ *goredo-faq*
+
+ Hashing and stamping~
+
+All targets are checksummed if their ctime differs from the previous
+ones. apenwarr/redo gives many reasons why every time checksumming is
+bad, but in my opinion in practice all of his reasons do not apply.
+
+* Aggregate targets and willing to be out-of-date ones just must not
+ produce empty output files. apenwarr/*, redo-c and goredo
+ implementations consider non existing file as an out-of-date target
+* If you really wish to produce an empty target file, just: touch $3
+
+DJB's proposal with both stdout and $3 gives that ability to control
+your desired behaviour. Those who does not capture stdout -- failed.
+Those who creates an empty file if no stdout was written -- failed.
+
+redo is a tool for helping people. Literally all targets can be safely
+"redo-stamp < $3"-ed, reducing false positive out-of-dates. Of course,
+with the correct working with stdout/$3 and placing necessary results in
+$3, instead of just silently feeding them in redo-stamp.
+
+redo implementations are already automatically records -ifchange on .do
+files and -ifcreate on non-existing .do files. So why they can not
+record redo-stamp the same way implicitly? No, Zen of Python does not
+applicable there, because -ifchange/-ifcreate contradict it already.
+
+Modern cryptographic hash algorithms and CPUs are so fast, that even all
+read and writes to or from hard drive arrays can be easily checksummed
+and transparently compressed, as ZFS with LZ4 and Skein/BLAKE[23]
+algorithms demonstrate us.
+
+goredo includes redo-stamp, that really records the stamp in the .dep
+file, but it does not play any role later. It is stayed just for
+compatibility.
+
+ Removed .do can lead to permanent errors of its non existence~
+
+That is true, because dependency on it was recorded previously. Is it
+safe to assume that .do-less target now is an ordinary source-file? I
+have no confidence in such behaviour. So it is user's decision how to
+deal with it, probably it was just his inaccuracy mistake. If you really
+want to get rid of that dependency knowledge for foo/bar target, then
+just remove foo/.redo/bar.dep.
+
STATE *goredo-state*
Dependency and build state is kept inside .redo subdirectory in each