package forgepb import ( "errors" "fmt" "os" "path/filepath" "strings" "github.com/destel/rill" "go.wit.com/lib/cobol" "go.wit.com/lib/config" "go.wit.com/lib/env" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) func reloadCheck(repo *gitpb.Repo) error { if err := repo.ReloadCheck(); err != nil { log.Infof("%s reload() says err(%v) change(%s)\n", repo.FullPath, err, repo.StateChange) return err } return nil } func (f *Forge) Reload() map[string]*RillStats { return f.RillRepos(reloadCheck) } func (f *Forge) checkNamespace(fullpath string) (*gitpb.Repo, error) { if repo := f.Repos.FindByFullPath(fullpath); repo != nil { return nil, nil } repo, err := gitpb.NewRepo(fullpath) if err != nil { log.Info(fullpath, err) return nil, err } return repo, err } func (f *Forge) RescanRepos() error { gopath := env.Get("gopath") fullpath := env.FullPath(gopath) if env.Verbose() { log.Info("RescanRepos() running in", fullpath) } f.scanRepoDir(fullpath) err := f.Save() // return errors.New("ScanReposByMode() not implemented yet") return err } // scans for .git/ directories func (f *Forge) scanRepoDir(path string) error { if path == "" { return errors.New("ScanRepoDir() got sent blank dir") } dirs, err := gitDirectoriesNew(path) if err != nil { return err } stats := f.RillRepos(reloadCheck) for _, stat := range stats { if stat.Err == nil { continue } config.SetChanged("repos", true) } newcount, err := f.rillScanDirsNew(dirs) if err != nil { log.Info("go src dir problem. exit for now?", err) return err } if newcount != 0 { log.Info("forge go src scan found", newcount, "repos") config.SetChanged("repos", true) } return err } // rill is awesome. long live rill // attempt scan with rill func (f *Forge) rillScanDirsNew(fullpaths []string) (int, error) { // Convert a slice of user IDs into a channel ids := rill.FromSlice(fullpaths, nil) // Read users from the API. // Concurrency = 20 dirs := rill.Map(ids, cobol.Int(env.Get("RillX")), func(id string) (*gitpb.Repo, error) { return f.checkNamespace(id) }) var counter int // Activate users. // Concurrency = 10 err := rill.ForEach(dirs, cobol.Int(env.Get("RillY")), func(repo *gitpb.Repo) error { if repo == nil { return nil } repo = f.Repos.Clone(repo) f.VerifyBranchNames(repo) if f.Config.IsReadOnly(repo.GetGoPath()) { repo.ReadOnly = true } repo.ReloadCheck() counter += 1 return nil }) return counter, 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) { if srcDir == "" { log.Info("SCANNING DISALBED") return nil, errors.New("SCANNING DISALBED") } var all []string var untracked []string var dirs []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 "gowork.pb": case "go.work": case "go.work.last": case "go.work.sum": default: // log.Info("WARNING: you have an untracked file outside of any .git repository:", path) untracked = append(untracked, path) trip = true var match bool for _, adir := range dirs { if strings.HasPrefix(path, adir) { match = true } } if match { // already have this dir } else { dirs = append(dirs, path) } } 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: you have files that are untracked by .git repos here") log.Info("WARNING:") count := 0 for _, file := range untracked { log.Info("WARNING:", file) if count > 7 { break } count += 1 } log.Info("WARNING:") log.Printf("WARNING: you have %d untracked files %d paths\n", len(untracked), len(dirs)) log.Info("WARNING:") } return all, err }