Merge "jiri: Use the latest update snapshot manifest when computing LocalProjects."
diff --git a/jiri/.api b/jiri/.api
index 384b799..bbf12c1 100644
--- a/jiri/.api
+++ b/jiri/.api
@@ -14,6 +14,7 @@
pkg jiri, method (*X) ResolveManifestPath(string) (string, error)
pkg jiri, method (*X) RootMetaDir() string
pkg jiri, method (*X) UpdateHistoryDir() string
+pkg jiri, method (*X) UpdateHistoryLatestLink() string
pkg jiri, method (*X) UsageErrorf(string, ...interface{}) error
pkg jiri, method (*X) UsingOldManifests() bool
pkg jiri, method (RelPath) Abs(*X) string
diff --git a/jiri/x.go b/jiri/x.go
index 20133dd..6a574b3 100644
--- a/jiri/x.go
+++ b/jiri/x.go
@@ -136,6 +136,12 @@
return filepath.Join(x.RootMetaDir(), "update_history")
}
+// UpdateHistoryLatestLink returns the path to a symlink that points to the
+// latest update in the update history directory.
+func (x *X) UpdateHistoryLatestLink() string {
+ return filepath.Join(x.UpdateHistoryDir(), "latest")
+}
+
// ResolveManifestPath resolves the given manifest name to an absolute path in
// the local filesystem.
func (x *X) ResolveManifestPath(name string) (string, error) {
diff --git a/profiles/profilesreader/reader.go b/profiles/profilesreader/reader.go
index 7949cc7..eff4533 100644
--- a/profiles/profilesreader/reader.go
+++ b/profiles/profilesreader/reader.go
@@ -117,7 +117,7 @@
if err != nil {
return nil, err
}
- projects, tools, err := project.ReadManifest(jirix)
+ projects, tools, err := project.ReadJiriManifest(jirix)
if err != nil {
return nil, err
}
diff --git a/project/.api b/project/.api
index f689087..f475c27 100644
--- a/project/.api
+++ b/project/.api
@@ -17,7 +17,7 @@
pkg project, func PollProjects(*jiri.X, map[string]struct{}) (Update, error)
pkg project, func ProjectAtPath(*jiri.X, string) (Project, error)
pkg project, func ProjectFromFile(*jiri.X, string) (*Project, error)
-pkg project, func ReadManifest(*jiri.X) (Projects, Tools, error)
+pkg project, func ReadJiriManifest(*jiri.X) (Projects, Tools, error)
pkg project, func TransitionBinDir(*jiri.X) error
pkg project, func UpdateUniverse(*jiri.X, bool) error
pkg project, method (*Manifest) ToBytes() ([]byte, error)
diff --git a/project/paths.go b/project/paths.go
index 7ff4bb8..d34c41f 100644
--- a/project/paths.go
+++ b/project/paths.go
@@ -18,7 +18,7 @@
// breaks. We should revisit the whole data directory thing, and in particular
// see if we can get rid of tools having to know their own names.
func DataDirPath(jirix *jiri.X, toolName string) (string, error) {
- projects, tools, err := ReadManifest(jirix)
+ projects, tools, err := ReadJiriManifest(jirix)
if err != nil {
return "", err
}
diff --git a/project/project.go b/project/project.go
index 30cc6ad..07fdae7 100644
--- a/project/project.go
+++ b/project/project.go
@@ -564,7 +564,7 @@
}
// Add all tools from the current manifest to the snapshot manifest.
- _, tools, err := ReadManifest(jirix)
+ _, tools, err := ReadJiriManifest(jirix)
if err != nil {
return err
}
@@ -643,11 +643,16 @@
jirix.TimerPush("local projects")
defer jirix.TimerPop()
- if scanMode == FastScan {
- // Fast path: Full scan was not requested, and all projects in
- // manifest exist on local filesystem. We just use the projects
- // directly from the manifest.
- manifestProjects, _, err := ReadManifest(jirix)
+ latestUpdateSnapshot := jirix.UpdateHistoryLatestLink()
+ latestUpdateSnapshotExists, err := jirix.NewSeq().IsFile(latestUpdateSnapshot)
+ if err != nil {
+ return nil, err
+ }
+ if scanMode == FastScan && latestUpdateSnapshotExists {
+ // Fast path: Full scan was not requested, and we have a snapshot
+ // containing the latest update. Check that the projects listed in the
+ // snapshot exist locally. If not, then fall back on the slow path.
+ manifestProjects, _, err := readManifestFile(jirix, latestUpdateSnapshot)
if err != nil {
return nil, err
}
@@ -665,7 +670,7 @@
// JIRI_ROOT.
projects := Projects{}
jirix.TimerPush("scan fs")
- err := findLocalProjects(jirix, jirix.Root, projects)
+ err = findLocalProjects(jirix, jirix.Root, projects)
jirix.TimerPop()
if err != nil {
return nil, err
@@ -711,7 +716,7 @@
if err != nil {
return nil, err
}
- remoteProjects, _, err := ReadManifest(jirix)
+ remoteProjects, _, err := ReadJiriManifest(jirix)
if err != nil {
return nil, err
}
@@ -772,15 +777,19 @@
return update, nil
}
-// ReadManifest retrieves and parses the manifest that determines what
-// projects and tools are part of the jiri universe.
-func ReadManifest(jirix *jiri.X) (Projects, Tools, error) {
- jirix.TimerPush("read manifest")
- defer jirix.TimerPop()
+// ReadJiriManifest reads and parses the .jiri_manifest file.
+func ReadJiriManifest(jirix *jiri.X) (Projects, Tools, error) {
file, err := jirix.ResolveManifestPath(jirix.Manifest())
if err != nil {
return nil, nil, err
}
+ return readManifestFile(jirix, file)
+}
+
+// readManifestFile reads and parses the manifest with the given filename.
+func readManifestFile(jirix *jiri.X, file string) (Projects, Tools, error) {
+ jirix.TimerPush("read manifest")
+ defer jirix.TimerPop()
var imp importer
projects, tools := Projects{}, Tools{}
if err := imp.Load(jirix, jirix.Root, file, "", projects, tools); err != nil {
@@ -853,7 +862,7 @@
if err := updateManifestProjects(jirix); err != nil {
return err
}
- remoteProjects, remoteTools, err := ReadManifest(jirix)
+ remoteProjects, remoteTools, err := ReadJiriManifest(jirix)
if err != nil {
return err
}
@@ -2151,7 +2160,7 @@
// ParseNames identifies the set of projects that a jiri command should
// be applied to.
func ParseNames(jirix *jiri.X, args []string, defaultProjects map[string]struct{}) (Projects, error) {
- manifestProjects, _, err := ReadManifest(jirix)
+ manifestProjects, _, err := ReadJiriManifest(jirix)
if err != nil {
return nil, err
}
diff --git a/project/project_test.go b/project/project_test.go
index 706e270..95ae6d0 100644
--- a/project/project_test.go
+++ b/project/project_test.go
@@ -319,8 +319,6 @@
jirix, cleanup := jiritest.NewX(t)
defer cleanup()
- manifestDir := setupNewProject(t, jirix, jirix.Root, ".manifest", false)
-
// Create some projects.
numProjects, projectPaths := 3, []string{}
for i := 0; i < numProjects; i++ {
@@ -337,8 +335,23 @@
projectPaths = append(projectPaths, path)
}
- // Create manifest but only tell it about the first project.
- createRemoteManifest(t, jirix, manifestDir, projectPaths[:1])
+ // Create a latest update snapshot but only tell it about the first project.
+ manifest := project.Manifest{
+ Projects: []project.Project{
+ {
+ Name: projectPaths[0],
+ Path: localProjectName(0),
+ Protocol: "git",
+ Remote: projectPaths[0],
+ },
+ },
+ }
+ if err := jirix.NewSeq().MkdirAll(jirix.UpdateHistoryDir(), 0755).Done(); err != nil {
+ t.Fatalf("MkdirAll(%v) failed: %v", jirix.UpdateHistoryDir(), err)
+ }
+ if err := manifest.ToFile(jirix, jirix.UpdateHistoryLatestLink()); err != nil {
+ t.Fatalf("manifest.ToFile(%v) failed: %v", jirix.UpdateHistoryLatestLink(), err)
+ }
// LocalProjects with scanMode = FastScan should only find the first
// project.
diff --git a/rebuild.go b/rebuild.go
index 4b65150..3f68b9a 100644
--- a/rebuild.go
+++ b/rebuild.go
@@ -29,7 +29,7 @@
}
func runRebuild(jirix *jiri.X, args []string) (e error) {
- _, tools, err := project.ReadManifest(jirix)
+ _, tools, err := project.ReadJiriManifest(jirix)
if err != nil {
return err
}
diff --git a/runutil/sequence.go b/runutil/sequence.go
index 9bf28d9..40754d4 100644
--- a/runutil/sequence.go
+++ b/runutil/sequence.go
@@ -947,6 +947,9 @@
fileInfo, err = os.Stat(dirname)
return err
}, fmt.Sprintf("isdir %q", dirname))
+ if IsNotExist(err) {
+ return false, nil
+ }
if err != nil {
return false, err
}
@@ -967,6 +970,9 @@
fileInfo, err = os.Stat(file)
return err
}, fmt.Sprintf("isfile %q", file))
+ if IsNotExist(err) {
+ return false, nil
+ }
if err != nil {
return false, err
}
diff --git a/update.go b/update.go
index 05f46dd..f9ef8a7 100644
--- a/update.go
+++ b/update.go
@@ -65,6 +65,11 @@
if err := project.CreateSnapshot(jirix, snapshotFile); err != nil {
return err
}
+ // Point the "latest" update history symlink to the new snapshot file.
+ link := jirix.UpdateHistoryLatestLink()
+ if err := jirix.NewSeq().RemoveAll(link).Symlink(snapshotFile, link).Done(); err != nil {
+ return err
+ }
// Only attempt the bin dir transition after the update has succeeded, to
// avoid messy partial states.
return project.TransitionBinDir(jirix)