Example #1
0
func runSnapshotCreate(jirix *jiri.X, args []string) error {
	if len(args) != 1 {
		return jirix.UsageErrorf("unexpected number of arguments")
	}
	label := args[0]
	snapshotDir, err := getSnapshotDir(jirix)
	if err != nil {
		return err
	}
	snapshotFile := filepath.Join(snapshotDir, "labels", label, time.Now().Format(timeFormatFlag))

	if !pushRemoteFlag {
		// No git operations necessary.  Just create the snapshot file.
		return createSnapshot(jirix, snapshotDir, snapshotFile, label)
	}

	// Attempt to create a snapshot on a clean master branch.  If snapshot
	// creation fails, return to the state we were in before.
	createFn := func() error {
		git := gitutil.New(jirix.NewSeq())
		revision, err := git.CurrentRevision()
		if err != nil {
			return err
		}
		if err := createSnapshot(jirix, snapshotDir, snapshotFile, label); err != nil {
			git.Reset(revision)
			git.RemoveUntrackedFiles()
			return err
		}
		return commitAndPushChanges(jirix, snapshotDir, snapshotFile, label)
	}

	// Execute the above function in the snapshot directory on a clean master branch.
	p := project.Project{
		Path:         snapshotDir,
		Protocol:     "git",
		RemoteBranch: "master",
		Revision:     "HEAD",
	}
	return project.ApplyToLocalMaster(jirix, project.Projects{p.Key(): p}, createFn)
}
Example #2
0
func runImport(jirix *jiri.X, args []string) error {
	if len(args) != 2 {
		return jirix.UsageErrorf("wrong number of arguments")
	}
	// Initialize manifest.
	var manifest *project.Manifest
	if !flagImportOverwrite {
		m, err := project.ManifestFromFile(jirix, jirix.JiriManifestFile())
		if err != nil && !runutil.IsNotExist(err) {
			return err
		}
		manifest = m
	}
	if manifest == nil {
		manifest = &project.Manifest{}
	}
	// There's not much error checking when writing the .jiri_manifest file;
	// errors will be reported when "jiri update" is run.
	manifest.Imports = append(manifest.Imports, project.Import{
		Manifest:     args[0],
		Name:         flagImportName,
		Protocol:     flagImportProtocol,
		Remote:       args[1],
		RemoteBranch: flagImportRemoteBranch,
		Root:         flagImportRoot,
	})
	// Write output to stdout or file.
	outFile := flagImportOut
	if outFile == "" {
		outFile = jirix.JiriManifestFile()
	}
	if outFile == "-" {
		bytes, err := manifest.ToBytes()
		if err != nil {
			return err
		}
		_, err = os.Stdout.Write(bytes)
		return err
	}
	return manifest.ToFile(jirix, outFile)
}
Example #3
0
func runSnapshotCheckout(jirix *jiri.X, args []string) error {
	if len(args) != 1 {
		return jirix.UsageErrorf("unexpected number of arguments")
	}
	return project.CheckoutSnapshot(jirix, args[0], snapshotGcFlag)
}
Example #4
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
}
Example #5
0
func runCLMailCurrent(jirix *jiri.X, _ []string) error {
	// Check that working dir exist on remote branch.  Otherwise checking out
	// remote branch will break the users working dir.
	git := gitutil.New(jirix.NewSeq())
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	relWd, err := filepath.Rel(topLevel, wd)
	if err != nil {
		return err
	}
	if !git.DirExistsOnBranch(relWd, remoteBranchFlag) {
		return fmt.Errorf("directory %q does not exist on branch %q.\nPlease run 'jiri cl mail' from root directory of this repo.", relWd, remoteBranchFlag)
	}

	// Sanity checks for the <presubmitFlag> flag.
	if !checkPresubmitFlag() {
		return jirix.UsageErrorf("invalid value for the -presubmit flag. Valid values: %s.",
			strings.Join(gerrit.PresubmitTestTypes(), ","))
	}

	p, err := currentProject(jirix)
	if err != nil {
		return err
	}

	host := hostFlag
	if host == "" {
		if p.GerritHost == "" {
			return fmt.Errorf("No gerrit host found.  Please use the '--host' flag, or add a 'gerrithost' attribute for project %q.", p.Name)
		}
		host = p.GerritHost
	}
	hostUrl, err := url.Parse(host)
	if err != nil {
		return fmt.Errorf("invalid Gerrit host %q: %v", host, err)
	}
	projectRemoteUrl, err := url.Parse(p.Remote)
	if err != nil {
		return fmt.Errorf("invalid project remote: %v", p.Remote, err)
	}
	gerritRemote := *hostUrl
	gerritRemote.Path = projectRemoteUrl.Path

	// Create and run the review.
	review, err := newReview(jirix, p, gerrit.CLOpts{
		Autosubmit:   autosubmitFlag,
		Ccs:          parseEmails(ccsFlag),
		Draft:        draftFlag,
		Edit:         editFlag,
		Remote:       gerritRemote.String(),
		Host:         hostUrl,
		Presubmit:    gerrit.PresubmitTestType(presubmitFlag),
		RemoteBranch: remoteBranchFlag,
		Reviewers:    parseEmails(reviewersFlag),
		Verify:       verifyFlag,
	})
	if err != nil {
		return err
	}
	if confirmed, err := review.confirmFlagChanges(); err != nil {
		return err
	} else if !confirmed {
		return nil
	}
	err = review.run()
	// Ignore the error that is returned when there are no differences
	// between the local and gerrit branches.
	if err != nil && noChangesRE.MatchString(err.Error()) {
		return nil
	}
	return err
}
Example #6
0
func runCLCleanup(jirix *jiri.X, args []string) error {
	if len(args) == 0 {
		return jirix.UsageErrorf("cleanup requires at least one argument")
	}
	return cleanupCL(jirix, args)
}
Example #7
0
func runCLNew(jirix *jiri.X, args []string) error {
	if got, want := len(args), 1; got != want {
		return jirix.UsageErrorf("unexpected number of arguments: got %v, want %v", got, want)
	}
	return newCL(jirix, args)
}