package forgepb import ( "fmt" "os" "path/filepath" "github.com/destel/rill" "go.wit.com/lib/config" "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 %v\n", repo.FullPath, err) return err } return nil } func (f *Forge) TestScan() error { f.Repos = gitpb.NewRepos() dirs, err := gitDirectoriesNew(f.Config.ReposDir) if err != nil { return err } for i, fullpath := range dirs { repo, err := gitpb.NewRepo(fullpath) if err != nil { log.Info("ReAdd() error", fullpath, err) } log.Info(i, "worked", repo.FullPath) repo = f.Repos.Append(repo) f.VerifyBranchNames(repo) if f.Config.IsReadOnly(repo.GetGoPath()) { repo.ReadOnly = true } repo.ReloadCheck() if i > 5 { break } } return nil } 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) ScanRepoDir() error { dirs, err := gitDirectoriesNew(f.Config.ReposDir) if err != nil { return err } log.Info("doing reload()") 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, int(f.Config.RillX), func(id string) (*gitpb.Repo, error) { return f.checkNamespace(id) }) var counter int // Activate users. // Concurrency = 10 err := rill.ForEach(dirs, int(f.Config.RillY), func(repo *gitpb.Repo) error { if repo == nil { return nil } repo = f.Repos.Append(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) { 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": case "go.work.sum": 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 }