Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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()
}
Beispiel #7
0
// 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
}