func runProjectClean(jirix *jiri.X, args []string) (e error) { localProjects, err := project.LocalProjects(jirix, project.FullScan) if err != nil { return err } var projects project.Projects if len(args) > 0 { for _, arg := range args { p, err := localProjects.FindUnique(arg) if err != nil { fmt.Fprintf(jirix.Stderr(), "Error finding local project %q: %v.\n", p.Name, err) } else { projects[p.Key()] = p } } } else { projects = localProjects } if err := project.CleanupProjects(jirix, projects, cleanupBranchesFlag); err != nil { return err } return nil }
func runProjectClean(env *cmdline.Env, args []string) (e error) { ctx := tool.NewContextFromEnv(env) localProjects, err := project.LocalProjects(ctx, project.FullScan) if err != nil { return err } projects := map[string]project.Project{} if len(args) > 0 { for _, arg := range args { if p, ok := localProjects[arg]; ok { projects[p.Name] = p } else { fmt.Fprintf(ctx.Stderr(), "Local project %q not found.\n", p.Name) } } } else { projects = localProjects } if err := project.CleanupProjects(ctx, projects, cleanupBranchesFlag); err != nil { return err } return nil }
// TestLocalProjects tests the behavior of the LocalProjects method with // different ScanModes. func TestLocalProjects(t *testing.T) { jirix, cleanup := jiritest.NewX(t) defer cleanup() // Create some projects. numProjects, projectPaths := 3, []string{} for i := 0; i < numProjects; i++ { s := jirix.NewSeq() name := projectName(i) path := filepath.Join(jirix.Root, name) if err := s.MkdirAll(path, 0755).Done(); err != nil { t.Fatal(err) } // Initialize empty git repository. The commit is necessary, otherwise // "git rev-parse master" fails. git := gitutil.New(s, gitutil.RootDirOpt(path)) if err := git.Init(path); err != nil { t.Fatal(err) } if err := git.Commit(); err != nil { t.Fatal(err) } // Write project metadata. p := project.Project{ Path: path, Name: name, } if err := project.InternalWriteMetadata(jirix, p, path); err != nil { t.Fatalf("writeMetadata %v %v) failed: %v\n", p, path, err) } projectPaths = append(projectPaths, path) } // Create a latest update snapshot but only tell it about the first project. manifest := project.Manifest{ Projects: []project.Project{ { Name: projectName(0), Path: projectPaths[0], }, }, } if err := jirix.NewSeq().MkdirAll(jirix.UpdateHistoryDir(), 0755).Done(); err != nil { t.Fatalf("MkdirAll(%v) failed: %v", jirix.UpdateHistoryDir(), err) } if err := manifest.ToFile(jirix, jirix.UpdateHistoryLatestLink()); err != nil { t.Fatalf("manifest.ToFile(%v) failed: %v", jirix.UpdateHistoryLatestLink(), err) } // LocalProjects with scanMode = FastScan should only find the first // project. foundProjects, err := project.LocalProjects(jirix, project.FastScan) if err != nil { t.Fatalf("LocalProjects(%v) failed: %v", project.FastScan, err) } checkProjectsMatchPaths(t, foundProjects, projectPaths[:1]) // LocalProjects with scanMode = FullScan should find all projects. foundProjects, err = project.LocalProjects(jirix, project.FullScan) if err != nil { t.Fatalf("LocalProjects(%v) failed: %v", project.FastScan, err) } checkProjectsMatchPaths(t, foundProjects, projectPaths[:]) // Check that deleting a project forces LocalProjects to run a full scan, // even if FastScan is specified. if err := jirix.NewSeq().RemoveAll(projectPaths[0]).Done(); err != nil { t.Fatalf("RemoveAll(%v) failed: %v", projectPaths[0]) } foundProjects, err = project.LocalProjects(jirix, project.FastScan) if err != nil { t.Fatalf("LocalProjects(%v) failed: %v", project.FastScan, err) } checkProjectsMatchPaths(t, foundProjects, projectPaths[1:]) }
func runContributors(env *cmdline.Env, args []string) error { ctx := tool.NewContextFromEnv(env) projects, err := project.LocalProjects(ctx, project.FastScan) if err != nil { return err } projectNames := map[string]struct{}{} if len(args) != 0 { projectNames = set.String.FromSlice(args) } else { for name, _ := range projects { projectNames[name] = struct{}{} } } aliases, err := loadAliases(ctx) if err != nil { return err } contributors := map[string]*contributor{} for name, _ := range projectNames { project, ok := projects[name] if !ok { continue } if err := ctx.Run().Chdir(project.Path); err != nil { return err } switch project.Protocol { case "git": lines, err := listCommitters(ctx) if err != nil { return err } for _, line := range lines { matches := contributorRE.FindStringSubmatch(line) if got, want := len(matches), 4; got != want { return fmt.Errorf("unexpected length of %v: got %v, want %v", matches, got, want) } count, err := strconv.Atoi(strings.TrimSpace(matches[1])) if err != nil { return fmt.Errorf("Atoi(%v) failed: %v", strings.TrimSpace(matches[1]), err) } c := &contributor{ count: count, email: strings.TrimSpace(matches[3]), name: strings.TrimSpace(matches[2]), } if c.email == "*****@*****.**" || c.email == "*****@*****.**" { continue } c.email, c.name = canonicalize(aliases, c.email, c.name) if existing, ok := contributors[c.name]; ok { existing.count += c.count } else { contributors[c.name] = c } } } } names := []string{} for name, _ := range contributors { names = append(names, name) } sort.Strings(names) for _, name := range names { c := contributors[name] if countFlag { fmt.Fprintf(env.Stdout, "%4d ", c.count) } fmt.Fprintf(env.Stdout, "%v <%v>\n", c.name, c.email) } return nil }