/* findDofile searches for the most specific .do file for the target and, if found, returns a DoInfo structure whose Missing field is an array of paths to more specific .do files, if any, that were not found. Multiple extensions do not change the $2 argument to the .do script, which still only has one level of extension removed. */ func (f *File) findDoFile() (*DoInfo, error) { candidates := []string{f.Name + ".do"} ext := strings.Split(f.Name, ".") for i := 0; i < len(ext); i++ { candidates = append(candidates, strings.Join(append(append([]string{"default"}, ext[i+1:]...), "do"), ".")) } relPath := &RelPath{} var missing []string dir := f.Dir TOP: for { for _, candidate := range candidates { path := filepath.Join(dir, candidate) exists, err := fileutils.FileExists(path) if err != nil { return nil, err } else if exists { return &DoInfo{dir, candidate, relPath.Join(), missing}, nil } else { missing = append(missing, path) } } if dir == f.RootDir { break TOP } relPath.Add(filepath.Base(dir)) dir = filepath.Dir(dir) } return &DoInfo{Missing: missing}, nil }
// Exist verifies that the file exists on disk. func (f *File) Exists() (bool, error) { return fileutils.FileExists(f.Fullpath()) }
func runRedo(targets []string) error { // set options from environment if not provided. if verbosity.NArg() == 0 { for i := len(os.Getenv("REDO_VERBOSE")); i > 0; i-- { verbosity.Set("true") } } if debug.NArg() == 0 { if len(os.Getenv("REDO_DEBUG")) > 0 { debug.Set("true") } } if s := shArgs; s != "" { os.Setenv("REDO_SHELL_ARGS", s) redux.ShellArgs = s } // if shell args are set, ensure that at least minimal verbosity is also set. if redux.ShellArgs != "" && (verbosity.NArg() == 0) { verbosity.Set("true") } // Set explicit options to avoid clobbering environment inherited options. if n := verbosity.NArg(); n > 0 { os.Setenv("REDO_VERBOSE", strings.Repeat("x", n)) redux.Verbosity = n } if n := debug.NArg(); n > 0 { os.Setenv("REDO_DEBUG", "true") redux.Debug = true } // If no arguments are specified, use run default target if its .do file exists. // Otherwise, print usage and exit. if len(targets) == 0 && os.Getenv("REDO_DEPTH") == "" { if found, err := fileutils.FileExists(DEFAULT_DO); err != nil { return err } else if found { targets = append(targets, DEFAULT_TARGET) } else { targets = append(targets, "all") } } wd, err := os.Getwd() if err != nil { return err } // It *is* slower to reinitialize for each target, but doing // so guarantees that a single redo call with multiple targets that // potentially have differing roots will work correctly. for _, path := range targets { if file, err := redux.NewFile(wd, path); err != nil { return err } else { file.IsTaskFlag = isTask if err := file.Redo(); err != nil { return err } } } return nil }