package forgepb import ( "errors" "fmt" "os" "path/filepath" "strings" "github.com/destel/rill" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) func (f *Forge) ScanGoSrc() (bool, error) { dirs, err := gitDirectoriesNew(f.goSrc) if err != nil { return false, err } var gopaths []string for _, dir := range dirs { // log.Info("forge.ScanGoSrc()", dir) if strings.HasPrefix(dir, f.goSrc) { gopath := strings.TrimPrefix(dir, f.goSrc) gopath = strings.Trim(gopath, "/") if r := f.FindByGoPath(gopath); r != nil { // log.Info("already have", gopath) continue } gopaths = append(gopaths, gopath) } else { log.Log(FORGEPBWARN, "ScanGoSrc() bad:", dir) return false, errors.New("forgepb.ScanGoSrc() bad dir: " + dir) } } newcount, err := f.rillScanDirs(gopaths) if err != nil { log.Info("go src dir problem. exit for now?", err) return false, err } if newcount != 0 { log.Info("forge go src scan found", newcount, "repos") f.Repos.ConfigSave() } return true, err } // doesn't enter the directory any further when it finds a .git/ // not stupid like my old version func gitDirectoriesNew(srcDir string) ([]string, error) { var all []string var trip bool err := filepath.WalkDir(srcDir, func(path string, d os.DirEntry, err error) error { if err != nil { // Handle possible errors, like permission issues fmt.Fprintf(os.Stderr, "error accessing path %q: %v\n", path, err) return err } if d.IsDir() { // log.Info("path is dir", path) } else { _, fname := filepath.Split(path) switch fname { case "repos.pb": case "go.work": case "go.work.last": default: // todo: figure out a way to do padding for init() if trip == false { log.Info("WARNING:") } log.Info("WARNING: you have an untracked file outside of any .git repository:", path) trip = true } return nil } gitdir := filepath.Join(path, ".git") _, err2 := os.Stat(gitdir) if !os.IsNotExist(err2) { all = append(all, path) return filepath.SkipDir } return nil }) // // probably always leave this here forever // this check, along with CheckDirty() makes sure you can safely delete ~/go/src or the go.work directory // because everything is either checked in or deleted. An important thing to know! if trip { log.Info("WARNING:") log.Info("WARNING: there isn't a way to disable this warning yet") log.Info("WARNING: probably this is a good thing however. you don't want to leave files outside of git repos here") log.Info("WARNING: so this warning should probably stay") log.Info("WARNING:") log.Info("WARNING: this also might mean you put these files here because you are actively working on them") log.Info("WARNING: and you don't want to forget about them") log.Info("WARNING:") } return all, err } func gitDirectoriesOld(srcDir string) ([]string, error) { var all []string err := filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error { if err != nil { log.Log(FORGEPBWARN, "Error accessing path:", path, err) return nil } // Check if the path is a directory and has a .git subdirectory if info.IsDir() && IsGitDir(path) { all = append(all, path) } return nil }) if err != nil { log.Log(FORGEPBWARN, "Error walking the path:", srcDir, err) } return all, err } // IsGitDir checks if a .git directory exists inside the given directory func IsGitDir(dir string) bool { gitDir := filepath.Join(dir, ".git") info, err := os.Stat(gitDir) if os.IsNotExist(err) { return false } return info.IsDir() } // rill is awesome. long live rill // attempt scan with rill func (f *Forge) rillScanDirs(gopaths []string) (int, error) { // Convert a slice of user IDs into a channel ids := rill.FromSlice(gopaths, nil) // Read users from the API. // Concurrency = 20 dirs := rill.Map(ids, 20, func(id string) (*gitpb.Repo, error) { return f.checkpath(id, "") }) var counter int // Activate users. // Concurrency = 10 err := rill.ForEach(dirs, 10, func(repo *gitpb.Repo) error { counter += 1 return nil }) return counter, err } func (f *Forge) checkpath(gopath string, url string) (*gitpb.Repo, error) { fullpath := filepath.Join(f.GetGoSrc(), gopath) log.Info("checkpath()", gopath, fullpath) repo, err := f.NewGoRepo(gopath, "") if err != nil { log.Info("checkpath()", gopath, err) } return repo, err } func (f *Forge) RillRedoGoMod() int { var all []*gitpb.Repo tmp := f.Repos.SortByFullPath() for tmp.Scan() { repo := tmp.Next() if !repo.IsValidDir() { log.Printf("%10s %-50s", "why am I in RillRedoGoMod? old?", repo.GetGoPath()) continue } all = append(all, repo) } // Convert a slice of user IDs into a channel ids := rill.FromSlice(all, nil) var counter int // Read users from the API. // Concurrency = 20 dirs := rill.Map(ids, 50, func(id *gitpb.Repo) (*gitpb.Repo, error) { return id, nil }) err := rill.ForEach(dirs, 20, func(repo *gitpb.Repo) error { counter += 1 // repo.RedoGoMod() return nil }) if err != nil { log.Info("rill.ForEach() error:", err) } return counter }