Merge "jiri: Remove support for old-style manifests."
diff --git a/.api b/.api
index d02b8f3..3983236 100644
--- a/.api
+++ b/.api
@@ -16,14 +16,12 @@
pkg jiri, method (*X) JiriManifestFile() string
pkg jiri, method (*X) ProfilesDBDir() string
pkg jiri, method (*X) ProfilesRootDir() string
-pkg jiri, method (*X) ResolveManifestPath(string) (string, error)
pkg jiri, method (*X) RootMetaDir() string
pkg jiri, method (*X) ScriptsDir() string
pkg jiri, method (*X) UpdateHistoryDir() string
pkg jiri, method (*X) UpdateHistoryLatestLink() string
pkg jiri, method (*X) UpdateHistorySecondLatestLink() string
pkg jiri, method (*X) UsageErrorf(string, ...interface{}) error
-pkg jiri, method (*X) UsingOldManifests() bool
pkg jiri, method (RelPath) Abs(*X) string
pkg jiri, method (RelPath) Join(...string) RelPath
pkg jiri, method (RelPath) Symbolic() string
diff --git a/cmd/jiri/cmd.go b/cmd/jiri/cmd.go
index a5d8ab5..5363083 100644
--- a/cmd/jiri/cmd.go
+++ b/cmd/jiri/cmd.go
@@ -41,7 +41,6 @@
cmdRebuild,
cmdSnapshot,
cmdUpdate,
- cmdUpgrade,
cmdWhich,
},
Topics: []cmdline.Topic{
diff --git a/cmd/jiri/doc.go b/cmd/jiri/doc.go
index 2b58edd..61a3e10 100644
--- a/cmd/jiri/doc.go
+++ b/cmd/jiri/doc.go
@@ -20,7 +20,6 @@
rebuild Rebuild all jiri tools
snapshot Manage project snapshots
update Update all jiri tools and projects
- upgrade Upgrade jiri to new-style manifests
which Show path to the jiri tool
help Display help for commands or topics
@@ -713,49 +712,6 @@
-v=false
Print verbose output.
-Jiri upgrade - Upgrade jiri to new-style manifests
-
-Upgrades jiri to use new-style manifests.
-
-The old (deprecated) behavior only allowed a single manifest repository, located
-in $JIRI_ROOT/.manifest. The initial manifest file is located as follows:
- 1) Use -manifest flag, if non-empty. If it's empty...
- 2) Use $JIRI_ROOT/.local_manifest file. If it doesn't exist...
- 3) Use $JIRI_ROOT/.manifest/v2/default.
-
-The new behavior allows multiple manifest repositories, by allowing imports to
-specify project attributes describing the remote repository. The -manifest flag
-is no longer allowed to be set; the initial manifest file is always located in
-$JIRI_ROOT/.jiri_manifest. The .local_manifest file is ignored.
-
-During the transition phase, both old and new behaviors are supported. The jiri
-tool uses the existence of the $JIRI_ROOT/.jiri_manifest file as the signal; if
-it exists we run the new behavior, otherwise we run the old behavior.
-
-The new behavior includes a "jiri import" command, which writes or updates the
-.jiri_manifest file. The new bootstrap procedure runs "jiri import", and it is
-intended as a regular command to add imports to your jiri environment.
-
-This upgrade command eases the transition by writing an initial .jiri_manifest
-file for you. If you have an existing .local_manifest file, its contents will
-be incorporated into the new .jiri_manifest file, and it will be renamed to
-.local_manifest.BACKUP. The -revert flag deletes the .jiri_manifest file, and
-restores the .local_manifest file.
-
-Usage:
- jiri upgrade [flags] <kind>
-
-<kind> specifies the kind of upgrade, one of "v23" or "fuchsia".
-
-The jiri upgrade flags are:
- -revert=false
- Revert the upgrade by deleting the $JIRI_ROOT/.jiri_manifest file.
-
- -color=true
- Use color to format output.
- -v=false
- Print verbose output.
-
Jiri which - Show path to the jiri tool
Which behaves similarly to the unix commandline tool. It is useful in
diff --git a/cmd/jiri/snapshot_test.go b/cmd/jiri/snapshot_test.go
index 151fb9b..78167a6 100644
--- a/cmd/jiri/snapshot_test.go
+++ b/cmd/jiri/snapshot_test.go
@@ -307,7 +307,7 @@
fake.EnableRemoteManifestPush()
defer fake.DisableRemoteManifestPush()
- manifestDir := filepath.Join(fake.X.Root, ".manifest")
+ manifestDir := filepath.Join(fake.X.Root, "manifest")
snapshotDir := filepath.Join(manifestDir, "snapshot")
label := "test"
diff --git a/cmd/jiri/upgrade.go b/cmd/jiri/upgrade.go
deleted file mode 100644
index 08eb99a..0000000
--- a/cmd/jiri/upgrade.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "fmt"
- "os"
- "path/filepath"
-
- "v.io/jiri"
- "v.io/jiri/project"
- "v.io/jiri/runutil"
- "v.io/x/lib/cmdline"
-)
-
-// TODO(toddw): Remove the upgrade command after the transition to new-style
-// manifests is complete.
-
-var flagUpgradeRevert bool
-
-func init() {
- cmdUpgrade.Flags.BoolVar(&flagUpgradeRevert, "revert", false, `Revert the upgrade by deleting the $JIRI_ROOT/.jiri_manifest file.`)
-}
-
-var cmdUpgrade = &cmdline.Command{
- Runner: jiri.RunnerFunc(runUpgrade),
- Name: "upgrade",
- Short: "Upgrade jiri to new-style manifests",
- Long: `
-Upgrades jiri to use new-style manifests.
-
-The old (deprecated) behavior only allowed a single manifest repository, located
-in $JIRI_ROOT/.manifest. The initial manifest file is located as follows:
- 1) Use -manifest flag, if non-empty. If it's empty...
- 2) Use $JIRI_ROOT/.local_manifest file. If it doesn't exist...
- 3) Use $JIRI_ROOT/.manifest/v2/default.
-
-The new behavior allows multiple manifest repositories, by allowing imports to
-specify project attributes describing the remote repository. The -manifest flag
-is no longer allowed to be set; the initial manifest file is always located in
-$JIRI_ROOT/.jiri_manifest. The .local_manifest file is ignored.
-
-During the transition phase, both old and new behaviors are supported. The jiri
-tool uses the existence of the $JIRI_ROOT/.jiri_manifest file as the signal; if
-it exists we run the new behavior, otherwise we run the old behavior.
-
-The new behavior includes a "jiri import" command, which writes or updates the
-.jiri_manifest file. The new bootstrap procedure runs "jiri import", and it is
-intended as a regular command to add imports to your jiri environment.
-
-This upgrade command eases the transition by writing an initial .jiri_manifest
-file for you. If you have an existing .local_manifest file, its contents will
-be incorporated into the new .jiri_manifest file, and it will be renamed to
-.local_manifest.BACKUP. The -revert flag deletes the .jiri_manifest file, and
-restores the .local_manifest file.
-`,
- ArgsName: "<kind>",
- ArgsLong: `
-<kind> specifies the kind of upgrade, one of "v23" or "fuchsia".
-`,
-}
-
-func runUpgrade(jirix *jiri.X, args []string) error {
- localFile := filepath.Join(jirix.Root, ".local_manifest")
- backupFile := localFile + ".BACKUP"
- if flagUpgradeRevert {
- // Restore .local_manifest.BACKUP if it exists.
- switch _, err := jirix.NewSeq().Stat(backupFile); {
- case err != nil && !runutil.IsNotExist(err):
- return err
- case err == nil:
- if err := jirix.NewSeq().Rename(backupFile, localFile).Done(); err != nil {
- return fmt.Errorf("couldn't restore %v to %v: %v", backupFile, localFile, err)
- }
- }
- // Deleting the .jiri_manifest file reverts to the old behavior.
- return jirix.NewSeq().Remove(jirix.JiriManifestFile()).Done()
- }
- if len(args) != 1 {
- return jirix.UsageErrorf("must specify upgrade kind")
- }
- kind := args[0]
- var argRemote, argName, argManifest string
- switch kind {
- case "v23":
- argRemote = "https://vanadium.googlesource.com/manifest"
- argName, argManifest = "manifest", "public"
- case "fuchsia":
- argRemote = "https://fuchsia.googlesource.com/fnl-start"
- argName, argManifest = "fnl-start", "manifest/fuchsia"
- default:
- return jirix.UsageErrorf("unknown upgrade kind %q", kind)
- }
- // Initialize manifest from .local_manifest.
- hasLocalFile := true
- manifest, err := project.ManifestFromFile(jirix, localFile)
- if err != nil {
- if !runutil.IsNotExist(err) {
- return err
- }
- hasLocalFile = false
- manifest = &project.Manifest{}
- }
- oldImports := manifest.Imports
- manifest.Imports = nil
- for _, oldImport := range oldImports {
- if oldImport.Remote != "" {
- // This is a new-style remote import, carry it over directly.
- manifest.Imports = append(manifest.Imports, oldImport)
- continue
- }
- // This is an old-style import, convert it to the new style.
- oldName := oldImport.Name
- switch {
- case kind == "v23" && oldName == "default":
- oldName = "public"
- case kind == "fuchsia" && oldName == "default":
- oldName = "manifest/fuchsia"
- }
- manifest.Imports = append(manifest.Imports, project.Import{
- Manifest: oldName,
- Name: argName,
- Remote: argRemote,
- })
- }
- if len(manifest.Imports) == 0 {
- manifest.Imports = append(manifest.Imports, project.Import{
- Manifest: argManifest,
- Name: argName,
- Remote: argRemote,
- })
- }
- // Write output to .jiri_manifest file.
- outFile := jirix.JiriManifestFile()
- if _, err := os.Stat(outFile); err == nil {
- return fmt.Errorf("%v already exists", outFile)
- }
- if err := manifest.ToFile(jirix, outFile); err != nil {
- return err
- }
- // Backup .local_manifest file, if it exists.
- if hasLocalFile {
- if err := jirix.NewSeq().Rename(localFile, backupFile).Done(); err != nil {
- return fmt.Errorf("couldn't backup %v to %v: %v", localFile, backupFile, err)
- }
- }
- return nil
-}
diff --git a/cmd/jiri/upgrade_test.go b/cmd/jiri/upgrade_test.go
deleted file mode 100644
index 16f4f72..0000000
--- a/cmd/jiri/upgrade_test.go
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "strings"
- "testing"
-
- "v.io/jiri"
- "v.io/x/lib/gosh"
-)
-
-type upgradeTestCase struct {
- Args []string
- Exist bool
- Local, Want string
- Stderr string
-}
-
-func TestUpgrade(t *testing.T) {
- tests := []upgradeTestCase{
- {
- Stderr: `must specify upgrade kind`,
- },
- {
- Args: []string{"foo"},
- Stderr: `unknown upgrade kind "foo"`,
- },
- // Test v23 upgrades.
- {
- Args: []string{"v23"},
- Exist: true,
- Stderr: `.jiri_manifest already exists`,
- },
- {
- Args: []string{"v23"},
- Want: `<manifest>
- <imports>
- <import manifest="public" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"v23"},
- Local: `<manifest>
- <imports>
- <import name="default"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="public" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"v23"},
- Local: `<manifest>
- <imports>
- <import name="private"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="private" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"v23"},
- Local: `<manifest>
- <imports>
- <import name="private"/>
- <import name="infrastructure"/>
- <import name="default"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="private" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- <import manifest="infrastructure" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- <import manifest="public" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"v23"},
- Local: `<manifest>
- <imports>
- <import name="default"/>
- <import name="infrastructure"/>
- <import name="private"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="public" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- <import manifest="infrastructure" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- <import manifest="private" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`,
- },
- // Test fuchsia upgrades.
- {
- Args: []string{"fuchsia"},
- Exist: true,
- Stderr: `.jiri_manifest already exists`,
- },
- {
- Args: []string{"fuchsia"},
- Want: `<manifest>
- <imports>
- <import manifest="manifest/fuchsia" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"fuchsia"},
- Local: `<manifest>
- <imports>
- <import name="default"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="manifest/fuchsia" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"fuchsia"},
- Local: `<manifest>
- <imports>
- <import name="private"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="private" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"fuchsia"},
- Local: `<manifest>
- <imports>
- <import name="private"/>
- <import name="infrastructure"/>
- <import name="default"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="private" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- <import manifest="infrastructure" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- <import manifest="manifest/fuchsia" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- </imports>
-</manifest>
-`,
- },
- {
- Args: []string{"fuchsia"},
- Local: `<manifest>
- <imports>
- <import name="default"/>
- <import name="infrastructure"/>
- <import name="private"/>
- </imports>
-</manifest>
-`,
- Want: `<manifest>
- <imports>
- <import manifest="manifest/fuchsia" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- <import manifest="infrastructure" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- <import manifest="private" name="fnl-start" remote="https://fuchsia.googlesource.com/fnl-start"/>
- </imports>
-</manifest>
-`,
- },
- }
- sh := gosh.NewShell(t)
- defer sh.Cleanup()
- jiriTool := gosh.BuildGoPkg(sh, sh.MakeTempDir(), "v.io/jiri/cmd/jiri")
- for _, test := range tests {
- if err := testUpgrade(t, jiriTool, test); err != nil {
- t.Errorf("%v: %v", test.Args, err)
- }
- }
-}
-
-func testUpgrade(t *testing.T, jiriTool string, test upgradeTestCase) error {
- sh := gosh.NewShell(t)
- sh.PropagateChildOutput = true
- defer sh.Cleanup()
- jiriRoot := sh.MakeTempDir()
- sh.Pushd(jiriRoot)
- // Set up an existing file or local_manifest, if they were specified
- if test.Exist {
- if err := ioutil.WriteFile(".jiri_manifest", []byte("<manifest/>"), 0644); err != nil {
- return err
- }
- }
- if test.Local != "" {
- if err := ioutil.WriteFile(".local_manifest", []byte(test.Local), 0644); err != nil {
- return err
- }
- }
- // Run upgrade and check the error.
- sh.Vars[jiri.RootEnv] = jiriRoot
- cmd := sh.Cmd(jiriTool, append([]string{"upgrade"}, test.Args...)...)
- if test.Stderr != "" {
- cmd.ExitErrorIsOk = true
- }
- _, stderr := cmd.StdoutStderr()
- if got, want := stderr, test.Stderr; !strings.Contains(got, want) || (got != "" && want == "") {
- return fmt.Errorf("stderr got %q, want substr %q", got, want)
- }
- // Make sure the right file is generated.
- if test.Want != "" {
- data, err := ioutil.ReadFile(".jiri_manifest")
- if err != nil {
- return err
- }
- if got, want := string(data), test.Want; got != want {
- return fmt.Errorf("GOT\n%s\nWANT\n%s", got, want)
- }
- }
- // Make sure the .local_manifest file is backed up.
- if test.Local != "" && test.Stderr == "" {
- data, err := ioutil.ReadFile(".local_manifest.BACKUP")
- if err != nil {
- return fmt.Errorf("local manifest backup got error: %v", err)
- }
- if got, want := string(data), test.Local; got != want {
- return fmt.Errorf("local manifest backup GOT\n%s\nWANT\n%s", got, want)
- }
- }
- return nil
-}
-
-func TestUpgradeRevert(t *testing.T) {
- sh := gosh.NewShell(t)
- defer sh.Cleanup()
- jiriRoot := sh.MakeTempDir()
- sh.Pushd(jiriRoot)
- jiriTool := gosh.BuildGoPkg(sh, sh.MakeTempDir(), "v.io/jiri/cmd/jiri")
- localData := `<manifest/>`
- jiriData := `<manifest>
- <imports>
- <import manifest="public" name="manifest" remote="https://vanadium.googlesource.com/manifest"/>
- </imports>
-</manifest>
-`
- // Set up an existing local_manifest.
- if err := ioutil.WriteFile(".local_manifest", []byte(localData), 0644); err != nil {
- t.Errorf("couldn't write local manifest: %v", err)
- }
- // Run a regular upgrade first, and make sure files are as expected.
- sh.Vars[jiri.RootEnv] = jiriRoot
- sh.Cmd(jiriTool, "upgrade", "v23").Run()
- gotJiri, err := ioutil.ReadFile(".jiri_manifest")
- if err != nil {
- t.Errorf("couldn't read jiri manifest: %v", err)
- }
- if got, want := string(gotJiri), jiriData; got != want {
- t.Errorf("jiri manifest GOT\n%s\nWANT\n%s", got, want)
- }
- gotBackup, err := ioutil.ReadFile(".local_manifest.BACKUP")
- if err != nil {
- t.Errorf("couldn't read local manifest backup: %v", err)
- }
- if got, want := string(gotBackup), localData; got != want {
- t.Errorf("local manifest backup GOT\n%s\nWANT\n%s", got, want)
- }
- // Now run a revert, and make sure files are as expected.
- sh.Cmd(jiriTool, "upgrade", "-revert").Run()
- if _, err := os.Stat(".jiri_manifest"); !os.IsNotExist(err) {
- t.Errorf(".jiri_manifest still exists after revert: %v", err)
- }
- if _, err := os.Stat(".local_manifest.BACKUP"); !os.IsNotExist(err) {
- t.Errorf(".local_manifest.BACKUP still exists after revert: %v", err)
- }
- gotLocal, err := ioutil.ReadFile(".local_manifest")
- if err != nil {
- t.Errorf("couldn't read local manifest: %v", err)
- }
- if got, want := string(gotLocal), localData; got != want {
- t.Errorf("local manifest GOT\n%s\nWANT\n%s", got, want)
- }
-}
diff --git a/jiritest/.api b/jiritest/.api
index 5ba67b4..48b6fe4 100644
--- a/jiritest/.api
+++ b/jiritest/.api
@@ -5,10 +5,10 @@
pkg jiritest, method (FakeJiriRoot) CreateRemoteProject(string) error
pkg jiritest, method (FakeJiriRoot) DisableRemoteManifestPush() error
pkg jiritest, method (FakeJiriRoot) EnableRemoteManifestPush() error
-pkg jiritest, method (FakeJiriRoot) ReadLocalManifest() (*project.Manifest, error)
+pkg jiritest, method (FakeJiriRoot) ReadJiriManifest() (*project.Manifest, error)
pkg jiritest, method (FakeJiriRoot) ReadRemoteManifest() (*project.Manifest, error)
pkg jiritest, method (FakeJiriRoot) UpdateUniverse(bool) error
-pkg jiritest, method (FakeJiriRoot) WriteLocalManifest(*project.Manifest) error
+pkg jiritest, method (FakeJiriRoot) WriteJiriManifest(*project.Manifest) error
pkg jiritest, method (FakeJiriRoot) WriteRemoteManifest(*project.Manifest) error
pkg jiritest, type FakeJiriRoot struct
pkg jiritest, type FakeJiriRoot struct, Projects map[string]string
diff --git a/jiritest/fake.go b/jiritest/fake.go
index 155fc74..f0aa2e5 100644
--- a/jiritest/fake.go
+++ b/jiritest/fake.go
@@ -24,11 +24,10 @@
}
const (
- defaultDataDir = "data"
- defaultManifest = "default"
- manifestProject = ".manifest"
- manifestVersion = "v2"
- toolsProject = "tools"
+ defaultDataDir = "data"
+ manifestFileName = "public"
+ manifestProjectName = "manifest"
+ manifestProjectPath = "manifest"
)
// NewFakeJiriRoot returns a new FakeJiriRoot and a cleanup closure. The
@@ -48,40 +47,34 @@
t.Fatalf("TempDir() failed: %v", err)
}
fake.remote = remoteDir
- if err := fake.CreateRemoteProject(manifestProject); err != nil {
+ if err := fake.CreateRemoteProject(manifestProjectPath); err != nil {
t.Fatal(err)
}
- if err := fake.CreateRemoteProject(toolsProject); err != nil {
- t.Fatal(err)
- }
-
// Create a fake manifest.
- manifestDir := filepath.Join(remoteDir, manifestProject, manifestVersion)
+ manifestDir := filepath.Join(remoteDir, manifestProjectPath)
if err := s.MkdirAll(manifestDir, os.FileMode(0700)).Done(); err != nil {
t.Fatal(err)
}
if err := fake.WriteRemoteManifest(&project.Manifest{}); err != nil {
t.Fatal(err)
}
- if err := gitutil.New(jirix.NewSeq()).CloneRecursive(fake.Projects[manifestProject], filepath.Join(jirix.Root, manifestProject)); err != nil {
- t.Fatal(err)
- }
-
- // Add the "tools" project and a fake "jiri" tool to the
- // manifests. This is necessary to make sure that the commonly
- // invoked DataDirPath() function, which uses the "jiri" tool
- // configuration for its default, works.
+ // Add the "manifest" project to the manifest.
if err := fake.AddProject(project.Project{
- Name: toolsProject,
- Path: toolsProject,
- Remote: fake.Projects[toolsProject],
+ Name: manifestProjectName,
+ Path: manifestProjectPath,
+ Remote: fake.Projects[manifestProjectName],
}); err != nil {
t.Fatal(err)
}
- if err := fake.AddTool(project.Tool{
- Name: "jiri",
- Data: defaultDataDir,
- Project: toolsProject,
+ // Create a .jiri_manifest file which imports the manifest created above.
+ if err := fake.WriteJiriManifest(&project.Manifest{
+ Imports: []project.Import{
+ project.Import{
+ Manifest: manifestFileName,
+ Name: manifestProjectName,
+ Remote: filepath.Join(fake.remote, manifestProjectPath),
+ },
+ },
}); err != nil {
t.Fatal(err)
}
@@ -140,7 +133,7 @@
// DisableRemoteManifestPush disables pushes to the remote manifest
// repository.
func (fake FakeJiriRoot) DisableRemoteManifestPush() error {
- dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProject))
+ dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath))
if err := gitutil.New(fake.X.NewSeq(), dir).CheckoutBranch("master"); err != nil {
return err
}
@@ -150,7 +143,7 @@
// EnableRemoteManifestPush enables pushes to the remote manifest
// repository.
func (fake FakeJiriRoot) EnableRemoteManifestPush() error {
- dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProject))
+ dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath))
if !gitutil.New(fake.X.NewSeq(), dir).BranchExists("non-master") {
if err := gitutil.New(fake.X.NewSeq(), dir).CreateBranch("non-master"); err != nil {
return err
@@ -178,23 +171,9 @@
return nil
}
-func getManifest(jirix *jiri.X) string {
- manifest := jirix.Manifest()
- if manifest != "" {
- return manifest
- }
- return defaultManifest
-}
-
-// ReadLocalManifest read a manifest from the local manifest project.
-func (fake FakeJiriRoot) ReadLocalManifest() (*project.Manifest, error) {
- path := filepath.Join(fake.X.Root, manifestProject, manifestVersion, getManifest(fake.X))
- return project.ManifestFromFile(fake.X, path)
-}
-
// ReadRemoteManifest read a manifest from the remote manifest project.
func (fake FakeJiriRoot) ReadRemoteManifest() (*project.Manifest, error) {
- path := filepath.Join(fake.remote, manifestProject, manifestVersion, getManifest(fake.X))
+ path := filepath.Join(fake.remote, manifestProjectPath, manifestFileName)
return project.ManifestFromFile(fake.X, path)
}
@@ -212,30 +191,33 @@
return nil
}
-// WriteLocalManifest writes the given manifest to the local
-// manifest project.
-func (fake FakeJiriRoot) WriteLocalManifest(manifest *project.Manifest) error {
- dir := filepath.Join(fake.X.Root, manifestProject)
- path := filepath.Join(dir, manifestVersion, getManifest(fake.X))
- return fake.writeManifest(manifest, dir, path)
+// ReadJiriManifest reads the .jiri_manifest manifest.
+func (fake FakeJiriRoot) ReadJiriManifest() (*project.Manifest, error) {
+ return project.ManifestFromFile(fake.X, fake.X.JiriManifestFile())
+}
+
+// WriteJiriManifest writes the given manifest to the .jiri_manifest file.
+func (fake FakeJiriRoot) WriteJiriManifest(manifest *project.Manifest) error {
+ return manifest.ToFile(fake.X, fake.X.JiriManifestFile())
}
// WriteRemoteManifest writes the given manifest to the remote
// manifest project.
func (fake FakeJiriRoot) WriteRemoteManifest(manifest *project.Manifest) error {
- dir := filepath.Join(fake.remote, manifestProject)
- path := filepath.Join(dir, manifestVersion, getManifest(fake.X))
+ dir := filepath.Join(fake.remote, manifestProjectPath)
+ path := filepath.Join(dir, manifestFileName)
return fake.writeManifest(manifest, dir, path)
}
func (fake FakeJiriRoot) writeManifest(manifest *project.Manifest, dir, path string) error {
+ git := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir))
if err := manifest.ToFile(fake.X, path); err != nil {
return err
}
- if err := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir)).Add(path); err != nil {
+ if err := git.Add(path); err != nil {
return err
}
- if err := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir)).Commit(); err != nil {
+ if err := git.Commit(); err != nil {
return err
}
return nil
diff --git a/project/project.go b/project/project.go
index 18c8cd1..5bc5c0a 100644
--- a/project/project.go
+++ b/project/project.go
@@ -220,13 +220,6 @@
Manifest string `xml:"manifest,attr,omitempty"`
// Name is the name of the remote manifest project, used to determine the
// project key.
- //
- // If Remote and Manifest are empty, it is the old-style name of the manifest
- // to import, similar to localimport. This is deprecated behavior, and will be
- // removed.
- //
- // TODO(toddw): Remove the old behavior when the transition to new-style
- // manifests is complete.
Name string `xml:"name,attr,omitempty"`
// Protocol is the version control protocol used by the remote manifest
// project. If not set, "git" is used as the default.
@@ -243,47 +236,28 @@
}
func (i *Import) fillDefaults() error {
- if i.Remote != "" {
- if i.Protocol == "" {
- i.Protocol = "git"
- }
- if i.RemoteBranch == "" {
- i.RemoteBranch = "master"
- }
+ if i.Protocol == "" {
+ i.Protocol = "git"
+ }
+ if i.RemoteBranch == "" {
+ i.RemoteBranch = "master"
}
return i.validate()
}
func (i *Import) unfillDefaults() error {
- if i.Remote != "" {
- if i.Protocol == "git" {
- i.Protocol = ""
- }
- if i.RemoteBranch == "master" {
- i.RemoteBranch = ""
- }
+ if i.Protocol == "git" {
+ i.Protocol = ""
+ }
+ if i.RemoteBranch == "master" {
+ i.RemoteBranch = ""
}
return i.validate()
}
func (i *Import) validate() error {
- // After our transition is done, the "import" element will always denote
- // remote imports, and the "remote" and "manifest" attributes will be
- // required. During the transition we allow old-style local imports, which
- // only set the "name" attribute.
- //
- // This is a bit tricky, since the "name" attribute is allowed in both old and
- // new styles, but have different semantics. We distinguish between old and
- // new styles based on the existence of the "remote" attribute.
- oldStyle := *i
- oldStyle.Name = ""
- switch {
- case i.Name != "" && oldStyle == Import{}:
- // Only "name" is set, this is the old-style.
- case i.Remote != "" && i.Manifest != "":
- // At least "remote" and "manifest" are set, this is the new-style.
- default:
- return fmt.Errorf("bad import: neither old style (only name is set) or new style (at least remote and manifest are set): %+v", *i)
+ if i.Manifest == "" || i.Remote == "" {
+ return fmt.Errorf("bad import: both manifest and remote must be specified")
}
return nil
}
@@ -396,13 +370,6 @@
XMLName struct{} `xml:"project"`
}
-var (
- startUpperProjectBytes = []byte("<Project")
- startLowerProjectBytes = []byte("<project")
- endUpperProjectBytes = []byte("</Project>")
- endLowerProjectBytes = []byte("</project>")
-)
-
// ProjectFromFile returns a project parsed from the contents of filename,
// with defaults filled in and all paths absolute.
func ProjectFromFile(jirix *jiri.X, filename string) (*Project, error) {
@@ -411,16 +378,6 @@
return nil, err
}
- // Previous versions of the jiri tool had a bug where the project start and
- // end elements were in upper-case, since the XMLName field was missing. That
- // bug is now fixed, but the xml.Unmarshal call is case-sensitive, and will
- // fail if it sees the upper-case version. This hack rewrites the elements to
- // the lower-case version.
- //
- // TODO(toddw): Remove when the transition to new manifests is complete.
- data = bytes.Replace(data, startUpperProjectBytes, startLowerProjectBytes, -1)
- data = bytes.Replace(data, endUpperProjectBytes, endLowerProjectBytes, -1)
-
p := new(Project)
if err := xml.Unmarshal(data, p); err != nil {
return nil, err
@@ -684,17 +641,11 @@
}
// Add all tools from the current manifest to the snapshot manifest.
- var tools Tools
- if jirix.UsingOldManifests() {
- // TODO(nlacasse): Remove this logic when the transition to new manifests is done.
- _, tools, err = LoadManifest(jirix)
- } else {
- // We can't just call LoadManifest here, since that determines the
- // local projects using FastScan, but if we're calling CreateSnapshot
- // during "jiri update" and we added some new projects, they won't be
- // found anymore.
- _, tools, err = loadManifestFile(jirix, jirix.JiriManifestFile(), localProjects)
- }
+ // We can't just call LoadManifest here, since that determines the
+ // local projects using FastScan, but if we're calling CreateSnapshot
+ // during "jiri update" and we added some new projects, they won't be
+ // found anymore.
+ _, tools, err := loadManifestFile(jirix, jirix.JiriManifestFile(), localProjects)
if err != nil {
return err
}
@@ -921,10 +872,6 @@
// resolving remote and local imports. Returns the projects and tools specified
// by the manifest.
//
-// If the user is still using old-style manifests, it uses the old
-// ResolveManifestPath logic to determine the initial manifest file, since the
-// .jiri_manifest doesn't exist.
-//
// WARNING: LoadManifest cannot be run multiple times in parallel! It invokes
// git operations which require a lock on the filesystem. If you see errors
// about ".git/index.lock exists", you are likely calling LoadManifest in
@@ -932,18 +879,8 @@
func LoadManifest(jirix *jiri.X) (Projects, Tools, error) {
jirix.TimerPush("load manifest")
defer jirix.TimerPop()
- var (
- file string
- localProjects Projects
- err error
- )
- // TODO(toddw): Remove old manifest logic when the transition is complete.
- if jirix.UsingOldManifests() {
- file, err = jirix.ResolveManifestPath(jirix.Manifest())
- } else {
- file = jirix.JiriManifestFile()
- localProjects, err = LocalProjects(jirix, FastScan)
- }
+ file := jirix.JiriManifestFile()
+ localProjects, err := LocalProjects(jirix, FastScan)
if err != nil {
return nil, nil, err
}
@@ -983,10 +920,6 @@
func loadUpdatedManifest(jirix *jiri.X, localProjects Projects) (Projects, Tools, string, error) {
jirix.TimerPush("load updated manifest")
defer jirix.TimerPop()
- if jirix.UsingOldManifests() {
- projects, tools, err := loadUpdatedManifestDeprecated(jirix)
- return projects, tools, "", err
- }
ld := newManifestLoader(localProjects, true)
if err := ld.Load(jirix, "", jirix.JiriManifestFile(), ""); err != nil {
return nil, nil, ld.TmpDir, err
@@ -994,30 +927,6 @@
return ld.Projects, ld.Tools, ld.TmpDir, nil
}
-// TODO(toddw): Remove this logic when the transition to new manifests is done.
-func loadUpdatedManifestDeprecated(jirix *jiri.X) (Projects, Tools, error) {
- manifestPath := filepath.Join(jirix.Root, ".manifest")
- manifestRemote, err := getManifestRemote(jirix, manifestPath)
- if err != nil {
- return nil, nil, err
- }
- project := Project{
- Path: manifestPath,
- Remote: manifestRemote,
- }
- if err := project.fillDefaults(); err != nil {
- return nil, nil, err
- }
- if err := syncProjectMaster(jirix, project); err != nil {
- return nil, nil, err
- }
- file, err := jirix.ResolveManifestPath(jirix.Manifest())
- if err != nil {
- return nil, nil, err
- }
- return loadManifestFile(jirix, file, nil)
-}
-
// UpdateUniverse updates all local projects and tools to match the remote
// counterparts identified in the manifest. Optionally, the 'gc' flag can be
// used to indicate that local projects that no longer exist remotely should be
@@ -1638,10 +1547,6 @@
}
// Process remote imports.
for _, remote := range m.Imports {
- if remote.Remote == "" {
- // Old-style named imports handled in loop below.
- continue
- }
nextRoot := filepath.Join(root, remote.Root)
key := remote.ProjectKey()
p, ok := ld.localProjects[key]
@@ -1668,9 +1573,9 @@
}
ld.localProjects[key] = p
}
- // Reset the project to its specified branch and load the next file.
- // Note that we call load() recursively, so multiple files may be
- // loaded by resetAndLoad.
+ // Reset the project to its specified branch and load the next file. Note
+ // that we call load() recursively, so multiple files may be loaded by
+ // resetAndLoad.
p.Revision = "HEAD"
p.RemoteBranch = remote.RemoteBranch
nextFile := filepath.Join(p.Path, remote.Manifest)
@@ -1678,22 +1583,6 @@
return err
}
}
- // Process old-style named imports.
- //
- // TODO(toddw): Remove this logic when the manifest transition is done.
- for _, named := range m.Imports {
- if named.Remote != "" {
- // New-style remote imports handled in loop above.
- continue
- }
- nextFile, err := jirix.ResolveManifestPath(named.Name)
- if err != nil {
- return err
- }
- if err := ld.Load(jirix, root, nextFile, ""); err != nil {
- return err
- }
- }
// Process local imports.
for _, local := range m.LocalImports {
// TODO(toddw): Add our invariant check that the file is in the same
diff --git a/project/project_test.go b/project/project_test.go
index fb12f3e..d8b44f1 100644
--- a/project/project_test.go
+++ b/project/project_test.go
@@ -19,43 +19,28 @@
"v.io/jiri/gitutil"
"v.io/jiri/jiritest"
"v.io/jiri/project"
- "v.io/jiri/runutil"
)
-func addRemote(t *testing.T, jirix *jiri.X, localProject, name, remoteProject string) {
- cwd, err := os.Getwd()
- if err != nil {
+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)
}
- defer jirix.NewSeq().Chdir(cwd)
- if err := jirix.NewSeq().Chdir(localProject).Done(); err != nil {
- t.Fatalf("%v", err)
- }
- if err := gitutil.New(jirix.NewSeq()).AddRemote(name, remoteProject); err != nil {
- t.Fatalf("%v", err)
- }
-}
-
-func checkReadme(t *testing.T, jirix *jiri.X, project, message string) {
- if _, err := jirix.NewSeq().Stat(project); err != nil {
- t.Fatalf("%v", err)
- }
- readmeFile := filepath.Join(project, "README")
+ 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 %v:\ngot\n%s\nwant\n%s\n", project, got, want)
+ t.Fatalf("unexpected content in project %v:\ngot\n%s\nwant\n%s\n", p.Name, got, want)
}
}
// Checks that /.jiri/ is ignored in a local project checkout
-func checkGitIgnore(t *testing.T, jirix *jiri.X, project string) {
- if _, err := jirix.NewSeq().Stat(project); err != nil {
+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(project, ".git", "info", "exclude")
+ gitInfoExcludeFile := filepath.Join(p.Path, ".git", "info", "exclude")
data, err := ioutil.ReadFile(gitInfoExcludeFile)
if err != nil {
t.Fatalf("ReadFile(%v) failed: %v", gitInfoExcludeFile, err)
@@ -66,30 +51,6 @@
}
}
-func createLocalManifestCopy(t *testing.T, jirix *jiri.X, dir, manifestDir string) {
- // Load the remote manifest.
- m, err := project.ManifestFromFile(jirix, filepath.Join(manifestDir, "v2", "default"))
- if err != nil {
- t.Fatal(err)
- }
- // Store the manifest locally.
- if err := m.ToFile(jirix, filepath.Join(dir, ".local_manifest")); err != nil {
- t.Fatal(err)
- }
-}
-
-func createLocalManifestStub(t *testing.T, jirix *jiri.X, dir string) {
- // Create a manifest stub.
- manifest := project.Manifest{}
- imp := project.Import{}
- imp.Name = "default"
- manifest.Imports = append(manifest.Imports, imp)
- // Store the manifest locally.
- if err := manifest.ToFile(jirix, filepath.Join(dir, ".local_manifest")); err != nil {
- t.Fatal(err)
- }
-}
-
func commitFile(t *testing.T, jirix *jiri.X, dir, file, msg string) {
cwd, err := os.Getwd()
if err != nil {
@@ -104,126 +65,8 @@
}
}
-func createRemoteManifest(t *testing.T, jirix *jiri.X, dir string, remotes []string) {
- manifestDir, perm := filepath.Join(dir, "v2"), os.FileMode(0755)
- if err := jirix.NewSeq().MkdirAll(manifestDir, perm).Done(); err != nil {
- t.Fatalf("%v", err)
- }
- manifest := project.Manifest{}
- for i, remote := range remotes {
- project := project.Project{
- Name: remote,
- Path: localProjectName(i),
- Protocol: "git",
- Remote: remote,
- }
- manifest.Projects = append(manifest.Projects, project)
- }
- commitManifest(t, jirix, &manifest, dir)
-}
-
-func commitManifest(t *testing.T, jirix *jiri.X, manifest *project.Manifest, manifestDir string) {
- manifestFile := filepath.Join(manifestDir, "v2", "default")
- if err := manifest.ToFile(jirix, manifestFile); err != nil {
- t.Fatal(err)
- }
- commitFile(t, jirix, manifestDir, manifestFile, "creating manifest")
-}
-
-func createProject(t *testing.T, jirix *jiri.X, manifestDir, name, remote, path string) {
- m, err := project.ManifestFromFile(jirix, filepath.Join(manifestDir, "v2", "default"))
- if err != nil {
- t.Fatal(err)
- }
- m.Projects = append(m.Projects, project.Project{Name: name, Remote: remote, Path: path})
- commitManifest(t, jirix, m, manifestDir)
-}
-
-func deleteProject(t *testing.T, jirix *jiri.X, manifestDir, remote string) {
- m, err := project.ManifestFromFile(jirix, filepath.Join(manifestDir, "v2", "default"))
- if err != nil {
- t.Fatal(err)
- }
- deleteKey := project.MakeProjectKey(remote, remote)
- var projects []project.Project
- for _, p := range m.Projects {
- if p.Key() != deleteKey {
- projects = append(projects, p)
- }
- }
- m.Projects = projects
- commitManifest(t, jirix, m, manifestDir)
-}
-
-// Identify the current revision for a given project.
-func currentRevision(t *testing.T, jirix *jiri.X, name string) string {
- cwd, err := os.Getwd()
- if err != nil {
- t.Fatalf("%v", err)
- }
- defer jirix.NewSeq().Chdir(cwd)
- if err := jirix.NewSeq().Chdir(name).Done(); err != nil {
- t.Fatalf("%v", err)
- }
- revision, err := gitutil.New(jirix.NewSeq()).CurrentRevision()
- if err != nil {
- t.Fatalf("%v", err)
- }
- return revision
-}
-
-// Fix the revision in the manifest file.
-func setRevisionForProject(t *testing.T, jirix *jiri.X, manifestDir, name, revision string) {
- m, err := project.ManifestFromFile(jirix, filepath.Join(manifestDir, "v2", "default"))
- if err != nil {
- t.Fatal(err)
- }
- updated := false
- for i, p := range m.Projects {
- if p.Name == name {
- p.Revision = revision
- m.Projects[i] = p
- updated = true
- break
- }
- }
- if !updated {
- t.Fatalf("failed to fix revision for project %v", name)
- }
- commitManifest(t, jirix, m, manifestDir)
-}
-
-func holdProjectBack(t *testing.T, jirix *jiri.X, manifestDir, name string) {
- revision := currentRevision(t, jirix, name)
- setRevisionForProject(t, jirix, manifestDir, name, revision)
-}
-
-func localProjectName(i int) string {
- return "test-local-project-" + fmt.Sprintf("%d", i)
-}
-
-func moveProject(t *testing.T, jirix *jiri.X, manifestDir, name, dst string) {
- m, err := project.ManifestFromFile(jirix, filepath.Join(manifestDir, "v2", "default"))
- if err != nil {
- t.Fatal(err)
- }
- updated := false
- for i, p := range m.Projects {
- if p.Name == name {
- p.Path = dst
- m.Projects[i] = p
- updated = true
- break
- }
- }
- if !updated {
- t.Fatalf("failed to set path for project %v", name)
- }
- commitManifest(t, jirix, m, manifestDir)
-}
-
-func remoteProjectName(i int) string {
- return "test-remote-project-" + fmt.Sprintf("%d", i)
+func projectName(i int) string {
+ return fmt.Sprintf("project-%d", i)
}
func setupNewProject(t *testing.T, jirix *jiri.X, dir, name string, ignore bool) string {
@@ -258,14 +101,6 @@
return projectDir
}
-func writeEmptyMetadata(t *testing.T, jirix *jiri.X, projectDir string) {
- metadataFile := filepath.Join(projectDir, jiri.ProjectMetaDir, jiri.ProjectMetaFile)
- p := project.Project{}
- if err := p.ToFile(jirix, metadataFile); err != nil {
- t.Fatal(err)
- }
-}
-
func writeReadme(t *testing.T, jirix *jiri.X, projectDir, message string) {
path, perm := filepath.Join(projectDir, "README"), os.FileMode(0644)
if err := ioutil.WriteFile(path, []byte(message), perm); err != nil {
@@ -274,34 +109,6 @@
commitFile(t, jirix, projectDir, path, "creating README")
}
-func createAndCheckoutBranch(t *testing.T, jirix *jiri.X, projectDir, branch string) {
- cwd, err := os.Getwd()
- if err != nil {
- t.Fatalf("%v", err)
- }
- defer jirix.NewSeq().Chdir(cwd)
- if err := jirix.NewSeq().Chdir(projectDir).Done(); err != nil {
- t.Fatalf("%v", err)
- }
- if err := gitutil.New(jirix.NewSeq()).CreateAndCheckoutBranch(branch); err != nil {
- t.Fatalf("%v", err)
- }
-}
-
-func resetToOriginMaster(t *testing.T, jirix *jiri.X, projectDir string) {
- cwd, err := os.Getwd()
- if err != nil {
- t.Fatalf("%v", err)
- }
- defer jirix.NewSeq().Chdir(cwd)
- if err := jirix.NewSeq().Chdir(projectDir).Done(); err != nil {
- t.Fatalf("%v", err)
- }
- if err := gitutil.New(jirix.NewSeq()).Reset("origin/master"); err != nil {
- t.Fatalf("%v", err)
- }
-}
-
func checkProjectsMatchPaths(t *testing.T, gotProjects project.Projects, wantProjectPaths []string) {
gotProjectPaths := []string{}
for _, p := range gotProjects {
@@ -323,7 +130,7 @@
// Create some projects.
numProjects, projectPaths := 3, []string{}
for i := 0; i < numProjects; i++ {
- name := localProjectName(i)
+ name := projectName(i)
path := setupNewProject(t, jirix, jirix.Root, name, true)
p := project.Project{
Path: path,
@@ -341,7 +148,7 @@
Projects: []project.Project{
{
Name: projectPaths[0],
- Path: localProjectName(0),
+ Path: projectName(0),
Protocol: "git",
Remote: projectPaths[0],
},
@@ -381,196 +188,300 @@
checkProjectsMatchPaths(t, foundProjects, projectPaths[1:])
}
-// TestUpdateUniverse is a comprehensive test of the "jiri update"
-// logic that handles projects.
-//
-// TODO(jsimsa): Add tests for the logic that updates tools.
-func TestUpdateUniverse(t *testing.T) {
- // Setup an instance of jiri universe, creating the remote repositories for
- // the manifest and projects under the ".remote" directory, which is ignored
- // from the consideration of LocalProjects().
- jirix, cleanup := jiritest.NewX(t)
- defer cleanup()
+// setupUniverse creates a fake jiri root with 3 remote projects. Each project
+// has a README with text "initial readme".
+func setupUniverse(t *testing.T) ([]project.Project, *jiritest.FakeJiriRoot, func()) {
+ fake, cleanup := jiritest.NewFakeJiriRoot(t)
+ success := false
+ defer func() {
+ if !success {
+ cleanup()
+ }
+ }()
- localDir := jirix.Root
- remoteDir := filepath.Join(jirix.Root, ".remote")
-
- localManifest := setupNewProject(t, jirix, localDir, ".manifest", false)
- writeEmptyMetadata(t, jirix, localManifest)
- remoteManifest := setupNewProject(t, jirix, remoteDir, "test-remote-manifest", false)
- addRemote(t, jirix, localManifest, "origin", remoteManifest)
- numProjects, remoteProjects := 6, []string{}
+ // Create some projects and add them to the remote manifest.
+ numProjects := 3
+ localProjects := []project.Project{}
for i := 0; i < numProjects; i++ {
- remoteProject := setupNewProject(t, jirix, remoteDir, remoteProjectName(i), true)
- remoteProjects = append(remoteProjects, remoteProject)
- }
- createRemoteManifest(t, jirix, remoteManifest, remoteProjects)
-
- // Check that calling UpdateUniverse() creates local copies of
- // the remote repositories, advancing projects to HEAD or to
- // the fixed revision set in the manifest.
- for _, remoteProject := range remoteProjects {
- writeReadme(t, jirix, remoteProject, "revision 1")
- }
- holdProjectBack(t, jirix, remoteManifest, remoteProjects[0])
- for _, remoteProject := range remoteProjects {
- writeReadme(t, jirix, remoteProject, "revision 2")
- }
- if err := project.UpdateUniverse(jirix, false); err != nil {
- t.Fatalf("%v", err)
- }
- checkCreateFn := func(i int, revision string) {
- localProject := filepath.Join(localDir, localProjectName(i))
- checkGitIgnore(t, jirix, localProject)
- if i == 0 {
- checkReadme(t, jirix, localProject, "revision 1")
- } else {
- checkReadme(t, jirix, localProject, revision)
+ name := projectName(i)
+ path := fmt.Sprintf("path-%d", i)
+ if err := fake.CreateRemoteProject(name); err != nil {
+ t.Fatal(err)
+ }
+ p := project.Project{
+ Name: name,
+ Path: filepath.Join(fake.X.Root, path),
+ Remote: fake.Projects[name],
+ }
+ localProjects = append(localProjects, p)
+ if err := fake.AddProject(p); err != nil {
+ t.Fatal(err)
}
}
- for i, _ := range remoteProjects {
- checkCreateFn(i, "revision 2")
+
+ // Create initial commit in each repo.
+ for _, remoteProjectDir := range fake.Projects {
+ writeReadme(t, fake.X, remoteProjectDir, "initial readme")
}
- // Commit more work to the remote repositories and check that
- // calling UpdateUniverse() advances project to HEAD or to the
- // fixed revision set in the manifest.
- holdProjectBack(t, jirix, remoteManifest, remoteProjects[1])
- for _, remoteProject := range remoteProjects {
- writeReadme(t, jirix, remoteProject, "revision 3")
+ success = true
+ return localProjects, fake, cleanup
+}
+
+// TestUpdateUniverseSimple tests that UpdateUniverse will pull remote projects
+// locally, and that jiri metadata is ignored in the repos.
+func TestUpdateUniverseSimple(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ s := fake.X.NewSeq()
+
+ // Check that calling UpdateUniverse() creates local copies of the remote
+ // repositories, and that jiri metadata is ignored by git.
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- if err := project.UpdateUniverse(jirix, false); err != nil {
- t.Fatalf("%v", err)
+ for _, p := range localProjects {
+ if err := s.AssertDirExists(p.Path).Done(); err != nil {
+ t.Fatalf("expected project to exist at path %q but none found", p.Path)
+ }
+ checkReadme(t, fake.X, p, "initial readme")
+ checkMetadataIsIgnored(t, fake.X, p)
}
- checkUpdateFn := func(i int, revision string) {
+}
+
+// TestUpdateUniverseWithRevision checks that UpdateUniverse will pull remote
+// projects at the specified revision.
+func TestUpdateUniverseWithRevision(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ s := fake.X.NewSeq()
+
+ // Set project 1's revision in the manifest to the current revision.
+ git := gitutil.New(s, gitutil.RootDirOpt(fake.Projects[localProjects[1].Name]))
+ rev, err := git.CurrentRevision()
+ if err != nil {
+ t.Fatal(err)
+ }
+ m, err := fake.ReadRemoteManifest()
+ if err != nil {
+ t.Fatal(err)
+ }
+ projects := []project.Project{}
+ for _, p := range m.Projects {
+ if p.Name == localProjects[1].Name {
+ p.Revision = rev
+ }
+ projects = append(projects, p)
+ }
+ m.Projects = projects
+ if err := fake.WriteRemoteManifest(m); err != nil {
+ t.Fatal(err)
+ }
+ // Update README in all projects.
+ for _, remoteProjectDir := range fake.Projects {
+ writeReadme(t, fake.X, remoteProjectDir, "new revision")
+ }
+ // Check that calling UpdateUniverse() updates all projects except for
+ // project 1.
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
+ }
+ for i, p := range localProjects {
if i == 1 {
- checkReadme(t, jirix, filepath.Join(localDir, localProjectName(i)), "revision 2")
+ checkReadme(t, fake.X, p, "initial readme")
} else {
- checkCreateFn(i, revision)
+ checkReadme(t, fake.X, p, "new revision")
}
}
- for i, _ := range remoteProjects {
- checkUpdateFn(i, "revision 3")
+}
+
+// TestUpdateUniverseWithUncommitted checks that uncommitted files are not droped
+// by UpdateUniverse(). This ensures that the "git reset --hard" mechanism used
+// for pointing the master branch to a fixed revision does not lose work in
+// progress.
+func TestUpdateUniverseWithUncommitted(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- // Create an uncommitted file and make sure UpdateUniverse()
- // does not drop it. This ensures that the "git reset --hard"
- // mechanism used for pointing the master branch to a fixed
- // revision does not lose work in progress.
- file, perm, want := filepath.Join(remoteProjects[1], "uncommitted_file"), os.FileMode(0644), []byte("uncommitted work")
+ // Create an uncommitted file in project 1.
+ file, perm, want := filepath.Join(localProjects[1].Path, "uncommitted_file"), os.FileMode(0644), []byte("uncommitted work")
if err := ioutil.WriteFile(file, want, perm); err != nil {
t.Fatalf("WriteFile(%v, %v) failed: %v", file, err, perm)
}
- if err := project.UpdateUniverse(jirix, false); err != nil {
- t.Fatalf("%v", err)
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
got, err := ioutil.ReadFile(file)
if err != nil {
t.Fatalf("%v", err)
}
if bytes.Compare(got, want) != 0 {
- t.Fatalf("unexpected content %v:\ngot\n%s\nwant\n%s\n", remoteProjects[1], got, want)
+ t.Fatalf("unexpected content %v:\ngot\n%s\nwant\n%s\n", localProjects[1], got, want)
+ }
+}
+
+// TestUpdateUniverseMovedProject checks that UpdateUniverse can move a
+// project.
+func TestUpdateUniverseMovedProject(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ s := fake.X.NewSeq()
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- // Update the local path at which a remote project is to be
- // located and check that UpdateUniverse() moves the local
- // copy of the project.
- destination := filepath.Join("test", localProjectName(2))
- moveProject(t, jirix, remoteManifest, remoteProjects[2], destination)
- if err := project.UpdateUniverse(jirix, false); err != nil {
- t.Fatalf("%v", err)
+ // Update the local path at which project 1 is located.
+ m, err := fake.ReadRemoteManifest()
+ if err != nil {
+ t.Fatal(err)
}
- checkMoveFn := func(i int, revision string) {
- if i == 2 {
- checkReadme(t, jirix, filepath.Join(localDir, destination), revision)
- } else {
- checkUpdateFn(i, revision)
+ oldProjectPath := localProjects[1].Path
+ localProjects[1].Path = filepath.Join(fake.X.Root, "new-project-path")
+ projects := []project.Project{}
+ for _, p := range m.Projects {
+ if p.Name == localProjects[1].Name {
+ p.Path = localProjects[1].Path
}
+ projects = append(projects, p)
}
- for i, _ := range remoteProjects {
- checkMoveFn(i, "revision 3")
+ m.Projects = projects
+ if err := fake.WriteRemoteManifest(m); err != nil {
+ t.Fatal(err)
+ }
+ // Check that UpdateUniverse() moves the local copy of the project 1.
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
+ }
+ if err := s.AssertDirExists(oldProjectPath).Done(); err == nil {
+ t.Fatalf("expected project %q at path %q not to exist but it did", localProjects[1].Name, oldProjectPath)
+ }
+ if err := s.AssertDirExists(localProjects[2].Path).Done(); err != nil {
+ t.Fatalf("expected project %q at path %q to exist but it did not", localProjects[1].Name, localProjects[1].Path)
+ }
+ checkReadme(t, fake.X, localProjects[1], "initial readme")
+}
+
+// TestUpdateUniverseDeletedProject checks that UpdateUniverse will delete a
+// project iff gc=true.
+func TestUpdateUniverseDeletedProject(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ s := fake.X.NewSeq()
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- // Delete a remote project and check that UpdateUniverse()
- // deletes the local copy of the project.
- deleteProject(t, jirix, remoteManifest, remoteProjects[3])
- if err := project.UpdateUniverse(jirix, true); err != nil {
- t.Fatalf("%v", err)
+ // Delete project 1.
+ m, err := fake.ReadRemoteManifest()
+ if err != nil {
+ t.Fatal(err)
}
- checkDeleteFn := func(i int, revision string) {
- if i == 3 {
- localProject := filepath.Join(localDir, localProjectName(i))
- if _, err := jirix.NewSeq().Stat(localProject); err == nil {
- t.Fatalf("project %v has not been deleted", localProject)
- } else {
- if !runutil.IsNotExist(err) {
- t.Fatalf("%v", err)
- }
- }
- } else {
- checkMoveFn(i, revision)
+ projects := []project.Project{}
+ for _, p := range m.Projects {
+ if p.Name == localProjects[1].Name {
+ continue
}
+ projects = append(projects, p)
}
- for i, _ := range remoteProjects {
- checkDeleteFn(i, "revision 3")
+ m.Projects = projects
+ if err := fake.WriteRemoteManifest(m); err != nil {
+ t.Fatal(err)
+ }
+ // Check that UpdateUniverse() with gc=false does not delete the local copy
+ // of the project.
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
+ }
+ if err := s.AssertDirExists(localProjects[1].Path).Done(); err != nil {
+ t.Fatalf("expected project %q at path %q to exist but it did not", localProjects[1].Name, localProjects[1].Path)
+ }
+ checkReadme(t, fake.X, localProjects[1], "initial readme")
+ // Check that UpdateUniverse() with gc=true does delete the local copy of
+ // the project.
+ if err := fake.UpdateUniverse(true); err != nil {
+ t.Fatal(err)
+ }
+ if err := s.AssertDirExists(localProjects[1].Path).Done(); err == nil {
+ t.Fatalf("expected project %q at path %q not to exist but it did", localProjects[1].Name, localProjects[3].Path)
+ }
+}
+
+// TestUpdateUniverseNewProjectSamePath checks that UpdateUniverse can handle a
+// new project with the same path as a deleted project, but a different path.
+func TestUpdateUniverseNewProjectSamePath(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- // Delete a project and create a new one with a different name but the same
- // path. Check that UpdateUniverse() does not fail.
- deleteProject(t, jirix, remoteManifest, remoteProjects[4])
- createProject(t, jirix, remoteManifest, "new.project", remoteProjects[4], localProjectName(4))
- if err := project.UpdateUniverse(jirix, true); err != nil {
- t.Fatalf("%v", err)
+ // Delete a project 1 and create a new one with a different name but the
+ // same path.
+ m, err := fake.ReadRemoteManifest()
+ if err != nil {
+ t.Fatal(err)
}
-
- // Commit to a non-master branch of a remote project and check that
- // UpdateUniverse() can update the local project to point to a revision on
- // that branch.
- writeReadme(t, jirix, remoteProjects[5], "master commit")
- createAndCheckoutBranch(t, jirix, remoteProjects[5], "non_master")
- writeReadme(t, jirix, remoteProjects[5], "non master commit")
- remoteBranchRevision := currentRevision(t, jirix, remoteProjects[5])
- setRevisionForProject(t, jirix, remoteManifest, remoteProjects[5], remoteBranchRevision)
- if err := project.UpdateUniverse(jirix, true); err != nil {
- t.Fatalf("%v", err)
- }
- localProject := filepath.Join(localDir, localProjectName(5))
- localBranchRevision := currentRevision(t, jirix, localProject)
- if localBranchRevision != remoteBranchRevision {
- t.Fatalf("project 5 is at revision %v, expected %v\n", localBranchRevision, remoteBranchRevision)
- }
- // Reset back to origin/master so the next update without a "revision" works.
- resetToOriginMaster(t, jirix, localProject)
-
- // Create a local manifest that imports the remote manifest
- // and check that UpdateUniverse() has no effect.
- createLocalManifestStub(t, jirix, localDir)
- if err := project.UpdateUniverse(jirix, true); err != nil {
- t.Fatalf("%v", err)
- }
-
- checkRebaseFn := func(i int, revision string) {
- if i == 5 {
- checkReadme(t, jirix, localProject, "non master commit")
- } else {
- checkDeleteFn(i, revision)
+ newProjectName := "new-project-name"
+ projects := []project.Project{}
+ for _, p := range m.Projects {
+ if p.Path == localProjects[1].Path {
+ p.Name = newProjectName
}
+ projects = append(projects, p)
}
- for i, _ := range remoteProjects {
- checkRebaseFn(i, "revision 3")
+ localProjects[1].Name = newProjectName
+ m.Projects = projects
+ if err := fake.WriteRemoteManifest(m); err != nil {
+ t.Fatal(err)
+ }
+ // Check that UpdateUniverse() does not fail.
+ if err := fake.UpdateUniverse(true); err != nil {
+ t.Fatal(err)
+ }
+}
+
+// TestUpdateUniverseRemoteBranch checks that UpdateUniverse can pull from a
+// non-master remote branch.
+func TestUpdateUniverseRemoteBranch(t *testing.T) {
+ localProjects, fake, cleanup := setupUniverse(t)
+ defer cleanup()
+ s := fake.X.NewSeq()
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
}
- // Create a local manifest that matches the remote manifest,
- // then revert the remote manifest to its initial version and
- // check that UpdateUniverse() has no effect.
- createLocalManifestCopy(t, jirix, localDir, remoteManifest)
- createRemoteManifest(t, jirix, remoteManifest, remoteProjects)
- if err := project.UpdateUniverse(jirix, true); err != nil {
- t.Fatalf("%v", err)
+ // Commit to master branch of a project 1.
+ writeReadme(t, fake.X, fake.Projects[localProjects[1].Name], "master commit")
+ // Create and checkout a new branch of project 1 and make a new commit.
+ git := gitutil.New(s, gitutil.RootDirOpt(fake.Projects[localProjects[1].Name]))
+ if err := git.CreateAndCheckoutBranch("non-master"); err != nil {
+ t.Fatal(err)
}
- for i, _ := range remoteProjects {
- checkRebaseFn(i, "revision 3")
+ writeReadme(t, fake.X, fake.Projects[localProjects[1].Name], "non-master commit")
+ // Point the manifest to the new non-master branch.
+ m, err := fake.ReadRemoteManifest()
+ if err != nil {
+ t.Fatal(err)
}
+ projects := []project.Project{}
+ for _, p := range m.Projects {
+ if p.Name == localProjects[1].Name {
+ p.RemoteBranch = "non-master"
+ }
+ projects = append(projects, p)
+ }
+ m.Projects = projects
+ if err := fake.WriteRemoteManifest(m); err != nil {
+ t.Fatal(err)
+ }
+ // Check that UpdateUniverse pulls the commit from the non-master branch.
+ if err := fake.UpdateUniverse(false); err != nil {
+ t.Fatal(err)
+ }
+ checkReadme(t, fake.X, localProjects[1], "non-master commit")
}
func TestFileImportCycle(t *testing.T) {
@@ -928,9 +839,6 @@
Remote: "remote2",
RemoteBranch: "branch2",
},
- {
- Name: "oldimport",
- },
},
LocalImports: []project.LocalImport{
{File: "fileimport"},
@@ -968,7 +876,6 @@
<imports>
<import manifest="manifest1" name="remoteimport1" remote="remote1"/>
<import manifest="manifest2" name="remoteimport2" remote="remote2" remotebranch="branch2"/>
- <import name="oldimport"/>
<localimport file="fileimport"/>
</imports>
<projects>
@@ -1057,63 +964,3 @@
}
}
}
-
-func TestProjectFromFileBackwardsCompatible(t *testing.T) {
- jirix, cleanup := jiritest.NewX(t)
- defer cleanup()
-
- tests := []struct {
- XML string
- Project project.Project
- }{
- // Make sure <Project> opening tag is accepted.
- {
- `<Project name="project" path="path" remote="remote"/>`,
- project.Project{
- Name: "project",
- Path: filepath.Join(jirix.Root, "path"),
- Protocol: "git",
- Remote: "remote",
- RemoteBranch: "master",
- Revision: "HEAD",
- },
- },
- // Make sure <Project> opening and closing tags are accepted.
- {
- `<Project name="project" path="path" remote="remote"></Project>`,
- project.Project{
- Name: "project",
- Path: filepath.Join(jirix.Root, "path"),
- Protocol: "git",
- Remote: "remote",
- RemoteBranch: "master",
- Revision: "HEAD",
- },
- },
- // Make sure "this_attribute_should_be_ignored" is silently ignored.
- {
- `<Project this_attribute_should_be_ignored="junk" name="project" path="path" remote="remote" remotebranch="branch" revision="rev"></Project>`,
- project.Project{
- Name: "project",
- Path: filepath.Join(jirix.Root, "path"),
- Protocol: "git",
- Remote: "remote",
- RemoteBranch: "branch",
- Revision: "rev",
- },
- },
- }
- for index, test := range tests {
- filename := filepath.Join(jirix.Root, fmt.Sprintf("test-%d", index))
- if err := jirix.NewSeq().WriteFile(filename, []byte(test.XML), 0644).Done(); err != nil {
- t.Errorf("%+v WriteFile failed: %v", test.Project, err)
- }
- project, err := project.ProjectFromFile(jirix, filename)
- if err != nil {
- t.Errorf("%+v FromFile failed: %v", test.Project, err)
- }
- if got, want := project, &test.Project; !reflect.DeepEqual(got, want) {
- t.Errorf("%+v FromFile got %#v, want %#v", test.Project, got, want)
- }
- }
-}
diff --git a/x.go b/x.go
index 2dda4b1..726cdd8 100644
--- a/x.go
+++ b/x.go
@@ -143,14 +143,6 @@
return filepath.Join(x.Root, JiriManifestFile)
}
-// UsingOldManifests returns true iff the JIRI_ROOT/.jiri_manifest file does not
-// exist. This is the one signal used to decide whether to use the old manifest
-// logic (checking .local_manifest and the -manifest flag), or the new logic.
-func (x *X) UsingOldManifests() bool {
- _, err := os.Stat(x.JiriManifestFile())
- return os.IsNotExist(err)
-}
-
// BinDir returns the path to the bin directory.
func (x *X) BinDir() string {
return filepath.Join(x.RootMetaDir(), "bin")
@@ -188,43 +180,6 @@
return filepath.Join(x.UpdateHistoryDir(), "second-latest")
}
-// ResolveManifestPath resolves the given manifest name to an absolute path in
-// the local filesystem.
-//
-// TODO(toddw): Remove this once the transition to new manifests is done. In
-// the new world, we always start with the JiriManifestFile.
-func (x *X) ResolveManifestPath(name string) (string, error) {
- if x.UsingOldManifests() {
- return x.resolveManifestPathDeprecated(name)
- }
- if name != "" {
- return "", fmt.Errorf("-manifest flag isn't supported with .jiri_manifest")
- }
- return x.JiriManifestFile(), nil
-}
-
-// Deprecated logic, only run if JIRI_ROOT/.jiri_manifest doesn't exist.
-//
-// TODO(toddw): Remove this logic when the transition to .jiri_manifest is done.
-func (x *X) resolveManifestPathDeprecated(name string) (string, error) {
- manifestDir := filepath.Join(x.Root, ".manifest", "v2")
- if name != "" {
- if filepath.IsAbs(name) {
- return name, nil
- }
- return filepath.Join(manifestDir, name), nil
- }
- path := filepath.Join(x.Root, ".local_manifest")
- switch _, err := os.Stat(path); {
- case err == nil:
- return path, nil
- case os.IsNotExist(err):
- return filepath.Join(manifestDir, "default"), nil
- default:
- return "", fmt.Errorf("Stat(%v) failed: %v", path, err)
- }
-}
-
// RunnerFunc is an adapter that turns regular functions into cmdline.Runner.
// This is similar to cmdline.RunnerFunc, but the first function argument is
// jiri.X, rather than cmdline.Env.