diff --git a/cmd/chisel/cmd_find.go b/cmd/chisel/cmd_find.go index 91c3f7f7..1a208d4b 100644 --- a/cmd/chisel/cmd_find.go +++ b/cmd/chisel/cmd_find.go @@ -57,9 +57,13 @@ func (cmd *cmdFind) Execute(args []string) error { } w := tabWriter() - fmt.Fprintf(w, "Slice\tSummary\n") + fmt.Fprintf(w, "Slice\tHint\n") for _, s := range slices { - fmt.Fprintf(w, "%s\t%s\n", s, "-") + hint := "-" + if s.Hint != "" { + hint = s.Hint + } + fmt.Fprintf(w, "%s\t%s\n", s, hint) } w.Flush() diff --git a/cmd/chisel/cmd_info_test.go b/cmd/chisel/cmd_info_test.go index b3fd6eb0..36bde44b 100644 --- a/cmd/chisel/cmd_info_test.go +++ b/cmd/chisel/cmd_info_test.go @@ -38,6 +38,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: + hint: Hint for mypkg2_myslice contents: /dir/another-file: {} `, @@ -52,6 +53,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -67,6 +69,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -74,6 +77,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: + hint: Hint for mypkg2_myslice contents: /dir/another-file: {} `, @@ -88,6 +92,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -148,6 +153,7 @@ var infoRelease = map[string]string{ contents: /dir/file: myslice2: + hint: Hint for mypkg1_myslice2 v3-essential: mypkg2_myslice: {arch: amd64} `, @@ -155,6 +161,7 @@ var infoRelease = map[string]string{ package: mypkg2 slices: myslice: + hint: Hint for mypkg2_myslice contents: /dir/another-file: `, diff --git a/internal/setup/setup.go b/internal/setup/setup.go index db3d9518..918fb29b 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -59,6 +59,7 @@ type Package struct { type Slice struct { Package string Name string + Hint string Essential map[SliceKey]EssentialInfo Contents map[string]PathInfo Scripts SliceScripts diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index ac956ce1..4572a7b0 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1265,7 +1265,49 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice name "cc" in slices/mydir/mypkg.yaml \(start with a-z, len >= 3, only a-z / 0-9 / -\)`, + relerror: `invalid slice name in slices/mydir/mypkg.yaml \(start with a-z, len >= 3, only a-z / 0-9 / -\): "cc"`, +}, { + summary: "Invalid slice hint - too long", + input: map[string]string{ + "slices/mydir/mypkg.yaml": ` + package: mypkg + slices: + slice1: + hint: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + contents: + /usr/bin/cc: + `, + }, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only letters, numbers, symbols and " "\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, +}, { + summary: "Invalid slice hint - line breaks", + input: map[string]string{ + "slices/mydir/mypkg.yaml": ` + package: mypkg + slices: + slice1: + hint: | + On + multiple + lines. + contents: + /usr/bin/cc: + `, + }, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only letters, numbers, symbols and " "\): "On\\nmultiple\\nlines.\\n"`, +}, { + summary: "Invalid slice hint - non-standard spaces", + input: map[string]string{ + "slices/mydir/mypkg.yaml": ` + package: mypkg + slices: + slice1: + hint: "Seperated\tby\ttabs." + contents: + /usr/bin/cc: + `, + }, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only letters, numbers, symbols and " "\): "Seperated\\tby\\ttabs."`, }, { summary: "Package essentials with same package slice", input: map[string]string{ @@ -3702,6 +3744,19 @@ func (s *S) TestPackageYAMLFormat(c *C) { /dir/file: {} `, }, + }, { + summary: "Slice with hint", + input: map[string]string{ + "slices/mypkg.yaml": ` + package: mypkg + archive: ubuntu + slices: + myslice: + hint: Shipping greatness + contents: + /dir/file: {} + `, + }, }, { summary: "All types of paths", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index b7fc65b4..bf484396 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -8,6 +8,7 @@ import ( "slices" "strings" "time" + "unicode" "golang.org/x/crypto/openpgp/packet" "gopkg.in/yaml.v3" @@ -146,6 +147,7 @@ func (ym yamlMode) MarshalYAML() (any, error) { var _ yaml.Marshaler = yamlMode(0) type yamlSlice struct { + Hint string `yaml:"hint,omitempty"` Essential []string `yaml:"essential,omitempty"` Contents map[string]*yamlPath `yaml:"contents,omitempty"` Mutate string `yaml:"mutate,omitempty"` @@ -407,11 +409,18 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro for sliceName, yamlSlice := range yamlPkg.Slices { match := apacheutil.SnameExp.FindStringSubmatch(sliceName) if match == nil { - return nil, fmt.Errorf("invalid slice name %q in %s (start with a-z, len >= 3, only a-z / 0-9 / -)", sliceName, pkgPath) + return nil, fmt.Errorf("invalid slice name in %s (start with a-z, len >= 3, only a-z / 0-9 / -): %q", pkgPath, sliceName) + } + hintNotPrintable := strings.ContainsFunc(yamlSlice.Hint, func(r rune) bool { + return !unicode.IsPrint(r) + }) + if len(yamlSlice.Hint) > 40 || hintNotPrintable { + return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, only letters, numbers, symbols and \" \"): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, Name: sliceName, + Hint: yamlSlice.Hint, Scripts: SliceScripts{ Mutate: yamlSlice.Mutate, }, @@ -631,6 +640,7 @@ func pathInfoToYAML(pi *PathInfo) (*yamlPath, error) { // sliceToYAML converts a Slice object to a yamlSlice object. func sliceToYAML(s *Slice) (*yamlSlice, error) { slice := &yamlSlice{ + Hint: s.Hint, Contents: make(map[string]*yamlPath, len(s.Contents)), Mutate: s.Scripts.Mutate, V3Essential: make(map[string]*yamlEssential, len(s.Essential)),