X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=run.go;h=d8e439de5b0dcaabf7f38d76c0cf8f8529d9c279;hb=7782b7e4df32b283c92f08e70c3cf64c69a43fcd;hp=ac607a696b0ceea461d0147e9ef555ad8f663f59;hpb=7e3898c0b58d68b5287f3437f721f967809de2a9;p=goredo.git diff --git a/run.go b/run.go index ac607a6..d8e439d 100644 --- a/run.go +++ b/run.go @@ -1,6 +1,6 @@ /* goredo -- redo implementation on pure Go -Copyright (C) 2020 Sergey Matveev +Copyright (C) 2020-2021 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,6 +28,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "strings" "sync" "syscall" @@ -62,7 +63,8 @@ var ( StderrPrefix string Jobs sync.WaitGroup - flagTrace = flag.Bool("x", false, fmt.Sprintf("trace current target (sh -x) (set %s=1 for all others)", EnvTrace)) + 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)) ) @@ -75,8 +77,6 @@ type RunErr struct { Err error } -func (e RunErr) Unwrap() error { return e.Err } - func (e *RunErr) Name() string { var name string if e.DoFile == "" { @@ -266,12 +266,14 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // Determine basename and DIRPREFIX + doFileRelPath := doFile ents := strings.Split(cwd, "/") ents = ents[len(ents)-upLevels:] dirPrefix := path.Join(ents...) cwdOrig := cwd for i := 0; i < upLevels; i++ { cwd = path.Join(cwd, "..") + doFileRelPath = path.Join("..", doFileRelPath) } cwd = path.Clean(cwd) doFilePath := path.Join(cwd, doFile) @@ -279,10 +281,10 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { runErr := RunErr{Tgt: tgtOrig} if strings.HasPrefix(doFile, "default.") { basename = tgt[:len(tgt)-(len(doFile)-len("default.")-len(".do"))-1] - runErr.DoFile = doFile + runErr.DoFile = doFileRelPath } - if err = writeDep(fdDep, cwd, doFile); err != nil { + if err = writeDep(fdDep, cwdOrig, doFileRelPath); err != nil { cleanup() return TgtErr{tgtOrig, err} } @@ -305,17 +307,27 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // Temporary file for stdout - fdStdout, err := tempfile(cwd, tgt) + fdStdout, err := tempfile(cwdOrig, tgt) if err != nil { cleanup() return TgtErr{tgtOrig, err} } tmpPath := fdStdout.Name() + ".3" // and for $3 - args = append(args, tgt, basename, path.Base(tmpPath)) + tmpPathRel, err := filepath.Rel(cwd, tmpPath) + if err != nil { + panic(err) + } + args = append( + args, + path.Join(dirPrefix, tgt), + path.Join(dirPrefix, basename), + tmpPathRel, + ) cmd := exec.Command(cmdName, args...) cmd.Dir = cwd cmd.Stdout = fdStdout + // cmd.Stdin reads from /dev/null by default cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%d", EnvLevel, Level+1)) cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDirPrefix, dirPrefix)) cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvBuildUUID, BuildUUID)) @@ -368,7 +380,10 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } fdStderr.Truncate(0) } - shCtx := fmt.Sprintf("sh: %s: %s %s [%s]", tgtOrig, cmdName, args, cwd) + shCtx := fmt.Sprintf( + "sh: %s: %s %s cwd:%s dirprefix:%s", + tgtOrig, cmdName, args, cwd, dirPrefix, + ) trace(CDebug, "%s", shCtx) Jobs.Add(1) @@ -447,14 +462,16 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { } // Was $1 touched? - if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil { - ts, err := fileCtime(fd) - fd.Close() - if err == nil && ts != tsPrev { - runErr.Err = errors.New("$1 was explicitly touched") - errs <- runErr + if tsPrev != "" { + if fd, err := os.Open(path.Join(cwdOrig, tgt)); err == nil { + ts, err := fileCtime(fd) fd.Close() - return + if err == nil && ts != tsPrev { + runErr.Err = errors.New("$1 was explicitly touched") + errs <- runErr + fd.Close() + return + } } } @@ -494,6 +511,7 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { // Do we need to ifcreate it, of ifchange with renaming? if fd == nil { + os.Remove(path.Join(cwdOrig, tgt)) err = ifcreate(fdDep, tgt) if err != nil { goto Finish