Ejemplo n.º 1
0
func linuxList(jirix *jiri.X, pkgs []string) (map[string]bool, error) {
	aptitude, yum, pacman := UsingAptitude(jirix), UsingYum(jirix), UsingPacman(jirix)
	cmd := ""
	opt := ""
	switch {
	case aptitude:
		cmd = "dpkg"
		opt = "-L"
	case yum:
		cmd = "yum"
		opt = "list"
	case pacman:
		cmd = "pacman"
		opt = "-Q"
	default:
		return nil, fmt.Errorf("no usable package manager found, tested for aptitude, yum and pacman")
	}
	s := jirix.NewSeq()
	installedPkgs := map[string]bool{}
	for _, pkg := range pkgs {
		if err := s.Capture(ioutil.Discard, ioutil.Discard).Last(cmd, opt, pkg); err == nil {
			installedPkgs[pkg] = true
		}
	}
	return installedPkgs, nil
}
Ejemplo n.º 2
0
func packagesImpl(jirix *jiri.X, cl *packagesFlagValues, args []string) error {
	mgrs, _, err := availableProfileManagers(jirix, cl.dbPath, args)
	if err != nil {
		return err
	}
	cl.target.UseCommandLineEnv()
	root := jiri.NewRelPath(cl.root).Join(profileInstaller)
	s := jirix.NewSeq()
	installPackages := cl.installPackages
	// Never ask a subcommand to install packages.
	cl.installPackages = false
	for _, mgr := range mgrs {
		cmds, err := mgr.packageCmds(jirix, cl, root)
		if err != nil {
			return err
		}
		for _, cmd := range cmds {
			if installPackages {
				if err := s.Verbose(true).Last(cmd[0], cmd[1:]...); err != nil {
					return err
				}
			} else {
				fmt.Fprintf(jirix.Stdout(), "%s\n", strings.TrimSpace(strings.Join(cmd, " ")))
			}
		}
	}
	return nil
}
Ejemplo n.º 3
0
func runUpdate(jirix *jiri.X, _ []string) error {
	seq := jirix.NewSeq()
	// Create the $JIRI_ROOT/.jiri_root directory if it doesn't already exist.
	//
	// TODO(toddw): Remove this logic after the transition to .jiri_root is done.
	// The bootstrapping logic should create this directory, and jiri should fail
	// if the directory doesn't exist.
	if err := seq.MkdirAll(jirix.RootMetaDir(), 0755).Done(); err != nil {
		return err
	}

	// Update all projects to their latest version.
	// Attempt <attemptsFlag> times before failing.
	updateFn := func() error { return project.UpdateUniverse(jirix, gcFlag) }
	if err := retry.Function(jirix.Context, updateFn, retry.AttemptsOpt(attemptsFlag)); err != nil {
		return err
	}
	if err := project.WriteUpdateHistorySnapshot(jirix, ""); err != nil {
		return err
	}

	// Only attempt the bin dir transition after the update has succeeded, to
	// avoid messy partial states.
	return project.TransitionBinDir(jirix)
}
Ejemplo n.º 4
0
func getCommitMessageFileName(jirix *jiri.X, branch string) (string, error) {
	topLevel, err := gitutil.New(jirix.NewSeq()).TopLevel()
	if err != nil {
		return "", err
	}
	return filepath.Join(topLevel, jiri.ProjectMetaDir, branch, commitMessageFileName), nil
}
Ejemplo n.º 5
0
func runRebuild(jirix *jiri.X, args []string) (e error) {
	projects, tools, err := project.LoadManifest(jirix)
	if err != nil {
		return err
	}

	// Create a temporary directory in which tools will be built.
	tmpDir, err := jirix.NewSeq().TempDir("", "tmp-jiri-rebuild")
	if err != nil {
		return fmt.Errorf("TempDir() failed: %v", err)
	}

	// Make sure we cleanup the temp directory.
	defer collect.Error(func() error { return jirix.NewSeq().RemoveAll(tmpDir).Done() }, &e)

	// Paranoid sanity checking.
	if _, ok := tools[project.JiriName]; !ok {
		return fmt.Errorf("tool %q not found", project.JiriName)
	}

	// Build and install tools.
	if err := project.BuildTools(jirix, projects, tools, tmpDir); err != nil {
		return err
	}
	return project.InstallTools(jirix, tmpDir)
}
Ejemplo n.º 6
0
// AtomicAction performs an action 'atomically' by keeping track of successfully
// completed actions in the supplied completion log and re-running them if they
// are not successfully logged therein after deleting the entire contents of the
// dir parameter. Consequently it does not make sense to apply AtomicAction to
// the same directory in sequence.
func AtomicAction(jirix *jiri.X, installFn func() error, dir, message string) error {
	atomicFn := func() error {
		completionLogPath := filepath.Join(dir, ".complete")
		s := jirix.NewSeq()
		if dir != "" {
			if exists, _ := s.IsDir(dir); exists {
				// If the dir exists but the completionLogPath doesn't, then it
				// means the previous action didn't finish.
				// Remove the dir so we can perform the action again.
				if exists, _ := s.IsFile(completionLogPath); !exists {
					s.RemoveAll(dir).Done()
				} else {
					if jirix.Verbose() {
						fmt.Fprintf(jirix.Stdout(), "AtomicAction: %s already completed in %s\n", message, dir)
					}
					return nil
				}
			}
		}
		if err := installFn(); err != nil {
			if dir != "" {
				s.RemoveAll(dir).Done()
			}
			return err
		}
		return s.WriteFile(completionLogPath, []byte("completed"), DefaultFilePerm).Done()
	}
	return jirix.NewSeq().Call(atomicFn, message).Done()
}
Ejemplo n.º 7
0
// checkDependents makes sure that all CLs in the sequence of
// dependent CLs leading to (but not including) the current branch
// have been exported to Gerrit.
func checkDependents(jirix *jiri.X) (e error) {
	originalBranch, err := gitutil.New(jirix.NewSeq()).CurrentBranchName()
	if err != nil {
		return err
	}
	branches, err := getDependentCLs(jirix, originalBranch)
	if err != nil {
		return err
	}
	for i := 1; i < len(branches); i++ {
		file, err := getCommitMessageFileName(jirix, branches[i])
		if err != nil {
			return err
		}
		if _, err := jirix.NewSeq().Stat(file); err != nil {
			if !runutil.IsNotExist(err) {
				return err
			}
			return fmt.Errorf(`Failed to export the branch %q to Gerrit because its ancestor %q has not been exported to Gerrit yet.
The following steps are needed before the operation can be retried:
$ git checkout %v
$ jiri cl mail
$ git checkout %v
# retry the original command
`, originalBranch, branches[i], branches[i], originalBranch)
		}
	}

	return nil
}
Ejemplo n.º 8
0
// assertFilesNotCommitted asserts that the files exist and are *not*
// committed in the current branch.
func assertFilesNotCommitted(t *testing.T, jirix *jiri.X, files []string) {
	assertFilesExist(t, jirix, files)
	for _, file := range files {
		if gitutil.New(jirix.NewSeq()).IsFileCommitted(file) {
			t.Fatalf("expected file %v not to be committed but it is", file)
		}
	}
}
Ejemplo n.º 9
0
// assertStashSize asserts that the stash size matches the expected
// size.
func assertStashSize(t *testing.T, jirix *jiri.X, want int) {
	got, err := gitutil.New(jirix.NewSeq()).StashSize()
	if err != nil {
		t.Fatalf("%v", err)
	}
	if got != want {
		t.Fatalf("unxpected stash size: got %v, want %v", got, want)
	}
}
Ejemplo n.º 10
0
// Untar untars the file in srcFile and puts resulting files in directory dstDir.
func Untar(jirix *jiri.X, srcFile, dstDir string) error {
	s := jirix.NewSeq()
	if err := s.MkdirAll(dstDir, 0755).Done(); err != nil {
		return err
	}
	return s.Output([]string{"untarring " + srcFile + " into " + dstDir}).
		Pushd(dstDir).
		Last("tar", "xvf", srcFile)
}
Ejemplo n.º 11
0
// assertCommitCount asserts that the commit count between two
// branches matches the expectedCount.
func assertCommitCount(t *testing.T, jirix *jiri.X, branch, baseBranch string, expectedCount int) {
	got, err := gitutil.New(jirix.NewSeq()).CountCommits(branch, baseBranch)
	if err != nil {
		t.Fatalf("%v", err)
	}
	if want := 1; got != want {
		t.Fatalf("unexpected number of commits: got %v, want %v", got, want)
	}
}
Ejemplo n.º 12
0
// assertFilesPushedToRef asserts that the given files have been
// pushed to the given remote repository reference.
func assertFilesPushedToRef(t *testing.T, jirix *jiri.X, repoPath, gerritPath, pushedRef string, files []string) {
	chdir(t, jirix, gerritPath)
	assertCommitCount(t, jirix, pushedRef, "master", 1)
	if err := gitutil.New(jirix.NewSeq()).CheckoutBranch(pushedRef); err != nil {
		t.Fatalf("%v", err)
	}
	assertFilesCommitted(t, jirix, files)
	chdir(t, jirix, repoPath)
}
Ejemplo n.º 13
0
// assertFileContent asserts that the content of the given file
// matches the expected content.
func assertFileContent(t *testing.T, jirix *jiri.X, file, want string) {
	got, err := jirix.NewSeq().ReadFile(file)
	if err != nil {
		t.Fatalf("%v\n", err)
	}
	if string(got) != want {
		t.Fatalf("unexpected content of file %v: got %v, want %v", file, got, want)
	}
}
Ejemplo n.º 14
0
// assertFilesDoNotExist asserts that the files do not exist.
func assertFilesDoNotExist(t *testing.T, jirix *jiri.X, files []string) {
	s := jirix.NewSeq()
	for _, file := range files {
		if _, err := s.Stat(file); err != nil && !runutil.IsNotExist(err) {
			t.Fatalf("%v", err)
		} else if err == nil {
			t.Fatalf("expected file %v to not exist but it did", file)
		}
	}
}
Ejemplo n.º 15
0
// commitFile commits a file with the specified content into a branch
func commitFile(t *testing.T, jirix *jiri.X, filename string, content string) {
	s := jirix.NewSeq()
	if err := s.WriteFile(filename, []byte(content), 0644).Done(); err != nil {
		t.Fatalf("%v", err)
	}
	commitMessage := "Commit " + filename
	if err := gitutil.New(jirix.NewSeq()).CommitFile(filename, commitMessage); err != nil {
		t.Fatalf("%v", err)
	}
}
Ejemplo n.º 16
0
// createRepoFromOrigin creates a Git repo tracking origin/master.
func createRepoFromOrigin(t *testing.T, jirix *jiri.X, subpath string, originPath string) string {
	repoPath := createRepo(t, jirix, subpath)
	chdir(t, jirix, repoPath)
	if err := gitutil.New(jirix.NewSeq()).AddRemote("origin", originPath); err != nil {
		t.Fatalf("%v", err)
	}
	if err := gitutil.New(jirix.NewSeq()).Pull("origin", "master"); err != nil {
		t.Fatalf("%v", err)
	}
	return repoPath
}
Ejemplo n.º 17
0
// submit mocks a Gerrit review submit by pushing the Gerrit remote to origin.
// Actually origin pulls from Gerrit since origin isn't actually a bare git repo.
// Some of our tests actually rely on accessing .git in origin, so it must be non-bare.
func submit(t *testing.T, jirix *jiri.X, originPath string, gerritPath string, review *review) {
	cwd, err := os.Getwd()
	if err != nil {
		t.Fatalf("Getwd() failed: %v", err)
	}
	chdir(t, jirix, originPath)
	expectedRef := gerrit.Reference(review.CLOpts)
	if err := gitutil.New(jirix.NewSeq()).Pull(gerritPath, expectedRef); err != nil {
		t.Fatalf("Pull gerrit to origin failed: %v", err)
	}
	chdir(t, jirix, cwd)
}
Ejemplo n.º 18
0
func checkReadme(t *testing.T, jirix *jiri.X, p project.Project, message string) {
	if _, err := jirix.NewSeq().Stat(p.Path); err != nil {
		t.Fatalf("%v", err)
	}
	readmeFile := filepath.Join(p.Path, "README")
	data, err := ioutil.ReadFile(readmeFile)
	if err != nil {
		t.Fatalf("ReadFile(%v) failed: %v", readmeFile, err)
	}
	if got, want := data, []byte(message); bytes.Compare(got, want) != 0 {
		t.Fatalf("unexpected content in project %v:\ngot\n%s\nwant\n%s\n", p.Name, got, want)
	}
}
Ejemplo n.º 19
0
func brewList(jirix *jiri.X) (map[string]bool, error) {
	var out bytes.Buffer
	err := jirix.NewSeq().Capture(&out, &out).Last("brew", "list")
	if err != nil || tool.VerboseFlag {
		fmt.Fprintf(jirix.Stdout(), "%s", out.String())
	}
	scanner := bufio.NewScanner(&out)
	pkgs := map[string]bool{}
	for scanner.Scan() {
		pkgs[scanner.Text()] = true
	}
	return pkgs, err
}
Ejemplo n.º 20
0
func checkReadme(t *testing.T, jirix *jiri.X, project, message string) {
	s := jirix.NewSeq()
	if _, err := s.Stat(project); err != nil {
		t.Fatalf("%v", err)
	}
	readmeFile := filepath.Join(project, "README")
	data, err := s.ReadFile(readmeFile)
	if err != nil {
		t.Fatalf("%v", err)
	}
	if got, want := data, []byte(message); bytes.Compare(got, want) != 0 {
		t.Fatalf("unexpected content %v:\ngot\n%s\nwant\n%s\n", project, got, want)
	}
}
Ejemplo n.º 21
0
// Checks that /.jiri/ is ignored in a local project checkout
func checkMetadataIsIgnored(t *testing.T, jirix *jiri.X, p project.Project) {
	if _, err := jirix.NewSeq().Stat(p.Path); err != nil {
		t.Fatalf("%v", err)
	}
	gitInfoExcludeFile := filepath.Join(p.Path, ".git", "info", "exclude")
	data, err := ioutil.ReadFile(gitInfoExcludeFile)
	if err != nil {
		t.Fatalf("ReadFile(%v) failed: %v", gitInfoExcludeFile, err)
	}
	excludeString := "/.jiri/"
	if !strings.Contains(string(data), excludeString) {
		t.Fatalf("Did not find \"%v\" in exclude file", excludeString)
	}
}
Ejemplo n.º 22
0
func newCL(jirix *jiri.X, args []string) error {
	git := gitutil.New(jirix.NewSeq())
	topLevel, err := git.TopLevel()
	if err != nil {
		return err
	}
	originalBranch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}

	// Create a new branch using the current branch.
	newBranch := args[0]
	if err := git.CreateAndCheckoutBranch(newBranch); err != nil {
		return err
	}

	// Register a cleanup handler in case of subsequent errors.
	cleanup := true
	defer func() {
		if cleanup {
			git.CheckoutBranch(originalBranch, gitutil.ForceOpt(true))
			git.DeleteBranch(newBranch, gitutil.ForceOpt(true))
		}
	}()

	s := jirix.NewSeq()
	// Record the dependent CLs for the new branch. The dependent CLs
	// are recorded in a <dependencyPathFileName> file as a
	// newline-separated list of branch names.
	branches, err := getDependentCLs(jirix, originalBranch)
	if err != nil {
		return err
	}
	branches = append(branches, originalBranch)
	newMetadataDir := filepath.Join(topLevel, jiri.ProjectMetaDir, newBranch)
	if err := s.MkdirAll(newMetadataDir, os.FileMode(0755)).Done(); err != nil {
		return err
	}
	file, err := getDependencyPathFileName(jirix, newBranch)
	if err != nil {
		return err
	}
	if err := s.WriteFile(file, []byte(strings.Join(branches, "\n")), os.FileMode(0644)).Done(); err != nil {
		return err
	}

	cleanup = false
	return nil
}
Ejemplo n.º 23
0
// runCLMail is a wrapper that sets up and runs a review instance across
// multiple projects.
func runCLMail(jirix *jiri.X, _ []string) error {
	mp, err := initForMultiPart(jirix)
	if err != nil {
		return err
	}
	if mp.clean {
		if err := mp.cleanMultiPartMetadata(jirix); err != nil {
			return err
		}
		return nil
	}
	if mp.current {
		return runCLMailCurrent(jirix, []string{})
	}
	// multipart mode
	if err := mp.writeMultiPartMetadata(jirix); err != nil {
		mp.cleanMultiPartMetadata(jirix)
		return err
	}
	if err := runCLMailCurrent(jirix, []string{}); err != nil {
		return err
	}
	git := gitutil.New(jirix.NewSeq())
	branch, err := git.CurrentBranchName()
	if err != nil {
		return err
	}
	initialMessage, err := strippedGerritCommitMessage(jirix, branch)
	if err != nil {
		return err
	}
	s := jirix.NewSeq()
	tmp, err := s.TempFile("", branch+"-")
	if err != nil {
		return err
	}
	defer func() {
		tmp.Close()
		os.Remove(tmp.Name())
	}()
	if _, err := io.WriteString(tmp, initialMessage); err != nil {
		return err
	}
	// Use Capture to make sure that all output from the subcommands is
	// sent to stdout/stderr.
	flags := clMailMultiFlags()
	flags = append(flags, "--commit-message-body-file="+tmp.Name())
	return s.Capture(jirix.Stdout(), jirix.Stderr()).Last("jiri", mp.commandline(mp.currentKey, flags)...)
}
Ejemplo n.º 24
0
func (sc *subcommand) packageCmds(jirix *jiri.X, cl *packagesFlagValues, root jiri.RelPath) ([][]string, error) {
	cmd := []string{"profile-" + sc.installer, "os-packages"}
	cmd = append(cmd, cl.args()...)
	cmd = append(cmd, sc.qname)
	var out bytes.Buffer
	if err := jirix.NewSeq().Capture(&out, jirix.Stderr()).Last("jiri", cmd...); err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(&out)
	cmds := make([][]string, 0, 5)
	for scanner.Scan() {
		cmds = append(cmds, strings.Split(scanner.Text(), " "))
	}
	return cmds, nil
}
Ejemplo n.º 25
0
// gitCookies attempts to read and parse cookies from the .gitcookies file in
// the users home directory.
func gitCookies(jirix *jiri.X) []*http.Cookie {
	cookies := []*http.Cookie{}

	homeDir := os.Getenv("HOME")
	if homeDir == "" {
		return cookies
	}

	cookieFile := filepath.Join(homeDir, ".gitcookies")
	bytes, err := jirix.NewSeq().ReadFile(cookieFile)
	if err != nil {
		return cookies
	}
	return parseCookieFile(jirix, bytes)
}
Ejemplo n.º 26
0
// createTestRepos sets up three local repositories: origin, gerrit,
// and the main test repository which pulls from origin and can push
// to gerrit.
func createTestRepos(t *testing.T, jirix *jiri.X) (string, string, string) {
	// Create origin.
	originPath := createRepo(t, jirix, "origin")
	chdir(t, jirix, originPath)
	if err := gitutil.New(jirix.NewSeq()).CommitWithMessage("initial commit"); err != nil {
		t.Fatalf("%v", err)
	}
	// Create test repo.
	repoPath := createRepoFromOrigin(t, jirix, "test", originPath)
	// Add Gerrit remote.
	gerritPath := createRepoFromOrigin(t, jirix, "gerrit", originPath)
	// Switch back to test repo.
	chdir(t, jirix, repoPath)
	return repoPath, originPath, gerritPath
}
Ejemplo n.º 27
0
// strippedGerritCommitMessage returns the commit message stripped of variable
// meta-data such as multipart messages, or change IDs:
func strippedGerritCommitMessage(jirix *jiri.X, branch string) (string, error) {
	filename, err := getCommitMessageFileName(jirix, branch)
	if err != nil {
		return "", err
	}
	msg, err := jirix.NewSeq().ReadFile(filename)
	if err != nil {
		return "", err
	}
	// Strip "MultiPart ..." from the commit messages.
	strippedMessages := multiPartRE.ReplaceAllLiteralString(string(msg), "")
	// Strip "Change-Id: ..." from the commit messages.
	strippedMessages = changeIDRE.ReplaceAllLiteralString(strippedMessages, "")
	return strippedMessages, nil
}
Ejemplo n.º 28
0
// Unzip unzips the file in srcFile and puts resulting files in directory dstDir.
func Unzip(jirix *jiri.X, srcFile, dstDir string) error {
	r, err := zip.OpenReader(srcFile)
	if err != nil {
		return err
	}
	defer r.Close()

	unzipFn := func(zFile *zip.File) error {
		rc, err := zFile.Open()
		if err != nil {
			return err
		}
		defer rc.Close()

		s := jirix.NewSeq()
		fileDst := filepath.Join(dstDir, zFile.Name)
		if zFile.FileInfo().IsDir() {
			return s.MkdirAll(fileDst, zFile.Mode()).Done()
		}

		// Make sure the parent directory exists.  Note that sometimes files
		// can appear in a zip file before their directory.
		dirmode := zFile.Mode() | 0100
		if dirmode&0060 != 0 {
			// "group" has read or write permissions, so give
			// execute permissions on the directory.
			dirmode = dirmode | 0010
		}
		if err := s.MkdirAll(filepath.Dir(fileDst), dirmode).Done(); err != nil {
			return err
		}
		file, err := s.OpenFile(fileDst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, zFile.Mode())
		if err != nil {

			return err
		}
		defer file.Close()
		_, err = s.Copy(file, rc)
		return err
	}
	s := jirix.NewSeq()
	s.Output([]string{"unzipping " + srcFile})
	for _, zFile := range r.File {
		s.Output([]string{"extracting " + zFile.Name})
		s.Call(func() error { return unzipFn(zFile) }, "unzipFn(%s)", zFile.Name)
	}
	return s.Done()
}
Ejemplo n.º 29
0
func (mp *multiPart) cleanMultiPartMetadata(jirix *jiri.X) error {
	s := jirix.NewSeq()
	for _, state := range mp.states {
		filename := filepath.Join(state.Project.Path, jiri.ProjectMetaDir, mp.currentBranch, multiPartMetaDataFileName)
		ok, err := s.IsFile(filename)
		if err != nil {
			return err
		}
		if ok {
			if err := s.Remove(filename).Done(); err != nil {
				return err
			}
		}
	}
	return nil
}
Ejemplo n.º 30
0
func (eg *exampleManager) Uninstall(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	version, err := eg.versionInfo.Select(target.Version())
	if err != nil {
		return err
	}
	dir := eg.filename(root, target).Abs(jirix)
	if err := jirix.NewSeq().WriteFile(filepath.Join(dir, "version"), []byte(version), profilesutil.DefaultFilePerm).
		WriteFile(filepath.Join(dir, version), []byte(version), profilesutil.DefaultFilePerm).
		Remove(filepath.Join(dir, version)).
		Done(); err != nil {
		return err
	}
	if pdb.RemoveProfileTarget(eg.installer, eg.name, target) {
		eg.profile = nil
	}
	return nil
}