Пример #1
0
// ThirdPartyCCodePath returns that path to the directory containing built
// binaries for the target OS and architecture.
func ThirdPartyCCodePath(os, arch string) (string, error) {
	root, err := project.JiriRoot()
	if err != nil {
		return "", err
	}
	return filepath.Join(root, "third_party", "cout", fmt.Sprintf("%s_%s", os, arch)), nil
}
Пример #2
0
// WARNING: this function is in the proces of being removed and replaced
// by the profiles based configuration (see jiri/profiles). Use
// profiles.ConfigHelper instead of this for new code.
//
// JiriLegacyEnvironment returns the environment variables setting for the project.
// The util package captures the original state of the relevant environment
// variables when the tool is initialized and every invocation of this function
// updates this original state according to the jiri tool configuration.
//
// By default, the Go and VDL workspaces are added to the GOPATH and VDLPATH
// environment variables respectively. In addition, the JIRI_PROFILE
// environment variable can be used to activate an environment variable setting
// for various development profiles of the project (e.g. arm, android, java, or
// nacl).  Unlike the default setting, the setting enabled by the JIRI_PROFILE
// environment variable can override existing environment.
func JiriLegacyEnvironment(ctx *tool.Context) (*envvar.Vars, error) {
	env := envvar.VarsFromOS()
	root, err := project.JiriRoot()
	if err != nil {
		return nil, err
	}
	config, err := LoadConfig(ctx)
	if err != nil {
		return nil, err
	}
	env.Set("CGO_ENABLED", "1")
	if err := setGoPath(ctx, env, root, config); err != nil {
		return nil, err
	}
	if err := setVdlPath(ctx, env, root, config); err != nil {
		return nil, err
	}
	if profile := os.Getenv(jiriProfileEnv); profile != "" {
		fmt.Fprintf(ctx.Stdout(), `NOTE: Enabling environment variable setting for %q.
This can override values of existing environment variables.
`, profile)
		switch profile {
		case "android":
			// Cross-compilation for android on linux.
			if err := setAndroidEnv(ctx, env, root); err != nil {
				return nil, err
			}
		case "arm":
			// Cross-compilation for arm on linux.
			if err := setArmEnv(ctx, env, root); err != nil {
				return nil, err
			}
		case "java":
			// Building of a Go shared library for Java.
			if err := setJavaEnv(ctx, env, root); err != nil {
				return nil, err
			}
		case "nacl":
			// Cross-compilation for nacl.
			if err := setNaclEnv(ctx, env, root); err != nil {
				return nil, err
			}
		default:
			fmt.Fprintf(ctx.Stderr(), "Unknown environment profile %q", profile)
		}
	}
	if err := setSyncbaseEnv(ctx, env, root); err != nil {
		return nil, err
	}
	return env, nil
}
Пример #3
0
func Init(defaultManifestFilename string) {
	targetFlag = profiles.DefaultTarget()

	var err error
	rootDir, err = project.JiriRoot()
	if err != nil {
		panic(err)
	}
	manifest := filepath.Join(rootDir, defaultManifestFilename)

	// Every sub-command accepts: --manifest
	for _, fs := range []*flag.FlagSet{
		&cmdInstall.Flags,
		&cmdUpdate.Flags,
		&cmdCleanup.Flags,
		&cmdUninstall.Flags,
		&cmdEnv.Flags,
		&cmdList.Flags,
		&cmdRecreate.Flags} {
		profiles.RegisterManifestFlag(fs, &manifestFlag, manifest)
	}

	// install accepts: --target and, --env.
	profiles.RegisterTargetAndEnvFlags(&cmdInstall.Flags, &targetFlag)

	// uninstall and env accept: --target,
	for _, fs := range []*flag.FlagSet{
		&cmdUninstall.Flags,
		&cmdEnv.Flags} {
		profiles.RegisterTargetFlag(fs, &targetFlag)
	}

	// uninstall accept --all-targets but with different defaults.
	cmdUninstall.Flags.BoolVar(&allFlag, "all-targets", false, "apply to all targets for the specified profile(s)")

	// update accepts --v
	cmdUpdate.Flags.BoolVar(&verboseFlag, "v", false, "print more detailed information")

	// list accepts --show-manifest, --availabe, --v
	cmdList.Flags.BoolVar(&showManifestFlag, "show-manifest", false, "print out the manifest file")
	cmdList.Flags.BoolVar(&availableFlag, "available", false, "print the list of available profiles")
	cmdList.Flags.BoolVar(&verboseFlag, "v", false, "print more detailed information")

	// env accepts --profile
	cmdEnv.Flags.StringVar(&profileFlag, "profile", "", "the profile whose environment is to be displayed")

	for _, mgr := range profiles.Managers() {
		profiles.LookupManager(mgr).AddFlags(&cmdInstall.Flags, profiles.Install)
		profiles.LookupManager(mgr).AddFlags(&cmdUninstall.Flags, profiles.Uninstall)
	}
}
Пример #4
0
// ThirdPartyBinPath returns the path to the given third-party tool
// taking into account the host and the target Go architecture.
func ThirdPartyBinPath(name string) (string, error) {
	root, err := project.JiriRoot()
	if err != nil {
		return "", err
	}
	bin := filepath.Join(root, "third_party", "go", "bin", name)
	goArch := os.Getenv("GOARCH")
	machineArch, err := host.Arch()
	if err != nil {
		return "", err
	}
	if goArch != "" && goArch != machineArch {
		bin = filepath.Join(root, "third_party", "go", "bin", fmt.Sprintf("%s_%s", runtime.GOOS, goArch), name)
	}
	return bin, nil
}
Пример #5
0
// TestJiriRootSymlink checks that JiriRoot interprets the value
// of the JIRI_ROOT environment variable as a path, evaluates any
// symlinks the path might contain, and returns the result.
func TestJiriRootSymlink(t *testing.T) {
	ctx := tool.NewDefaultContext()

	// Create a temporary directory.
	tmpDir, err := ctx.Run().TempDir("", "")
	if err != nil {
		t.Fatalf("TempDir() failed: %v", err)
	}
	defer ctx.Run().RemoveAll(tmpDir)

	// Make sure tmpDir is not a symlink itself.
	tmpDir, err = filepath.EvalSymlinks(tmpDir)
	if err != nil {
		t.Fatalf("EvalSymlinks(%v) failed: %v", tmpDir, err)
	}

	// Create a directory and a symlink to it.
	root, perm := filepath.Join(tmpDir, "root"), os.FileMode(0700)
	if err := ctx.Run().MkdirAll(root, perm); err != nil {
		t.Fatalf("%v", err)
	}
	symRoot := filepath.Join(tmpDir, "sym_root")
	if err := ctx.Run().Symlink(root, symRoot); err != nil {
		t.Fatalf("%v", err)
	}

	// Set the JIRI_ROOT to the symlink created above and check
	// that JiriRoot() evaluates the symlink.
	oldRoot := os.Getenv("JIRI_ROOT")
	if err := os.Setenv("JIRI_ROOT", symRoot); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)
	got, err := project.JiriRoot()
	if err != nil {
		t.Fatalf("%v", err)
	}
	if want := root; got != want {
		t.Fatalf("unexpected output: got %v, want %v", got, want)
	}
}
Пример #6
0
func runUpdate(env *cmdline.Env, _ []string) error {
	ctx := tool.NewContextFromEnv(env)

	// Create a snapshot of the current state of all projects and
	// write it to the $JIRI_ROOT/.update_history folder.
	root, err := project.JiriRoot()
	if err != nil {
		return err
	}
	snapshotFile := filepath.Join(root, ".update_history", time.Now().Format(time.RFC3339))
	if err := project.CreateSnapshot(ctx, snapshotFile); err != nil {
		return err
	}

	// Update all projects to their latest version.
	// Attempt <attemptsFlag> times before failing.
	updateFn := func() error {
		return project.UpdateUniverse(ctx, gcFlag)
	}
	return retry.Function(ctx, updateFn, retry.AttemptsOpt(attemptsFlag))
}
Пример #7
0
func TestEnvFromTarget(t *testing.T) {
	profiles.Clear()
	root, _ := project.JiriRoot()
	ctx := tool.NewDefaultContext()
	profiles.InstallProfile("a", "root")
	profiles.InstallProfile("b", "root")
	t1, t2 := &profiles.Target{}, &profiles.Target{}
	t1.Set("t1=cpu1-os1")
	t1.Env.Set("A=B C=D, B=C Z=Z")
	t2.Set("t1=cpu1-os1")
	t2.Env.Set("A=Z,B=Z,Z=Z")
	profiles.AddProfileTarget("a", *t1)
	profiles.AddProfileTarget("b", *t2)
	tmpdir, err := ioutil.TempDir(".", "pdb")
	if err != nil {
		t.Fatal(err)
	}
	filename := filepath.Join("release", "go", "src", "v.io", "jiri", "profiles", tmpdir, "manifest")
	if err := profiles.Write(ctx, filepath.Join(root, filename)); err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tmpdir)
	ch, err := profiles.NewConfigHelper(ctx, profiles.UseProfiles, filename)
	if err != nil {
		t.Fatal(err)
	}
	ch.Vars = envvar.VarsFromSlice([]string{})
	target, _ := profiles.NewTarget("t1=")
	ch.SetEnvFromProfiles(map[string]string{"A": " "}, map[string]bool{"Z": true}, "a,b", target)
	vars := ch.ToMap()
	if got, want := len(vars), 3; got != want {
		t.Errorf("got %v, want %v", got, want)
	}
	if got, want := ch.Get("A"), "B C=D Z"; got != want {
		t.Errorf("got %v, want %v", got, want)
	}
	if got, want := ch.Get("B"), "Z"; got != want {
		t.Errorf("got %v, want %v", got, want)
	}
}
Пример #8
0
// NewConfigHelper creates a new config helper. If filename is of non-zero
// length then that file will be read as a profiles manifest file, if not, the
// existing, if any, in-memory profiles information will be used. If SkipProfiles
// is specified for profilesMode, then no profiles are used.
func NewConfigHelper(ctx *tool.Context, profilesMode ProfilesMode, filename string) (*ConfigHelper, error) {
	root, err := project.JiriRoot()
	if err != nil {
		return nil, err
	}
	config, err := util.LoadConfig(ctx)
	if err != nil {
		return nil, err
	}
	projects, tools, err := project.ReadManifest(ctx)
	if err != nil {
		return nil, err
	}
	if profilesMode == UseProfiles && len(filename) > 0 {
		if err := Read(ctx, filepath.Join(root, filename)); err != nil {
			return nil, err
		}
	}
	ch := &ConfigHelper{
		ctx:          ctx,
		root:         root,
		config:       config,
		projects:     projects,
		tools:        tools,
		profilesMode: bool(profilesMode),
	}
	ch.Vars = envvar.VarsFromOS()
	if profilesMode == SkipProfiles {
		return ch, nil
	}
	ch.legacyMode = (SchemaVersion() == Original) || (len(os.Getenv("JIRI_PROFILE")) > 0)
	if ch.legacyMode {
		vars, err := util.JiriLegacyEnvironment(ch.ctx)
		if err != nil {
			return nil, err
		}
		ch.Vars = vars
	}
	return ch, nil
}
Пример #9
0
func TestConfigSerialization(t *testing.T) {
	ctx := tool.NewDefaultContext()

	root, err := project.NewFakeJiriRoot(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer func() {
		if err := root.Cleanup(ctx); err != nil {
			t.Fatalf("%v", err)
		}
	}()
	oldRoot, err := project.JiriRoot()
	if err := os.Setenv("JIRI_ROOT", root.Dir); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)

	config := NewConfig(
		APICheckProjectsOpt(apiCheckProjects),
		CopyrightCheckProjectsOpt(copyrightCheckProjects),
		GoWorkspacesOpt(goWorkspaces),
		JenkinsMatrixJobsOpt(jenkinsMatrixJobs),
		ProjectTestsOpt(projectTests),
		TestDependenciesOpt(testDependencies),
		TestGroupsOpt(testGroups),
		TestPartsOpt(testParts),
		VDLWorkspacesOpt(vdlWorkspaces),
	)

	if err := SaveConfig(ctx, config); err != nil {
		t.Fatalf("%v", err)
	}
	gotConfig, err := LoadConfig(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}

	testConfigAPI(t, gotConfig)
}
Пример #10
0
func TestList(t *testing.T) {
	ctx := tool.NewDefaultContext()

	// Setup a fake JIRI_ROOT.
	root, err := project.NewFakeJiriRoot(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer func() {
		if err := root.Cleanup(ctx); err != nil {
			t.Fatalf("%v", err)
		}
	}()
	oldRoot, err := project.JiriRoot()
	if err := os.Setenv("JIRI_ROOT", root.Dir); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)

	remoteSnapshotDir, err := project.RemoteSnapshotDir()
	if err != nil {
		t.Fatalf("%v", err)
	}
	localSnapshotDir, err := project.LocalSnapshotDir()
	if err != nil {
		t.Fatalf("%v", err)
	}

	// Create a test suite.
	tests := []config{
		config{
			remote: false,
			dir:    localSnapshotDir,
		},
		config{
			remote: true,
			dir:    remoteSnapshotDir,
		},
	}
	labels := []label{
		label{
			name:      "beta",
			snapshots: []string{"beta-1", "beta-2", "beta-3"},
		},
		label{
			name:      "stable",
			snapshots: []string{"stable-1", "stable-2", "stable-3"},
		},
	}

	for _, test := range tests {
		remoteFlag = test.remote
		// Create the snapshots directory and populate it with the
		// data specified by the test suite.
		for _, label := range labels {
			createLabelDir(t, ctx, test.dir, label.name, label.snapshots)
		}

		// Check that running "jiri snapshot list" with no arguments
		// returns the expected output.
		var stdout bytes.Buffer
		env := &cmdline.Env{Stdout: &stdout}
		if err != nil {
			t.Fatalf("%v", err)
		}
		if err := runSnapshotList(env, nil); err != nil {
			t.Fatalf("%v", err)
		}
		got, want := stdout.String(), generateOutput(labels)
		if got != want {
			t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
		}

		// Check that running "jiri snapshot list" with one argument
		// returns the expected output.
		stdout.Reset()
		if err := runSnapshotList(env, []string{"stable"}); err != nil {
			t.Fatalf("%v", err)
		}
		got, want = stdout.String(), generateOutput(labels[1:])
		if got != want {
			t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
		}

		// Check that running "jiri snapshot list" with
		// multiple arguments returns the expected output.
		stdout.Reset()
		if err := runSnapshotList(env, []string{"beta", "stable"}); err != nil {
			t.Fatalf("%v", err)
		}
		got, want = stdout.String(), generateOutput(labels)
		if got != want {
			t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
		}
	}
}
Пример #11
0
func TestCreate(t *testing.T) {
	ctx := tool.NewDefaultContext()

	// Setup a fake JIRI_ROOT instance.
	root, err := project.NewFakeJiriRoot(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer func() {
		if err := root.Cleanup(ctx); err != nil {
			t.Fatalf("%v", err)
		}
	}()

	// Setup the initial remote and local projects.
	numProjects, remoteProjects := 2, []string{}
	for i := 0; i < numProjects; i++ {
		if err := root.CreateRemoteProject(ctx, remoteProjectName(i)); err != nil {
			t.Fatalf("%v", err)
		}
		if err := root.AddProject(ctx, project.Project{
			Name:   remoteProjectName(i),
			Path:   localProjectName(i),
			Remote: root.Projects[remoteProjectName(i)],
		}); err != nil {
			t.Fatalf("%v", err)
		}
	}

	// Point the JIRI_ROOT environment variable to the fake.
	oldRoot, err := project.JiriRoot()
	if err := os.Setenv("JIRI_ROOT", root.Dir); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)

	// Create initial commits in the remote projects and use
	// UpdateUniverse() to mirror them locally.
	for i := 0; i < numProjects; i++ {
		writeReadme(t, ctx, root.Projects[remoteProjectName(i)], "revision 1")
	}
	if err := project.UpdateUniverse(ctx, true); err != nil {
		t.Fatalf("%v", err)
	}

	// Create a local snapshot.
	var stdout bytes.Buffer
	env := &cmdline.Env{Stdout: &stdout}
	remoteFlag = false
	if err := runSnapshotCreate(env, []string{"test-local"}); err != nil {
		t.Fatalf("%v", err)
	}

	// Remove the local project repositories.
	for i, _ := range remoteProjects {
		localProject := filepath.Join(root.Dir, localProjectName(i))
		if err := ctx.Run().RemoveAll(localProject); err != nil {
			t.Fatalf("%v", err)
		}
	}

	// Check that invoking the UpdateUniverse() with the local
	// snapshot restores the local repositories.
	snapshotDir, err := project.LocalSnapshotDir()
	if err != nil {
		t.Fatalf("%v", err)
	}
	snapshotFile := filepath.Join(snapshotDir, "test-local")
	localCtx := ctx.Clone(tool.ContextOpts{
		Manifest: &snapshotFile,
	})
	if err := project.UpdateUniverse(localCtx, true); err != nil {
		t.Fatalf("%v", err)
	}
	for i, _ := range remoteProjects {
		localProject := filepath.Join(root.Dir, localProjectName(i))
		checkReadme(t, ctx, localProject, "revision 1")
	}

	// Create a remote snapshot.
	remoteFlag = true
	root.EnableRemoteManifestPush(ctx)
	if err := runSnapshotCreate(env, []string{"test-remote"}); err != nil {
		t.Fatalf("%v", err)
	}

	// Remove the local project repositories.
	for i, _ := range remoteProjects {
		localProject := filepath.Join(root.Dir, localProjectName(i))
		if err := ctx.Run().RemoveAll(localProject); err != nil {
			t.Fatalf("%v", err)
		}
	}

	// Check that invoking the UpdateUniverse() with the remote snapshot
	// restores the local repositories.
	manifest := "snapshot/test-remote"
	remoteCtx := ctx.Clone(tool.ContextOpts{
		Manifest: &manifest,
	})
	if err := project.UpdateUniverse(remoteCtx, true); err != nil {
		t.Fatalf("%v", err)
	}
	for i, _ := range remoteProjects {
		localProject := filepath.Join(root.Dir, localProjectName(i))
		checkReadme(t, ctx, localProject, "revision 1")
	}
}
Пример #12
0
func TestOncall(t *testing.T) {
	ctx := tool.NewDefaultContext()
	root, err := project.NewFakeJiriRoot(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer func() {
		if err := root.Cleanup(ctx); err != nil {
			t.Fatalf("%v", err)
		}
	}()
	oldRoot, err := project.JiriRoot()
	if err != nil {
		t.Fatalf("%v", err)
	}
	if err := os.Setenv("JIRI_ROOT", root.Dir); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)

	// Create a oncall.v1.xml file.
	createOncallFile(t, ctx)
	type testCase struct {
		targetTime    time.Time
		expectedShift *OncallShift
	}
	testCases := []testCase{
		testCase{
			targetTime:    time.Date(2013, time.November, 5, 12, 0, 0, 0, time.Local),
			expectedShift: nil,
		},
		testCase{
			targetTime: time.Date(2014, time.November, 5, 12, 0, 0, 0, time.Local),
			expectedShift: &OncallShift{
				Primary:   "spetrovic",
				Secondary: "suharshs",
				Date:      "Nov 5, 2014 12:00:00 PM",
			},
		},
		testCase{
			targetTime: time.Date(2014, time.November, 5, 14, 0, 0, 0, time.Local),
			expectedShift: &OncallShift{
				Primary:   "spetrovic",
				Secondary: "suharshs",
				Date:      "Nov 5, 2014 12:00:00 PM",
			},
		},
		testCase{
			targetTime: time.Date(2014, time.November, 20, 14, 0, 0, 0, time.Local),
			expectedShift: &OncallShift{
				Primary:   "jsimsa",
				Secondary: "toddw",
				Date:      "Nov 19, 2014 12:00:00 PM",
			},
		},
	}
	for _, test := range testCases {
		got, err := Oncall(ctx, test.targetTime)
		if err != nil {
			t.Fatalf("want no errors, got: %v", err)
		}
		if !reflect.DeepEqual(test.expectedShift, got) {
			t.Fatalf("want %#v, got %#v", test.expectedShift, got)
		}
	}
}
Пример #13
0
func testSetPathHelper(t *testing.T, name string) {
	profiles.Clear()
	ctx := tool.NewDefaultContext()

	// Setup a fake JIRI_ROOT.
	root, err := project.NewFakeJiriRoot(ctx)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer func() {
		if err := root.Cleanup(ctx); err != nil {
			t.Fatalf("%v", err)
		}
	}()

	// Create a test project and identify it as a Go workspace.
	if err := root.CreateRemoteProject(ctx, "test"); err != nil {
		t.Fatalf("%v", err)
	}
	if err := root.AddProject(ctx, project.Project{
		Name:   "test",
		Path:   "test",
		Remote: root.Projects["test"],
	}); err != nil {
		t.Fatalf("%v", err)
	}
	if err := root.UpdateUniverse(ctx, false); err != nil {
		t.Fatalf("%v", err)
	}
	var config *util.Config
	switch name {
	case "GOPATH":
		config = util.NewConfig(util.GoWorkspacesOpt([]string{"test", "does/not/exist"}))
	case "VDLPATH":
		config = util.NewConfig(util.VDLWorkspacesOpt([]string{"test", "does/not/exist"}))
	}

	oldRoot, err := project.JiriRoot()
	if err := os.Setenv("JIRI_ROOT", root.Dir); err != nil {
		t.Fatalf("%v", err)
	}
	defer os.Setenv("JIRI_ROOT", oldRoot)

	if err := profiles.Write(ctx, filepath.Join(root.Dir, "profiles-manifest")); err != nil {
		t.Fatal(err)
	}

	if err := util.SaveConfig(ctx, config); err != nil {
		t.Fatalf("%v", err)
	}

	// Retrieve Jiri_ROOT through JiriRoot() to account for symlinks.
	jiriRoot, err := project.JiriRoot()
	if err != nil {
		t.Fatalf("%v", err)
	}

	ch, err := profiles.NewConfigHelper(ctx, profiles.UseProfiles, "profiles-manifest")
	if err != nil {
		t.Fatal(err)
	}
	ch.Vars = envvar.VarsFromOS()
	ch.Set(name, "")

	var want string
	switch name {
	case "GOPATH":
		want = filepath.Join(jiriRoot, "test")
		ch.SetGoPath()
	case "VDLPATH":
		// Make a fake src directory.
		want = filepath.Join(jiriRoot, "test", "src")
		if err := ctx.Run().MkdirAll(want, 0755); err != nil {
			t.Fatalf("%v", err)
		}
		ch.SetVDLPath()
	}
	if got := ch.Get(name); got != want {
		t.Fatalf("unexpected value: got %v, want %v", got, want)
	}
}