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) }
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) }
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) }
// 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 }
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 }
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) }
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) }