From: Sergey Matveev Date: Thu, 15 Jan 2026 11:52:13 +0000 (+0300) Subject: Reuse documentation in usage help X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;p=goredo.git Reuse documentation in usage help --- diff --git a/doc/Jobserver b/doc/Jobserver index 06da9c8..f38cb85 100644 --- a/doc/Jobserver +++ b/doc/Jobserver @@ -21,6 +21,7 @@ bmake gmake Pass "--jobserver-auth=X,Y" arguments through $MAKEFLAGS variable. Beware that only --jobserver-style=pipe protocol is supported! + => https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html none Pass "X,Y" arguments through $REDO_JS_FD variable. Used by default, if $REDO_MAKE is not set. diff --git a/doc/cmd/Logs b/doc/cmd/Logs new file mode 100644 index 0000000..3f0aeac --- /dev/null +++ b/doc/cmd/Logs @@ -0,0 +1,61 @@ +A [Env] REDO_LOGS +A [Env] REDO_SILENT +stderr of the running targets can be kept on the disk by specifying -k +option (or by setting $REDO_LOGS=1 environment variable) to redo. You +can simultaneously use also -s option ($REDO_SILENT=1) to silence stderr +output, but still keeping it on the disk for possible further debug +investigation. *Only* the latest build is kept, previous one is +overwritten. + + $ redo -xx -k -s build-the-whole-huge-project + +Logs are stored in corresponding .redo/tgt.log file. +Each line of it is prefixed with +=> http://cr.yp.to/libtai/tai64.html TAI64N timestamp +that you can decode with tai64nlocal utility from + => http://cr.yp.to/daemontools.html daemontools +or similar one: + go install go.cypherpunks.su/tai64n/v4/cmd/tai64nlocal@latest + +When -k is in use, all environment variables, working directory, command +line arguments, start/finish times, duration, participated PIDs, return +codes are also saved in corresponding .redo/tgt.log.rec file. + +You can view any target's output with [cmd/redo-log] command (possibly +piping to tai64nlocal). -c option also shows how exactly it was started, +when started/finished and how long did it take. + +-r option enables recursive serialized indented output. When you run +redo in parallel, then all stderr (if no (-s)ilence was enabled) is +printed as it appears, mixing output from all commands, that is hard to +read and investigate. Serialized redo-log output rearranges output. I +will take example from original apenwarr's idea +=> https://apenwarr.ca/log/20181106 article +Serialized output will look like this: + + $ redo-log -r A + A: ...A stuff... + A: redo-ifchange J + J: > redo J + J: > ...J stuff... + J: > redo-ifchange X Y + X: > > redo X + X: > > ...X stuff... + X: > > done X + J: > > redo Y + Y: > > ...Y stuff... + Z: > > > redo Z + Z: > > > ...Z stuff... + Z: > > > done Z + Y: > > ...more Y stuff... + Y: > > done Y + J: > ...more J stuff... + J: > done J + A: ...more A stuff... + +It will output depth first logs. It can rearrange some "events" (redo +invocations): failed targets will be at the very end, because they are +the most interesting ones for the human. + +Pay attention that recursive output is more CPU hungry. Single target +output is literally copying of .redo/tgt.log file to stdout. diff --git a/doc/cmd/goredo b/doc/cmd/goredo new file mode 100644 index 0000000..abc72b9 --- /dev/null +++ b/doc/cmd/goredo @@ -0,0 +1,7 @@ +Usage: goredo -symlinks + +goredo expects to be called through the symbolic link to it. +Available commands: redo, redo-affects, redo-always, redo-cleanup, +redo-dep2rec, redo-depfix, redo-dot, redo-ifchange, redo-ifcreate, +redo-inode, redo-log, redo-ood, redo-sources, redo-stamp, +redo-targets, redo-whichdo. diff --git a/doc/cmd/redo b/doc/cmd/redo index 9171cbb..0a93536 100644 --- a/doc/cmd/redo +++ b/doc/cmd/redo @@ -1,3 +1,4 @@ -Forcefully and sequentially build specified targets. This is the main -command you will explicitly use from the command line. If no targets are -given, then "all" target will be used by default. +Usage: redo [-j X] [-k] [-s] [-x|-xx] [target ...] + +Unline redo-ifchange, forcefully and *sequentially* build specified targets. +If no targets specified, then use "all" one. diff --git a/doc/cmd/redo-affects b/doc/cmd/redo-affects index 9486533..3c570da 100644 --- a/doc/cmd/redo-affects +++ b/doc/cmd/redo-affects @@ -1,3 +1,3 @@ -It is not in other distributions, but it is some kind of opposite -of [cmd/redo-sources] -- shows the targets that will be affected -by specified files change. +Usage: redo-affects target [...] + +List all targets that will be affected by changing the specified ones. diff --git a/doc/cmd/redo-always b/doc/cmd/redo-always index e597fba..8564191 100644 --- a/doc/cmd/redo-always +++ b/doc/cmd/redo-always @@ -1,3 +1,5 @@ -Record current target as an always-do dependency. By definition it -should be always build. goredo tries to build it once per run. -Also look at [FAQ/redo-always]. +Usage: redo-always + +Always build current target. Unusable outside .do. +By definition it should be always build. +goredo tries to build it once per run. diff --git a/doc/cmd/redo-cleanup b/doc/cmd/redo-cleanup index da9151c..2efcd5a 100644 --- a/doc/cmd/redo-cleanup +++ b/doc/cmd/redo-cleanup @@ -1,2 +1,4 @@ -Removes either temporary ("tmp"), log files ("log"), lock files ("lock"), -or everything related to goredo ("full"). +Usage: redo-cleanup [-n] {full,log,lock,tmp} [...] + +Remove either temporary ("tmp"), log files ("log"), lock files ("lock"), +or everything (including .redo directories) related to goredo ("full"). diff --git a/doc/cmd/redo-dep2rec b/doc/cmd/redo-dep2rec index 054eb8f..6e90b93 100644 --- a/doc/cmd/redo-dep2rec +++ b/doc/cmd/redo-dep2rec @@ -1,2 +1,4 @@ -Convert specified .dep ([State]) file to recfile on stdout. +Usage: redo-dep2rec .redo/file.dep + +Convert binary .dep file to recfile and write it to stdout. Aimed to be used mainly for debugging purposes. diff --git a/doc/cmd/redo-depfix b/doc/cmd/redo-depfix index a2f9cb1..9c6387d 100644 --- a/doc/cmd/redo-depfix +++ b/doc/cmd/redo-depfix @@ -1,10 +1,15 @@ +Usage: redo-depfix + +Traverse over all .redo directories beneath and recalculate each target's +inode and hash information, rewriting dependency files. If dependency has +legacy .rec format, then it will be converted to .dep one. + When you copy your worktree to different place, then copied files ctime will change. And because recorded dependency information differs from updated ctimes, out-of-date algorithm will fallback to rereading the whole files for hash calculation, that is much slower. -If you do not want to rebuild your targets from the ground, then -redo-depfix can traverse through all dependency files and recalculate -dependency information. +If you do not want to rebuild your targets from the ground, you can +use that command. Also if it finds legacy .rec dependency files, it converts them to binary format. diff --git a/doc/cmd/redo-dot b/doc/cmd/redo-dot index 828dc05..2c547a9 100644 --- a/doc/cmd/redo-dot +++ b/doc/cmd/redo-dot @@ -1,4 +1,6 @@ -Dependency graph generator. +Usage: redo-dot target [...] + +Write dependency DOT graph to stdout. => https://en.wikipedia.org/wiki/DOT_(graph_description_language) DOT For example to visualize your dependencies with GraphViz: diff --git a/doc/cmd/redo-ifchange b/doc/cmd/redo-ifchange index 4d22c23..8976135 100644 --- a/doc/cmd/redo-ifchange +++ b/doc/cmd/redo-ifchange @@ -1,4 +1,6 @@ -Rebuild specified targets if they are out-of-date and record them as +Usage: redo-ifchange [-j X] [-k] [-s] [-x|-xx] target [...] + +(Re)build specified targets if they are out-of-date and record them as a dependency for the currently run target. This is the main command you will use in .do files. diff --git a/doc/cmd/redo-ifcreate b/doc/cmd/redo-ifcreate index 71513c7..eaa19e4 100644 --- a/doc/cmd/redo-ifcreate +++ b/doc/cmd/redo-ifcreate @@ -1,3 +1,5 @@ -Record the non-existent file dependency for the currently run -target. Target will be rebuilt if any of the given files appear. -Can be used only inside .do file. +Usage: redo-ifcreate target [...] + +Record ifcreate dependency for current target. +Target will be rebuilt if any of the given files appear. +Unusable outside .do. diff --git a/doc/cmd/redo-inode b/doc/cmd/redo-inode new file mode 100644 index 0000000..ce28bc3 --- /dev/null +++ b/doc/cmd/redo-inode @@ -0,0 +1,3 @@ +Usage: redo-inode target [...] + +Just calculate inode information about each target and print in recfile format. diff --git a/doc/cmd/redo-log b/doc/cmd/redo-log index 01a75a5..4aa1c1d 100644 --- a/doc/cmd/redo-log +++ b/doc/cmd/redo-log @@ -1,61 +1,7 @@ -A [Env] REDO_LOGS -A [Env] REDO_SILENT -stderr of the running targets can be kept on the disk by specifying -k -option (or by setting $REDO_LOGS=1 environment variable) to redo. You -can simultaneously use also -s option ($REDO_SILENT=1) to silence stderr -output, but still keeping it on the disk for possible further debug -investigation. *Only* the latest build is kept, previous one is -overwritten. +Usage: redo-log [-c] [-r] target [| tai64nlocal] - $ redo -xx -k -s build-the-whole-huge-project - -Logs are stored in corresponding .redo/tgt.log file. -Each line of it is prefixed with -=> http://cr.yp.to/libtai/tai64.html TAI64N timestamp -that you can decode with tai64nlocal utility from - => http://cr.yp.to/daemontools.html daemontools -or similar one: - go install go.cypherpunks.su/tai64n/v4/cmd/tai64nlocal@latest - -When -k is in use, all environment variables, working directory, command -line arguments, start/finish times, duration, participated PIDs, return -codes are also saved in corresponding .redo/tgt.log.rec file. - -You can view any target's output with redo-log command (possibly piping -to tai64nlocal). -c option also shows how exactly it was started, when -started/finished and how long did it take. - --r option enables recursive serialized indented output. When you run -redo in parallel, then all stderr (if no (-s)ilence was enabled) is -printed as it appears, mixing output from all commands, that is hard to -read and investigate. Serialized redo-log output rearranges output. I -will take example from original apenwarr's idea -=> https://apenwarr.ca/log/20181106 article -Serialized output will look like this: - - $ redo-log -r A - A: ...A stuff... - A: redo-ifchange J - J: > redo J - J: > ...J stuff... - J: > redo-ifchange X Y - X: > > redo X - X: > > ...X stuff... - X: > > done X - J: > > redo Y - Y: > > ...Y stuff... - Z: > > > redo Z - Z: > > > ...Z stuff... - Z: > > > done Z - Y: > > ...more Y stuff... - Y: > > done Y - J: > ...more J stuff... - J: > done J - A: ...more A stuff... - -It will output depth first logs. It can rearrange some "events" (redo -invocations): failed targets will be at the very end, because they are -the most interesting ones for the human. - -Pay attention that recursive output is more CPU hungry. Single target -output is literally copying of .redo/tgt.log file to stdout. +Display kept target's stderr with TAI64N timestamped lines. Only the +last build is kept. You must enable stderr keeping with either -k, +or REDO_LOGS=1. -c option show the exact command invoked, start and +finish time. -r option recursively and linearly show also all deeper +redo calls and their [Logs]. diff --git a/doc/cmd/redo-ood b/doc/cmd/redo-ood index 03a48ae..1833d13 100644 --- a/doc/cmd/redo-ood +++ b/doc/cmd/redo-ood @@ -1 +1,3 @@ -Similarly to [cmd/redo-targets] shows the targets, but only out-of-date ones. +Usage: redo-ood [target ...] + +Similar to redo-targets, but lists out-of-date ones. diff --git a/doc/cmd/redo-sources b/doc/cmd/redo-sources index a8aad69..71e33eb 100644 --- a/doc/cmd/redo-sources +++ b/doc/cmd/redo-sources @@ -1 +1,3 @@ +Usage: redo-sources [target ...] + Recursively show all source files the given targets depend on. diff --git a/doc/cmd/redo-stamp b/doc/cmd/redo-stamp index 0dbee5c..b4500e4 100644 --- a/doc/cmd/redo-stamp +++ b/doc/cmd/redo-stamp @@ -1,4 +1,6 @@ -Record "stamp" dependency. It reads stdin and stores its hash -in the dependency database. It is not used anyhow, it is dummy. -Read about [Stamping] in the FAQ. It is left only for -compatibility with some other implementations. +Usage: redo-stamp <[$3] + +Record stamp dependency for current target. Unusable outside .do. +It reads stdin and stores its hash in the dependency database. +It is not used anyhow, it is dummy, left only for compatibility +with some other implementations. diff --git a/doc/cmd/redo-targets b/doc/cmd/redo-targets index 10ad2dc..3a66aa3 100644 --- a/doc/cmd/redo-targets +++ b/doc/cmd/redo-targets @@ -1 +1,3 @@ -Show all known targets, possibly limited by specified directories. +Usage: redo-targets [target ...] + +List all currently known targets, possibly limited by specified directories. diff --git a/doc/cmd/redo-whichdo b/doc/cmd/redo-whichdo index 82f0891..f078d1f 100644 --- a/doc/cmd/redo-whichdo +++ b/doc/cmd/redo-whichdo @@ -1,4 +1,8 @@ -Display .do search paths for specified target (similar to apenwarr/redo): +Usage: redo-whichdo target + +Display .do search paths for specified target. Exits successfully +if the last .do in output if the found existing one. +Similar to apenwarr/redo: $ redo-whichdo x/y/a.b.o x/y/a.b.o.do diff --git a/usage.go b/usage.go index 5088201..399e85b 100644 --- a/usage.go +++ b/usage.go @@ -16,13 +16,15 @@ package main import ( + "embed" "flag" "fmt" "os" + "strings" ) const ( - Version = "2.8.0" + Version = "2.8.1" Warranty = `Copyright (C) 2020-2026 Sergey Matveev This program is free software: you can redistribute it and/or modify @@ -38,95 +40,21 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .` ) -func usage(cmd string) { - var d string - switch cmd { - case CmdNameRedo: - d = `Usage: redo [-j X] [-k] [-s] [-x|-xx] [options] [target ...] - -Forcefully and *sequentially* build specified targets. -If no targets specified, then use "all" one.` - case CmdNameRedoIfchange: - d = `Usage: redo-ifchange [-j X] [-k] [-s] [-x|-xx] target [...] - -Build specified targets in parallel, if they are changed. -Record them as dependencies for current target.` - case CmdNameRedoIfcreate: - d = `Usage: redo-ifcreate target [...] - -Record ifcreate dependency for current target. Unusable outside .do.` - case CmdNameRedoAlways: - d = `Usage: redo-always - -Always build current target. Unusable outside .do.` - case CmdNameRedoCleanup: - d = `Usage: redo-cleanup [-n] {full,log,lock,tmp} [...] - -Remove either all of goredo's related temporary files, or kept stderr -logs, or lock files, or everything (including .redo directories) related.` - case CmdNameRedoLog: - d = `Usage: redo-log [-c] [-r] target [ | tai64nlocal ] - -Display kept target's stderr with TAI64N timestamped lines. Only the -last build is kept. You must enable stderr keeping with either -logs, -or REDO_LOGS=1. -c option show the exact command invoked, start and -finish time. -r option recursively and linearly show also all deeper -redo calls and their logs.` - case CmdNameRedoDot: - d = `Usage: redo-dot target [...] - -Write dependency DOT graph to stdout.` - case CmdNameRedoStamp: - d = `Usage: redo-stamp < [$3] - -Record stamp dependency for current target. Unusable outside .do. -Stamp dependency does not play any role, as all targets are hashed -anyway.` - case CmdNameRedoWhichdo: - d = `Usage: redo-whichdo target - -Display .do search paths for specified target. Exits successfully -if the last .do in output if the found existing one.` - case CmdNameRedoTargets: - d = `Usage: redo-targets [target ...] +//go:embed doc/cmd/goredo doc/cmd/redo* +var cmdDocs embed.FS -List all currently known targets.` - case CmdNameRedoSources: - d = `Usage: redo-sources [target ...] - -List all currently known source files.` - case CmdNameRedoOOD: - d = `Usage: redo-ood [target ...] - -List all currently known out-of-date targets.` - case CmdNameRedoAffects: - d = `Usage: redo-affects target [...] - -List all targets that will be affected by changing the specified ones.` - case CmdNameRedoDep2Rec: - d = `Usage: redo-dep2rec .../.redo/file.dep - -Convert binary .dep file to recfile and write it to stdout.` - case CmdNameRedoDepFix: - d = `Usage: redo-depfix - -Traverse over all .redo directories beneath and recalculate each target's -inode and hash information, rewriting dependency files. If dependency has -legacy .rec format, then it will be converted to .dep one.` - case CmdNameRedoInode: - d = `Usage: redo-inode target [...] - -Just calculate inode information about each target and print in recfile format.` - default: - d = `Usage: goredo -symlinks - -goredo expects to be called through the symbolic link to it. -Available commands: redo, redo-affects, redo-always, redo-cleanup, -redo-dep2rec, redo-depfix, redo-dot, redo-ifchange, redo-ifcreate, -redo-inode, redo-log, redo-ood, redo-sources, redo-stamp, -redo-targets, redo-whichdo.` +func usage(cmd string) { + data, err := cmdDocs.ReadFile("doc/cmd/" + cmd) + if err != nil { + data, _ = cmdDocs.ReadFile("doc/cmd/goredo") + } + for line := range strings.SplitSeq(string(data), "\n") { + if len(line) > 0 && line[len(line)-1] == '\r' { + continue + } + fmt.Fprintln(os.Stderr, line) } - fmt.Fprintf(os.Stderr, "%s\n\nCommon options:\n", d) + fmt.Fprintln(os.Stderr, "Common options:") flag.PrintDefaults() fmt.Fprintln(os.Stderr, ` Additional environment variables: