[project] Add repeatable -package-to-skip flag
The -package-to-skip flag is a repeatable flag of package names which,
if fed into the update, run-hooks, or fetch-packages subcommands, will
direct Jiri to skip fetching the specified packages.
Test: Ran `jiri update` with the new flag against
infra/roller-tests/integration.git, confirmed that the specified
package was skipped.
Bug: 100001
Change-Id: Ie568a71218c2c20599cb93768ac06f1f844e6758
Reviewed-on: https://fuchsia-review.googlesource.com/c/jiri/+/678659
Reviewed-by: Nathan Mulcahey <nmulcahey@google.com>
Commit-Queue: Anthony Fandrianto <atyfto@google.com>
diff --git a/cmd/jiri/fetch_pkgs.go b/cmd/jiri/fetch_pkgs.go
index e9e0af9..842ebcc 100644
--- a/cmd/jiri/fetch_pkgs.go
+++ b/cmd/jiri/fetch_pkgs.go
@@ -15,6 +15,7 @@
fetchPkgsTimeout uint
attempts uint
skipLocalProjects bool
+ packagesToSkip arrayFlag
}
var cmdFetchPkgs = &cmdline.Command{
@@ -32,6 +33,7 @@
cmdFetchPkgs.Flags.UintVar(&fetchPkgsFlags.fetchPkgsTimeout, "fetch-packages-timeout", project.DefaultPackageTimeout, "Timeout in minutes for fetching prebuilt packages using cipd.")
cmdFetchPkgs.Flags.UintVar(&fetchPkgsFlags.attempts, "attempts", 1, "Number of attempts before failing.")
cmdFetchPkgs.Flags.BoolVar(&fetchPkgsFlags.skipLocalProjects, "skip-local-projects", false, "Skip checking local project state.")
+ cmdFetchPkgs.Flags.Var(&runHooksFlags.packagesToSkip, "package-to-skip", "Skip fetching this package. Repeatable.")
}
func runFetchPkgs(jirix *jiri.X, args []string) (err error) {
@@ -60,6 +62,7 @@
if err := project.FilterOptionalProjectsPackages(jirix, jirix.FetchingAttrs, nil, pkgs); err != nil {
return err
}
+ project.FilterPackagesByName(jirix, pkgs, fetchPkgsFlags.packagesToSkip)
if len(pkgs) > 0 {
return project.FetchPackages(jirix, pkgs, fetchPkgsFlags.fetchPkgsTimeout)
}
diff --git a/cmd/jiri/run_hooks.go b/cmd/jiri/run_hooks.go
index f699d6c..c7cad9d 100644
--- a/cmd/jiri/run_hooks.go
+++ b/cmd/jiri/run_hooks.go
@@ -11,10 +11,11 @@
)
var runHooksFlags struct {
- localManifest bool
- hookTimeout uint
- attempts uint
- fetchPackages bool
+ localManifest bool
+ hookTimeout uint
+ attempts uint
+ fetchPackages bool
+ packagesToSkip arrayFlag
}
var cmdRunHooks = &cmdline.Command{
@@ -32,6 +33,7 @@
cmdRunHooks.Flags.UintVar(&runHooksFlags.hookTimeout, "hook-timeout", project.DefaultHookTimeout, "Timeout in minutes for running the hooks operation.")
cmdRunHooks.Flags.UintVar(&runHooksFlags.attempts, "attempts", 1, "Number of attempts before failing.")
cmdRunHooks.Flags.BoolVar(&runHooksFlags.fetchPackages, "fetch-packages", true, "Use fetching packages using jiri.")
+ cmdRunHooks.Flags.Var(&runHooksFlags.packagesToSkip, "package-to-skip", "Skip fetching this package. Repeatable.")
}
func runHooks(jirix *jiri.X, args []string) (err error) {
@@ -61,6 +63,7 @@
if err := project.FilterOptionalProjectsPackages(jirix, jirix.FetchingAttrs, nil, pkgs); err != nil {
return err
}
+ project.FilterPackagesByName(jirix, pkgs, runHooksFlags.packagesToSkip)
// Get packages if the fetchPackages is true
if runHooksFlags.fetchPackages && len(pkgs) > 0 {
// Extend timeout for packages to be 5 times the timeout of a single hook.
diff --git a/cmd/jiri/snapshot_test.go b/cmd/jiri/snapshot_test.go
index dc7a6f0..e030350 100644
--- a/cmd/jiri/snapshot_test.go
+++ b/cmd/jiri/snapshot_test.go
@@ -84,7 +84,7 @@
for i := 0; i < numProjects; i++ {
writeReadme(t, fake.X, fake.Projects[remoteProjectName(i)], "revision 1")
}
- if err := project.UpdateUniverse(fake.X, true, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, true, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatalf("%v", err)
}
@@ -111,7 +111,7 @@
}
snapshotFile := tmpfile.Name()
- if err := project.CheckoutSnapshot(fake.X, snapshotFile, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.CheckoutSnapshot(fake.X, snapshotFile, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatalf("%s", err)
}
for i := range remoteProjects {
diff --git a/cmd/jiri/source_manifest_test.go b/cmd/jiri/source_manifest_test.go
index 0159a67..2d1c0ae 100644
--- a/cmd/jiri/source_manifest_test.go
+++ b/cmd/jiri/source_manifest_test.go
@@ -53,7 +53,7 @@
for i := 0; i < numProjects; i++ {
writeReadme(t, fake.X, fake.Projects[remoteProjectName(i)], fmt.Sprintf("proj %d", i))
}
- if err := project.UpdateUniverse(fake.X, true, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, true, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatalf("%s", err)
}
diff --git a/cmd/jiri/update.go b/cmd/jiri/update.go
index b992196..9b64670 100644
--- a/cmd/jiri/update.go
+++ b/cmd/jiri/update.go
@@ -30,6 +30,7 @@
runHooksFlag bool
fetchPkgsFlag bool
overrideOptionalFlag bool
+ packagesToSkipFlag arrayFlag
)
const (
@@ -52,6 +53,7 @@
cmdUpdate.Flags.BoolVar(&runHooksFlag, "run-hooks", true, "Run hooks after updating sources.")
cmdUpdate.Flags.BoolVar(&fetchPkgsFlag, "fetch-packages", true, "Use cipd to fetch packages.")
cmdUpdate.Flags.BoolVar(&overrideOptionalFlag, "override-optional", false, "Override existing optional attributes in the snapshot file with current jiri settings")
+ cmdUpdate.Flags.Var(&packagesToSkipFlag, "package-to-skip", "Skip fetching this package. Repeatable.")
}
// cmdUpdate represents the "jiri update" command.
@@ -95,7 +97,7 @@
if len(args) > 0 {
jirix.OverrideOptional = overrideOptionalFlag
- if err := project.CheckoutSnapshot(jirix, args[0], gcFlag, runHooksFlag, fetchPkgsFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag); err != nil {
+ if err := project.CheckoutSnapshot(jirix, args[0], gcFlag, runHooksFlag, fetchPkgsFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag, packagesToSkipFlag); err != nil {
return err
}
} else {
@@ -109,7 +111,7 @@
}
err := project.UpdateUniverse(jirix, gcFlag, localManifestFlag,
- rebaseTrackedFlag, rebaseUntrackedFlag, rebaseAllFlag, runHooksFlag, fetchPkgsFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag)
+ rebaseTrackedFlag, rebaseUntrackedFlag, rebaseAllFlag, runHooksFlag, fetchPkgsFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag, packagesToSkipFlag)
if err2 := project.WriteUpdateHistorySnapshot(jirix, nil, nil, localManifestFlag); err2 != nil {
if err != nil {
return fmt.Errorf("while updating: %s, while writing history: %s", err, err2)
diff --git a/jiritest/fake.go b/jiritest/fake.go
index 8b43926..16af0ad 100644
--- a/jiritest/fake.go
+++ b/jiritest/fake.go
@@ -203,7 +203,7 @@
// UpdateUniverse synchronizes the content of the Vanadium fake based
// on the content of the remote manifest.
func (fake FakeJiriRoot) UpdateUniverse(gc bool) error {
- if err := project.UpdateUniverse(fake.X, gc, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, gc, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
return err
}
return nil
diff --git a/project/project.go b/project/project.go
index 4ae1539..8c72f30 100644
--- a/project/project.go
+++ b/project/project.go
@@ -823,7 +823,7 @@
// CheckoutSnapshot updates project state to the state specified in the given
// snapshot file. Note that the snapshot file must not contain remote imports.
-func CheckoutSnapshot(jirix *jiri.X, snapshot string, gc, runHooks, fetchPkgs bool, runHookTimeout, fetchTimeout uint) error {
+func CheckoutSnapshot(jirix *jiri.X, snapshot string, gc, runHooks, fetchPkgs bool, runHookTimeout, fetchTimeout uint, pkgsToSkip []string) error {
jirix.UsingSnapshot = true
// Find all local projects.
scanMode := FastScan
@@ -838,7 +838,7 @@
if err != nil {
return err
}
- if err := updateProjects(jirix, localProjects, remoteProjects, hooks, pkgs, gc, runHookTimeout, fetchTimeout, false /*rebaseTracked*/, false /*rebaseUntracked*/, false /*rebaseAll*/, true /*snapshot*/, runHooks, fetchPkgs); err != nil {
+ if err := updateProjects(jirix, localProjects, remoteProjects, hooks, pkgs, gc, runHookTimeout, fetchTimeout, false /*rebaseTracked*/, false /*rebaseUntracked*/, false /*rebaseAll*/, true /*snapshot*/, runHooks, fetchPkgs, pkgsToSkip); err != nil {
return err
}
return WriteUpdateHistorySnapshot(jirix, hooks, pkgs, false)
@@ -1412,7 +1412,7 @@
// counterparts identified in the manifest. Optionally, the 'gc' flag can be
// used to indicate that local projects that no longer exist remotely should be
// removed.
-func UpdateUniverse(jirix *jiri.X, gc, localManifest, rebaseTracked, rebaseUntracked, rebaseAll, runHooks, fetchPkgs bool, runHookTimeout, fetchTimeout uint) (e error) {
+func UpdateUniverse(jirix *jiri.X, gc, localManifest, rebaseTracked, rebaseUntracked, rebaseAll, runHooks, fetchPkgs bool, runHookTimeout, fetchTimeout uint, pkgsToSkip []string) (e error) {
jirix.Logger.Infof("Updating all projects")
updateFn := func(scanMode ScanMode) error {
jirix.TimerPush(fmt.Sprintf("update universe: %s", scanMode))
@@ -1432,7 +1432,7 @@
}
// Actually update the projects.
- return updateProjects(jirix, localProjects, remoteProjects, hooks, pkgs, gc, runHookTimeout, fetchTimeout, rebaseTracked, rebaseUntracked, rebaseAll, false /*snapshot*/, runHooks, fetchPkgs)
+ return updateProjects(jirix, localProjects, remoteProjects, hooks, pkgs, gc, runHookTimeout, fetchTimeout, rebaseTracked, rebaseUntracked, rebaseAll, false /*snapshot*/, runHooks, fetchPkgs, pkgsToSkip)
}
// Specifying gc should always force a full filesystem scan.
@@ -2332,6 +2332,24 @@
return nil
}
+// FilterPackagesByName removes packages in place given a list of CIPD package names.
+func FilterPackagesByName(jirix *jiri.X, pkgs Packages, pkgsToSkip []string) {
+ if len(pkgsToSkip) == 0 {
+ return
+ }
+ jirix.TimerPush("filter packages by name")
+ defer jirix.TimerPop()
+ pkgsSet := make(map[string]bool)
+ for _, p := range pkgsToSkip {
+ pkgsSet[p] = true
+ }
+ for k, v := range pkgs {
+ if _, ok := pkgsSet[v.Name]; ok {
+ delete(pkgs, k)
+ }
+ }
+}
+
// FilterOptionalProjectsPackages removes projects and packages in place if the Optional field is true and
// attributes in attrs does not match the Attributes field. Currently "match" means the intersection of
// both attributes is not empty.
@@ -2364,7 +2382,7 @@
return nil
}
-func updateProjects(jirix *jiri.X, localProjects, remoteProjects Projects, hooks Hooks, pkgs Packages, gc bool, runHookTimeout, fetchTimeout uint, rebaseTracked, rebaseUntracked, rebaseAll, snapshot, shouldRunHooks, shouldFetchPkgs bool) error {
+func updateProjects(jirix *jiri.X, localProjects, remoteProjects Projects, hooks Hooks, pkgs Packages, gc bool, runHookTimeout, fetchTimeout uint, rebaseTracked, rebaseUntracked, rebaseAll, snapshot, shouldRunHooks, shouldFetchPkgs bool, pkgsToSkip []string) error {
jirix.TimerPush("update projects")
defer jirix.TimerPop()
@@ -2383,6 +2401,7 @@
if err := FilterOptionalProjectsPackages(jirix, jirix.FetchingAttrs, remoteProjects, pkgs); err != nil {
return err
}
+ FilterPackagesByName(jirix, pkgs, pkgsToSkip)
if err := updateCache(jirix, remoteProjects); err != nil {
return err
diff --git a/project/project_test.go b/project/project_test.go
index 16d1e04..6ed5278 100644
--- a/project/project_test.go
+++ b/project/project_test.go
@@ -360,7 +360,7 @@
writeFile(t, fake.X, fake.Projects[localProjects[1].Name], "file1", "file1")
gitRemote := gitutil.New(fake.X, gitutil.RootDirOpt(fake.Projects[localProjects[1].Name]))
remoteRev, _ := gitRemote.CurrentRevision()
- if err := project.UpdateUniverse(fake.X, false, false, false, false, true /*rebase-all*/, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, false, false, false, true /*rebase-all*/, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
projects, err := project.LocalProjects(fake.X, project.FastScan)
@@ -400,7 +400,7 @@
writeFile(t, fake.X, fake.Projects[localProjects[1].Name], "file1", "file1")
remoteRev, _ := gitRemote.CurrentRevision()
- if err := project.UpdateUniverse(fake.X, false, false, false, false, true /*rebase-all*/, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, false, false, false, true /*rebase-all*/, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
projects, err := project.LocalProjects(fake.X, project.FastScan)
@@ -770,7 +770,7 @@
if err := manifest.ToFile(fake.X, filepath.Join(fake.X.Root, jiritest.ManifestProjectPath, jiritest.ManifestFileName)); err != nil {
t.Fatal(err)
}
- if err := project.UpdateUniverse(fake.X, false, true /* localManifest */, false, false, false, false, false, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, true /* localManifest */, false, false, false, false, false, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
@@ -852,7 +852,7 @@
// Add new commit to last project
writeFile(t, fake.X, fake.Projects[lastProject.Name], "file1", "file1")
- if err := project.UpdateUniverse(fake.X, false, true /* localManifest */, false, false, false, false, false, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, true /* localManifest */, false, false, false, false, false, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
// check last project revision
@@ -1001,7 +1001,7 @@
if err != nil {
t.Fatal(err)
}
- if err := project.UpdateUniverse(fake.X, false, false, true /*rebaseTracked*/, false, false, false /*run-hooks*/, false /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, false, true /*rebaseTracked*/, false, false, false /*run-hooks*/, false /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
}
@@ -1659,7 +1659,7 @@
t.Fatal(err)
}
- if err := project.UpdateUniverse(fake.X, false, false, true /*rebaseTracked*/, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, false, true /*rebaseTracked*/, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
@@ -1851,9 +1851,9 @@
}))
defer server.Close()
- project.CheckoutSnapshot(fake.X, server.URL, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout)
+ project.CheckoutSnapshot(fake.X, server.URL, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil)
} else {
- project.CheckoutSnapshot(fake.X, snapshotFile, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout)
+ project.CheckoutSnapshot(fake.X, snapshotFile, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil)
}
sort.Sort(project.ProjectsByPath(localProjects))
for i, localProject := range localProjects {
@@ -1904,7 +1904,7 @@
}
}
- if err := project.UpdateUniverse(fake.X, false, false, false, false, rebaseAll, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout); err != nil {
+ if err := project.UpdateUniverse(fake.X, false, false, false, false, rebaseAll, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil {
t.Fatal(err)
}
@@ -2007,7 +2007,7 @@
}
// The update should complain about the cycle.
- err := project.UpdateUniverse(jirix, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout)
+ err := project.UpdateUniverse(jirix, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil)
if got, want := fmt.Sprint(err), "import cycle detected in local manifest files"; !strings.Contains(got, want) {
t.Errorf("got error %v, want substr %v", got, want)
}
@@ -2058,7 +2058,7 @@
commitFile(t, fake.X, remote2, fileB, "commit B")
// The update should complain about the cycle.
- err := project.UpdateUniverse(fake.X, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout)
+ err := project.UpdateUniverse(fake.X, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil)
if got, want := fmt.Sprint(err), "import cycle detected in remote manifest imports"; !strings.Contains(got, want) {
t.Errorf("got error %v, want substr %v", got, want)
}
@@ -2128,7 +2128,7 @@
commitFile(t, fake.X, remote1, fileD, "commit D")
// The update should complain about the cycle.
- err := project.UpdateUniverse(fake.X, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout)
+ err := project.UpdateUniverse(fake.X, false, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil)
if got, want := fmt.Sprint(err), "import cycle detected"; !strings.Contains(got, want) {
t.Errorf("got error %v, want substr %v", got, want)
}
@@ -2846,3 +2846,33 @@
t.Errorf("expecting %v first level nodes, but got %v", 3, len(root.Children))
}
}
+
+func TestFilterPackagesByName(t *testing.T) {
+ jirix, cleanup := xtest.NewX(t)
+ defer cleanup()
+ p := []project.Package{
+ {Name: "test0", Version: "version"},
+ {Name: "test1", Version: "version"},
+ {Name: "test2", Version: "version"},
+ {Name: "test3", Version: "version"},
+ }
+ e := []project.Package{
+ {Name: "test0", Version: "version"},
+ {Name: "test3", Version: "version"},
+ }
+ pkgsToSkip := []string{"test1", "test2"}
+
+ pkgs := make(project.Packages)
+ expected := make(project.Packages)
+ for _, v := range p {
+ pkgs[v.Key()] = v
+ }
+ for _, v := range e {
+ expected[v.Key()] = v
+ }
+
+ project.FilterPackagesByName(jirix, pkgs, pkgsToSkip)
+ if !reflect.DeepEqual(pkgs, expected) {
+ t.Errorf("filter packages got %v, want %v", pkgs, expected)
+ }
+}