feat(vendor): --exclude plus content-type selection (--types/--exclude-types)
vendor add gains --exclude a,b,c (all mode minus those ids) as the mirror of --include, for taking the majority of a source while dropping a few items. Mutual exclusion with --include is a hard error, unknown ids fail naming the available ones (generalized checkIDEntries). vendor add and vendor select gain --types (allow-list) and --exclude-types (deny-list) over the four content types. The filter is stored as the optional, v2-compatible Selection.exclude_types field and survives vendor update: new upstream items of an excluded type never enter the work repository (unlike id expansion, which would silently re-admit them). --types/--exclude-types replace the filter on select, absent flags keep it, and --mode all clears it along with include/exclude. Also fixes materializeTree to create the staging directory for an empty selection — previously select-to-zero failed at the staging rename.
This commit is contained in:
1 parent
1ab97bff43
commit
0c779bc970
9 files changed
+533
-50
No files matched your search
Vendored
+37
-16
@@ -15,9 +15,11 @@ import (
|
||||
|
||||
// SelectOptions parameterize vendor select.
|
||||
type SelectOptions struct {
|
||||
Add []string
|
||||
Remove []string
|
||||
ModeAll bool
|
||||
Add []string
|
||||
Remove []string
|
||||
ModeAll bool
|
||||
OnlyTypes []string
|
||||
ExcludeTypes []string
|
||||
}
|
||||
|
||||
// Select changes what a vendored source contributes — without advancing the
|
||||
@@ -60,6 +62,9 @@ func Select(workDir, name string, opts SelectOptions, stdout io.Writer) (*Change
|
||||
if err := validateSelectIDs(items, src, opts, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := checkIncludeVsTypes(items, newSel, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
selected := applySelection(items, newSel)
|
||||
if err := checkCollisions(workDir, lf, name, selected, src.Renames); err != nil {
|
||||
@@ -99,6 +104,9 @@ func Select(workDir, name string, opts SelectOptions, stdout io.Writer) (*Change
|
||||
}
|
||||
|
||||
fmt.Fprintf(stdout, "source %s: selection updated at pinned rev %s (mode %s)\n", name, short(src.Rev), newSel.Mode)
|
||||
if len(newSel.ExcludeTypes) > 0 {
|
||||
fmt.Fprintf(stdout, " type filter: excluding %s\n", strings.Join(newSel.ExcludeTypes, ", "))
|
||||
}
|
||||
printChangeReport(stdout, report)
|
||||
return report, nil
|
||||
}
|
||||
@@ -106,30 +114,43 @@ func Select(workDir, name string, opts SelectOptions, stdout io.Writer) (*Change
|
||||
// planSelection derives the new selection from the flags — pure, before any
|
||||
// upstream contact: --mode all resets to everything; include mode grows and
|
||||
// shrinks the include list; all mode --remove moves ids onto the exclude
|
||||
// list.
|
||||
// list. --types/--exclude-types replace the type filter (absent flags keep
|
||||
// it; --mode all clears it along with include/exclude).
|
||||
func planSelection(src *lockfile.Source, opts SelectOptions, name string) (lockfile.Selection, error) {
|
||||
typeFilter, err := TypeFilter(opts.OnlyTypes, opts.ExcludeTypes)
|
||||
if err != nil {
|
||||
return lockfile.Selection{}, err
|
||||
}
|
||||
if opts.ModeAll {
|
||||
if len(opts.Add) > 0 || len(opts.Remove) > 0 {
|
||||
return lockfile.Selection{}, fmt.Errorf("--mode all cannot be combined with --add or --remove")
|
||||
if len(opts.Add) > 0 || len(opts.Remove) > 0 || typeFilter != nil {
|
||||
return lockfile.Selection{}, fmt.Errorf("--mode all cannot be combined with --add, --remove, --types or --exclude-types")
|
||||
}
|
||||
return lockfile.Selection{Mode: lockfile.ModeAll}, nil
|
||||
}
|
||||
if len(opts.Add) == 0 && len(opts.Remove) == 0 {
|
||||
return lockfile.Selection{}, fmt.Errorf("nothing to do: pass --add <ids>, --remove <ids> or --mode all")
|
||||
if len(opts.Add) == 0 && len(opts.Remove) == 0 && typeFilter == nil {
|
||||
return lockfile.Selection{}, fmt.Errorf("nothing to do: pass --add <ids>, --remove <ids>, --types/--exclude-types or --mode all")
|
||||
}
|
||||
var newSel lockfile.Selection
|
||||
if src.Selection.Mode == lockfile.ModeAll {
|
||||
if len(opts.Add) > 0 {
|
||||
return lockfile.Selection{}, fmt.Errorf("source %q: everything is already selected in all mode; use --remove <ids> to exclude items", name)
|
||||
}
|
||||
return lockfile.Selection{
|
||||
newSel = lockfile.Selection{
|
||||
Mode: lockfile.ModeAll,
|
||||
Exclude: unionIDs(src.Selection.Exclude, opts.Remove),
|
||||
}, nil
|
||||
}
|
||||
} else {
|
||||
newSel = lockfile.Selection{
|
||||
Mode: lockfile.ModeInclude,
|
||||
Include: unionIDs(minusIDs(src.Selection.Include, opts.Remove), opts.Add),
|
||||
}
|
||||
}
|
||||
return lockfile.Selection{
|
||||
Mode: lockfile.ModeInclude,
|
||||
Include: unionIDs(minusIDs(src.Selection.Include, opts.Remove), opts.Add),
|
||||
}, nil
|
||||
if typeFilter != nil {
|
||||
newSel.ExcludeTypes = typeFilter
|
||||
} else {
|
||||
newSel.ExcludeTypes = src.Selection.ExcludeTypes
|
||||
}
|
||||
return newSel, nil
|
||||
}
|
||||
|
||||
// validateSelectIDs checks flag ids against the pinned upstream (and, for
|
||||
@@ -137,7 +158,7 @@ func planSelection(src *lockfile.Source, opts SelectOptions, name string) (lockf
|
||||
// before anything is mutated.
|
||||
func validateSelectIDs(items []discovery.Item, src *lockfile.Source, opts SelectOptions, name string) error {
|
||||
if len(opts.Add) > 0 {
|
||||
if err := checkIncludeEntries(items, opts.Add, name); err != nil {
|
||||
if err := checkIDEntries(items, opts.Add, name, "include"); err != nil {
|
||||
return fmt.Errorf("--add: %w", err)
|
||||
}
|
||||
}
|
||||
@@ -153,7 +174,7 @@ func validateSelectIDs(items []discovery.Item, src *lockfile.Source, opts Select
|
||||
}
|
||||
}
|
||||
if len(opts.Remove) > 0 && src.Selection.Mode == lockfile.ModeAll {
|
||||
if err := checkIncludeEntries(items, opts.Remove, name); err != nil {
|
||||
if err := checkIDEntries(items, opts.Remove, name, "exclude"); err != nil {
|
||||
return fmt.Errorf("--remove: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user