func runProjectShellPrompt(env *cmdline.Env, args []string) error { ctx := tool.NewContextFromEnv(env) states, err := project.GetProjectStates(ctx, checkDirtyFlag) if err != nil { return err } names := []string{} for name := range states { names = append(names, name) } sort.Strings(names) // Get the name of the current project. currentProjectName, err := project.CurrentProjectName(ctx) if err != nil { return err } var statuses []string for _, name := range names { state := states[name] status := "" if checkDirtyFlag { if state.HasUncommitted { status += "*" } if state.HasUntracked { status += "%" } } short := state.CurrentBranch + status long := filepath.Base(name) + ":" + short if name == currentProjectName { if showNameFlag { statuses = append([]string{long}, statuses...) } else { statuses = append([]string{short}, statuses...) } } else { pristine := state.CurrentBranch == "master" if checkDirtyFlag { pristine = pristine && !state.HasUncommitted && !state.HasUntracked } if !pristine { statuses = append(statuses, long) } } } fmt.Println(strings.Join(statuses, ",")) return nil }
func runProjectShellPrompt(jirix *jiri.X, args []string) error { states, err := project.GetProjectStates(jirix, checkDirtyFlag) if err != nil { return err } var keys project.ProjectKeys for key := range states { keys = append(keys, key) } sort.Sort(keys) // Get the key of the current project. currentProjectKey, err := project.CurrentProjectKey(jirix) if err != nil { return err } var statuses []string for _, key := range keys { state := states[key] status := "" if checkDirtyFlag { if state.HasUncommitted { status += "*" } if state.HasUntracked { status += "%" } } short := state.CurrentBranch + status long := filepath.Base(states[key].Project.Name) + ":" + short if key == currentProjectKey { if showNameFlag { statuses = append([]string{long}, statuses...) } else { statuses = append([]string{short}, statuses...) } } else { pristine := state.CurrentBranch == "master" if checkDirtyFlag { pristine = pristine && !state.HasUncommitted && !state.HasUntracked } if !pristine { statuses = append(statuses, long) } } } fmt.Println(strings.Join(statuses, ",")) return nil }
// projectStates returns a map with all projects that are on the same // current branch as the current project, as well as a slice of their // project keys sorted lexicographically. Unless "allowdirty" is true, // an error is returned if any matching project has uncommitted changes. // The keys are returned, sorted, to avoid the caller having to recreate // the them by iterating over the map. func projectStates(jirix *jiri.X, allowdirty bool) (map[project.ProjectKey]*project.ProjectState, project.ProjectKeys, error) { git := gitutil.New(jirix.NewSeq()) branch, err := git.CurrentBranchName() if err != nil { return nil, nil, err } states, err := project.GetProjectStates(jirix, false) if err != nil { return nil, nil, err } uncommitted := []string{} var keys project.ProjectKeys for _, s := range states { if s.CurrentBranch == branch { key := s.Project.Key() fullState, err := project.GetProjectState(jirix, key, true) if err != nil { return nil, nil, err } if !allowdirty && fullState.HasUncommitted { uncommitted = append(uncommitted, string(key)) } else { keys = append(keys, key) } } } if len(uncommitted) > 0 { return nil, nil, fmt.Errorf("the following projects have uncommitted changes: %s", strings.Join(uncommitted, ", ")) } members := map[project.ProjectKey]*project.ProjectState{} for _, key := range keys { members[key] = states[key] } if len(members) == 0 { return nil, nil, nil } sort.Sort(keys) return members, keys, nil }
// runProjectList generates a listing of local projects. func runProjectList(env *cmdline.Env, _ []string) error { ctx := tool.NewContextFromEnv(env) states, err := project.GetProjectStates(ctx, noPristineFlag) if err != nil { return err } names := []string{} for name := range states { names = append(names, name) } sort.Strings(names) for _, name := range names { state := states[name] if noPristineFlag { pristine := len(state.Branches) == 1 && state.CurrentBranch == "master" && !state.HasUncommitted && !state.HasUntracked if pristine { continue } } fmt.Fprintf(ctx.Stdout(), "project=%q path=%q\n", path.Base(name), state.Project.Path) if branchesFlag { for _, branch := range state.Branches { s := " " if branch.Name == state.CurrentBranch { s += "* " } s += branch.Name if branch.HasGerritMessage { s += " (exported to gerrit)" } fmt.Fprintf(ctx.Stdout(), "%v\n", s) } } } return nil }
// runProjectList generates a listing of local projects. func runProjectList(jirix *jiri.X, _ []string) error { states, err := project.GetProjectStates(jirix, noPristineFlag) if err != nil { return err } var keys project.ProjectKeys for key := range states { keys = append(keys, key) } sort.Sort(keys) for _, key := range keys { state := states[key] if noPristineFlag { pristine := len(state.Branches) == 1 && state.CurrentBranch == "master" && !state.HasUncommitted && !state.HasUntracked if pristine { continue } } fmt.Fprintf(jirix.Stdout(), "name=%q remote=%q path=%q\n", state.Project.Name, state.Project.Remote, state.Project.Path) if branchesFlag { for _, branch := range state.Branches { s := " " if branch.Name == state.CurrentBranch { s += "* " } s += branch.Name if branch.HasGerritMessage { s += " (exported to gerrit)" } fmt.Fprintf(jirix.Stdout(), "%v\n", s) } } } return nil }
func runp(jirix *jiri.X, cmd *cmdline.Command, args []string) error { hasUntrackedSet := profilescmdline.IsFlagSet(cmd.ParsedFlags, "has-untracked") hasUncommitedSet := profilescmdline.IsFlagSet(cmd.ParsedFlags, "has-uncommitted") hasGerritSet := profilescmdline.IsFlagSet(cmd.ParsedFlags, "has-gerrit-message") if runpFlags.interactive { runpFlags.collateOutput = false } var keysRE, branchRE *regexp.Regexp var err error if profilescmdline.IsFlagSet(cmd.ParsedFlags, "projects") { re := "" for _, pre := range strings.Split(runpFlags.projectKeys, ",") { re += pre + "|" } re = strings.TrimRight(re, "|") keysRE, err = regexp.Compile(re) if err != nil { return fmt.Errorf("failed to compile projects regexp: %q: %v", runpFlags.projectKeys, err) } } if profilescmdline.IsFlagSet(cmd.ParsedFlags, "has-branch") { branchRE, err = regexp.Compile(runpFlags.hasBranch) if err != nil { return fmt.Errorf("failed to compile has-branch regexp: %q: %v", runpFlags.hasBranch, err) } } for _, f := range []string{"show-key-prefix", "show-name-prefix"} { if profilescmdline.IsFlagSet(cmd.ParsedFlags, f) { if runpFlags.interactive && profilescmdline.IsFlagSet(cmd.ParsedFlags, "interactive") { fmt.Fprintf(jirix.Stderr(), "WARNING: interactive mode being disabled because %s was set\n", f) } runpFlags.interactive = false runpFlags.collateOutput = true break } } git := gitutil.New(jirix.NewSeq()) homeBranch, err := git.CurrentBranchName() if err != nil { // jiri was run from outside of a project. Let's assume we'll // use all projects if none have been specified via the projects flag. if keysRE == nil { keysRE = regexp.MustCompile(".*") } } dirty := false if hasUntrackedSet || hasUncommitedSet { dirty = true } states, err := project.GetProjectStates(jirix, dirty) if err != nil { return err } mapInputs := map[project.ProjectKey]*mapInput{} var keys project.ProjectKeys for key, state := range states { if keysRE != nil { if !keysRE.MatchString(string(key)) { continue } } else { if state.CurrentBranch != homeBranch { continue } } if branchRE != nil { found := false for _, br := range state.Branches { if branchRE.MatchString(br.Name) { found = true break } } if !found { continue } } if hasUntrackedSet && (state.HasUntracked != runpFlags.hasUntracked) { continue } if hasUncommitedSet && (state.HasUncommitted != runpFlags.hasUncommitted) { continue } if hasGerritSet { hasMsg := false for _, br := range state.Branches { if (state.CurrentBranch == br.Name) && br.HasGerritMessage { hasMsg = true break } } if hasMsg != runpFlags.hasGerritMessage { continue } } mapInputs[key] = &mapInput{ ProjectState: state, jirix: jirix, key: key, } keys = append(keys, key) } total := len(mapInputs) index := 1 for _, mi := range mapInputs { mi.index = index mi.total = total index++ } if runpFlags.verbose { fmt.Fprintf(jirix.Stdout(), "Project Names: %s\n", strings.Join(stateNames(mapInputs), " ")) fmt.Fprintf(jirix.Stdout(), "Project Keys: %s\n", strings.Join(stateKeys(mapInputs), " ")) } reader, err := profilesreader.NewReader(jirix, runpFlags.ProfilesMode, runpFlags.DBFilename) runner := &runner{ reader: reader, args: args, } mr := simplemr.MR{} if runpFlags.interactive { // Run one mapper at a time. mr.NumMappers = 1 sort.Sort(keys) } in, out := make(chan *simplemr.Record, len(mapInputs)), make(chan *simplemr.Record, len(mapInputs)) sigch := make(chan os.Signal) signal.Notify(sigch, os.Interrupt) go func() { <-sigch; mr.Cancel() }() go mr.Run(in, out, runner, runner) for _, key := range keys { in <- &simplemr.Record{string(key), []interface{}{mapInputs[key]}} } close(in) <-out return mr.Error() }
// runProjectInfo provides structured info on local projects. func runProjectInfo(jirix *jiri.X, args []string) error { tmpl, err := template.New("info").Parse(formatFlag) if err != nil { return fmt.Errorf("failed to parse template %q: %v", formatFlag, err) } regexps := []*regexp.Regexp{} if len(args) > 0 { regexps = make([]*regexp.Regexp, len(args), len(args)) for i, a := range args { re, err := regexp.Compile(a) if err != nil { return fmt.Errorf("failed to compile regexp %v: %v", a, err) } regexps[i] = re } } dirty := false for _, slow := range []string{"HasUncommitted", "HasUntracked"} { if strings.Contains(formatFlag, slow) { dirty = true break } } var states map[project.ProjectKey]*project.ProjectState var keys project.ProjectKeys if len(args) == 0 { currentProjectKey, err := project.CurrentProjectKey(jirix) if err != nil { return err } state, err := project.GetProjectState(jirix, currentProjectKey, true) if err != nil { // jiri was run from outside of a project so let's // use all available projects. states, err = project.GetProjectStates(jirix, dirty) if err != nil { return err } for key := range states { keys = append(keys, key) } } else { states = map[project.ProjectKey]*project.ProjectState{ currentProjectKey: state, } keys = append(keys, currentProjectKey) } } else { var err error states, err = project.GetProjectStates(jirix, dirty) if err != nil { return err } for key := range states { for _, re := range regexps { if re.MatchString(string(key)) { keys = append(keys, key) break } } } } sort.Sort(keys) for _, key := range keys { state := states[key] out := &bytes.Buffer{} if err = tmpl.Execute(out, state); err != nil { return jirix.UsageErrorf("invalid format") } fmt.Fprintln(jirix.Stdout(), out.String()) } return nil }