From 2e85fe511f4f0410e4b8a1dcdb127396b7f3f7c0 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Fri, 30 Jul 2021 16:15:40 +0300 Subject: [PATCH] No flags for not appropriate commands --- cleanup.go | 11 ++++-- doc/cmds.texi | 6 +-- doc/news.texi | 15 +++++++ js.go | 11 +++++- log.go | 25 +++++++++--- main.go | 107 +++++++++++++++++++++++++++++++------------------- run.go | 22 +++++++++-- status.go | 10 ++++- usage.go | 41 ++++++++++--------- 9 files changed, 172 insertions(+), 76 deletions(-) diff --git a/cleanup.go b/cleanup.go index 61f028f..52f1496 100644 --- a/cleanup.go +++ b/cleanup.go @@ -34,9 +34,14 @@ const ( CleanupTmp = "tmp" ) -var ( - DryRun = flag.Bool("dry-run", false, "do no delete files during cleanup, just show them") -) +var DryRun *bool + +func init() { + if CmdName() != CmdNameRedoCleanup { + return + } + DryRun = flag.Bool("n", false, "do no delete files during cleanup, just show them") +} func redoDirClean(root, what string) error { root, err := filepath.Abs(root) diff --git a/doc/cmds.texi b/doc/cmds.texi index d76bf65..4c39609 100644 --- a/doc/cmds.texi +++ b/doc/cmds.texi @@ -31,14 +31,14 @@ With @option{-j} option you can enable parallel builds, probably with an infinite number of workers (@code{=0}). Also you can set @env{$REDO_JOBS} to automatically apply that setting globally. -With @option{-logs} (@env{$REDO_LOGS=1}) option you can capture job's +With @option{-k} (@env{$REDO_LOGS=1}) option you can capture job's @code{stderr} on the disk and read it later with @command{redo-log} command. Log's lines have @url{http://cr.yp.to/libtai/tai64.html, TAI64N} timestamp. You can decode it with @command{tai64nlocal} utility from @url{http://cr.yp.to/daemontools.html, daemontools}, or similar one: @code{go get go.cypherpunks.ru/tai64n/cmd/tai64nlocal}. -@option{-silent} (@env{$REDO_SILENT=1}) omits @code{stderr} printing at -all, but you can still capture it with @option{-logs}. +@option{-s} (@env{$REDO_SILENT=1}) omits @code{stderr} printing at +all, but you can still capture it with @option{-k}. @option{-log-pid} (@env{$REDO_LOG_PID=1}) can be used to prefix job's @code{stderr} with the PID, that could be useful during parallel builds. diff --git a/doc/news.texi b/doc/news.texi index 6496554..cb1622a 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -1,6 +1,21 @@ @node News @unnumbered News +@anchor{Release 1.9.0} +@section Release 1.9.0 +@itemize +@item + Do not enable command lines options not applicable to the command. + For example @option{-j} option is only applicable to @command{redo} + and @command{redo-ifchange} commands. +@item + @itemize + @item @option{-dry-run} option is renamed to @option{-n} + @item @option{-logs} option is renamed to @option{-k} + @item @option{-silent} option is renamed to @option{-s} + @end itemize +@end itemize + @anchor{Release 1.8.0} @section Release 1.8.0 @itemize diff --git a/js.go b/js.go index e80736f..ba5cff1 100644 --- a/js.go +++ b/js.go @@ -69,9 +69,18 @@ var ( jsTokens map[byte]int jsTokensM sync.Mutex - flagJobs = flag.Int("j", -1, fmt.Sprintf("number of parallel jobs (0=inf, <0=1) (%s)", EnvJobs)) + flagJobs *int ) +func init() { + cmdName := CmdName() + if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) { + return + } + flagJobs = flag.Int("j", -1, + fmt.Sprintf("number of parallel jobs (0=inf, <0=1) (%s)", EnvJobs)) +} + func jsStart(jobsEnv string) { jobs := uint64(1) var err error diff --git a/log.go b/log.go index 4d8a982..3064a7a 100644 --- a/log.go +++ b/log.go @@ -61,12 +61,12 @@ var ( CReset string CNone string = "NONE" - flagNoProgress = flag.Bool("no-progress", false, fmt.Sprintf("no progress printing (%s=1), also implies -no-status", EnvNoProgress)) flagDebug = flag.Bool("d", false, fmt.Sprintf("enable debug logging (%s=1)", EnvDebug)) - flagLogWait = flag.Bool("log-wait", false, fmt.Sprintf("enable wait messages logging (%s=1)", EnvLogWait)) - flagLogLock = flag.Bool("log-lock", false, fmt.Sprintf("enable lock messages logging (%s=1)", EnvLogLock)) - flagLogPid = flag.Bool("log-pid", false, fmt.Sprintf("append PIDs (%s=1)", EnvLogPid)) - flagLogJS = flag.Bool("log-js", false, fmt.Sprintf("enable jobserver messages logging (%s=1)", EnvLogJS)) + flagNoProgress *bool + flagLogWait *bool + flagLogLock *bool + flagLogPid *bool + flagLogJS *bool LogMutex sync.Mutex KeyEraseLine string @@ -84,6 +84,21 @@ func init() { CJS = string(t.Escape.White) CReset = string(t.Escape.Reset) KeyEraseLine = fmt.Sprintf("%s[K", CReset[0:1]) + + cmdName := CmdName() + if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) { + return + } + flagNoProgress = flag.Bool("no-progress", false, + fmt.Sprintf("no progress printing (%s=1), also implies -no-status", EnvNoProgress)) + flagLogWait = flag.Bool("log-wait", false, + fmt.Sprintf("enable wait messages logging (%s=1)", EnvLogWait)) + flagLogLock = flag.Bool("log-lock", false, + fmt.Sprintf("enable lock messages logging (%s=1)", EnvLogLock)) + flagLogPid = flag.Bool("log-pid", false, + fmt.Sprintf("append PIDs (%s=1)", EnvLogPid)) + flagLogJS = flag.Bool("log-js", false, + fmt.Sprintf("enable jobserver messages logging (%s=1)", EnvLogJS)) } func erasedStatus(s, end string) string { diff --git a/main.go b/main.go index 3a7088d..0bb9357 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,23 @@ import ( "golang.org/x/sys/unix" ) +const ( + CmdNameGoredo = "goredo" + CmdNameRedo = "redo" + CmdNameRedoAffects = "redo-affects" + CmdNameRedoAlways = "redo-always" + CmdNameRedoCleanup = "redo-cleanup" + CmdNameRedoDot = "redo-dot" + CmdNameRedoIfchange = "redo-ifchange" + CmdNameRedoIfcreate = "redo-ifcreate" + CmdNameRedoLog = "redo-log" + CmdNameRedoOOD = "redo-ood" + CmdNameRedoSources = "redo-sources" + CmdNameRedoStamp = "redo-stamp" + CmdNameRedoTargets = "redo-targets" + CmdNameRedoWhichdo = "redo-whichdo" +) + var ( Cwd string BuildUUID string @@ -61,10 +78,19 @@ func mustParseFd(v, name string) *os.File { return fd } +func CmdName() string { + return path.Base(os.Args[0]) +} + func main() { version := flag.Bool("version", false, "print version") warranty := flag.Bool("warranty", false, "print warranty information") - symlinks := flag.Bool("symlinks", false, "create necessary symlinks in current directory") + + var symlinks *bool + cmdName := CmdName() + if cmdName == "goredo" { + symlinks = flag.Bool("symlinks", false, "create necessary symlinks in current directory") + } flag.Usage = func() { usage(os.Args[0]) } flag.Parse() @@ -76,22 +102,22 @@ func main() { fmt.Println("goredo", Version, "built with", runtime.Version()) return } - if *symlinks { + if cmdName == CmdNameGoredo && *symlinks { rc := 0 for _, cmdName := range []string{ - "redo", - "redo-affects", - "redo-always", - "redo-cleanup", - "redo-dot", - "redo-ifchange", - "redo-ifcreate", - "redo-log", - "redo-ood", - "redo-sources", - "redo-stamp", - "redo-targets", - "redo-whichdo", + CmdNameRedo, + CmdNameRedoAffects, + CmdNameRedoAlways, + CmdNameRedoCleanup, + CmdNameRedoDot, + CmdNameRedoIfchange, + CmdNameRedoIfcreate, + CmdNameRedoLog, + CmdNameRedoOOD, + CmdNameRedoSources, + CmdNameRedoStamp, + CmdNameRedoTargets, + CmdNameRedoWhichdo, } { fmt.Println(os.Args[0], "<-", cmdName) if err := os.Symlink(os.Args[0], cmdName); err != nil { @@ -125,28 +151,28 @@ func main() { DirPrefix = os.Getenv(EnvDirPrefix) DepCwd = os.Getenv(EnvDepCwd) - if *flagStderrKeep { + if flagStderrKeep != nil && *flagStderrKeep { mustSetenv(EnvStderrKeep, "1") } - if *flagStderrSilent { + if flagStderrSilent != nil && *flagStderrSilent { mustSetenv(EnvStderrSilent, "1") } - if *flagNoProgress { + if flagNoProgress != nil && *flagNoProgress { mustSetenv(EnvNoProgress, "1") } - if *flagDebug { + if flagDebug != nil && *flagDebug { mustSetenv(EnvDebug, "1") } - if *flagLogWait { + if flagLogWait != nil && *flagLogWait { mustSetenv(EnvLogWait, "1") } - if *flagLogLock { + if flagLogLock != nil && *flagLogLock { mustSetenv(EnvLogLock, "1") } - if *flagLogPid { + if flagLogPid != nil && *flagLogPid { mustSetenv(EnvLogPid, "1") } - if *flagLogJS { + if flagLogJS != nil && *flagLogJS { mustSetenv(EnvLogJS, "1") } StderrKeep = os.Getenv(EnvStderrKeep) == "1" @@ -160,13 +186,13 @@ func main() { MyPid = os.Getpid() } var traced bool - if *flagTraceAll { + if flagTraceAll != nil && *flagTraceAll { mustSetenv(EnvTrace, "1") } if os.Getenv(EnvTrace) == "1" { TracedAll = true traced = true - } else { + } else if flagTrace != nil { traced = *flagTrace } @@ -246,7 +272,9 @@ func main() { } } - statusInit() + if cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange { + statusInit() + } for i, tgt := range tgts { if path.IsAbs(tgt) { @@ -256,7 +284,6 @@ func main() { ok := true err = nil - cmdName := path.Base(os.Args[0]) trace( CDebug, "[%s] run: %s %s cwd:%s dirprefix:%s", BuildUUID, cmdName, tgts, Cwd, DirPrefix, @@ -264,19 +291,19 @@ func main() { CmdSwitch: switch cmdName { - case "redo": + case CmdNameRedo: for _, tgt := range tgts { ok, err = ifchange([]string{tgt}, true, traced) if err != nil || !ok { break } } - case "redo-ifchange": + case CmdNameRedoIfchange: ok, err = ifchange(tgts, false, traced) if err == nil { err = writeDeps(fdDep, tgts) } - case "redo-ifcreate": + case CmdNameRedoIfcreate: if fdDep == nil { log.Fatalln("no", EnvDepFd) } @@ -286,26 +313,26 @@ CmdSwitch: break } } - case "redo-always": + case CmdNameRedoAlways: if fdDep == nil { log.Fatalln("no", EnvDepFd) } err = always(fdDep) - case "redo-cleanup": + case CmdNameRedoCleanup: for _, what := range tgts { err = cleanupWalker(Cwd, what) if err != nil { break } } - case "redo-dot": + case CmdNameRedoDot: err = dotPrint(tgts) - case "redo-stamp": + case CmdNameRedoStamp: if fdDep == nil { log.Fatalln("no", EnvDepFd) } err = stamp(fdDep, os.Stdin) - case "redo-log": + case CmdNameRedoLog: if len(tgts) != 1 { log.Fatalln("single target expected") } @@ -316,7 +343,7 @@ CmdSwitch: break } _, err = io.Copy(os.Stdout, fd) - case "redo-whichdo": + case CmdNameRedoWhichdo: if len(tgts) != 1 { log.Fatalln("single target expected") } @@ -363,7 +390,7 @@ CmdSwitch: } fmt.Println(rel) } - case "redo-targets": + case CmdNameRedoTargets: if tgtsWasEmpty { tgts = []string{Cwd} } @@ -375,7 +402,7 @@ CmdSwitch: for _, tgt := range tgts { fmt.Println(tgt) } - case "redo-affects": + case CmdNameRedoAffects: if tgtsWasEmpty { log.Fatalln("no targets specified") } @@ -400,7 +427,7 @@ CmdSwitch: for _, dep := range tgts { fmt.Println(dep) } - case "redo-ood": + case CmdNameRedoOOD: if tgtsWasEmpty { tgts, err = targetsWalker([]string{Cwd}) if err != nil { @@ -418,7 +445,7 @@ CmdSwitch: fmt.Println(tgt) } } - case "redo-sources": + case CmdNameRedoSources: if tgtsWasEmpty { tgts, err = targetsWalker([]string{Cwd}) if err != nil { diff --git a/run.go b/run.go index 57401ce..59e134e 100644 --- a/run.go +++ b/run.go @@ -64,14 +64,28 @@ var ( StderrPrefix string Jobs sync.WaitGroup - flagTrace = flag.Bool("x", false, "trace (sh -x) current targets") - flagTraceAll = flag.Bool("xx", false, fmt.Sprintf("trace (sh -x) all targets (%s=1)", EnvTrace)) - flagStderrKeep = flag.Bool("logs", false, fmt.Sprintf("keep job's stderr (%s=1)", EnvStderrKeep)) - flagStderrSilent = flag.Bool("silent", false, fmt.Sprintf("do not print job's stderr (%s=1)", EnvStderrSilent)) + flagTrace *bool + flagTraceAll *bool + flagStderrKeep *bool + flagStderrSilent *bool TracedAll bool ) +func init() { + cmdName := CmdName() + if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) { + return + } + flagTrace = flag.Bool("x", false, "trace (sh -x) current targets") + flagTraceAll = flag.Bool("xx", false, + fmt.Sprintf("trace (sh -x) all targets (%s=1)", EnvTrace)) + flagStderrKeep = flag.Bool("k", false, + fmt.Sprintf("keep job's stderr (%s=1)", EnvStderrKeep)) + flagStderrSilent = flag.Bool("s", false, + fmt.Sprintf("silent, do not print job's stderr (%s=1)", EnvStderrSilent)) +} + type RunErr struct { Tgt string DoFile string diff --git a/status.go b/status.go index 0852dbd..d6f7c0d 100644 --- a/status.go +++ b/status.go @@ -37,9 +37,17 @@ const ( var ( FdStatus *os.File - flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)") + flagNoStatus *bool ) +func init() { + cmdName := CmdName() + if !(cmdName == CmdNameRedo || cmdName == CmdNameRedoIfchange) { + return + } + flagNoStatus = flag.Bool("no-status", false, "disable statusline (REDO_NO_STATUS=1)") +} + func statusInit() { if NoProgress || *flagNoStatus { return diff --git a/usage.go b/usage.go index 985e879..58b182b 100644 --- a/usage.go +++ b/usage.go @@ -24,7 +24,7 @@ import ( ) const ( - Version = "1.8.0" + Version = "1.9.0" Warranty = `Copyright (C) 2020-2021 Sergey Matveev This program is free software: you can redistribute it and/or modify @@ -43,63 +43,63 @@ along with this program. If not, see .` func usage(cmd string) { var d string switch cmd { - case "redo": - d = `Usage: redo [options] [target ...] + 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 "redo-ifchange": - d = `Usage: redo-ifchange target [...] + 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 "redo-ifcreate": + case CmdNameRedoIfcreate: d = `Usage: redo-ifcreate target [...] Record ifcreate dependency for current target. Unusable outside .do.` - case "redo-always": + case CmdNameRedoAlways: d = `Usage: redo-always Always build current target. Unusable outside .do.` - case "redo-cleanup": - d = `Usage: redo-cleanup [-dry-run] {full,log,tmp} [...] + case CmdNameRedoCleanup: + d = `Usage: redo-cleanup [-n] {full,log,tmp} [...] Remove either all goredo's related temporary files, or kept stderr logs, or everything (including .redo directories) related.` - case "redo-log": + case CmdNameRedoLog: d = `Usage: redo-log 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.` - case "redo-dot": + case CmdNameRedoDot: d = `Usage: redo-dot target [...] Write dependency DOT graph to stdout.` - case "redo-stamp": + 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 "redo-whichdo": + 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 "redo-targets": + case CmdNameRedoTargets: d = `Usage: redo-targets [target ...] List all currently known targets.` - case "redo-sources": + case CmdNameRedoSources: d = `Usage: redo-sources [target ...] List all currently known source files.` - case "redo-ood": + case CmdNameRedoOOD: d = `Usage: redo-ood [target ...] List all currently known out-of-date targets.` - case "redo-affects": + case CmdNameRedoAffects: d = `Usage: redo-affects target [...] List all targets that will be affected by changing the specified ones.` @@ -116,10 +116,13 @@ redo-sources, redo-stamp, redo-targets, redo-whichdo.` fmt.Fprintln(os.Stderr, ` Additional environment variables: NO_COLOR -- disable messages colouring - REDO_NO_SYNC -- disable files/directories explicit filesystem syncing REDO_TOP_DIR -- do not search for .do above that directory - (it can contain .redo/top as an alternative) + (it can contain .redo/top as an alternative)`) + if cmd == CmdNameRedo || cmd == CmdNameRedoIfchange { + fmt.Fprintln(os.Stderr, ` + REDO_NO_SYNC -- disable files/directories explicit filesystem syncing REDO_INODE_NO_TRUST -- do not trust inode information (except for size) and always check file's hash REDO_MAKE -- bmake/gmake/none(default) jobserver protocol compatibility`) + } } -- 2.44.0