From 91126a28dc9442e5fc4f5ebc15916e572bd338a6 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Fri, 9 Jan 2026 17:36:24 +0100 Subject: [PATCH 01/10] feat: support hints --- cmd/chisel/cmd_find.go | 8 ++++++-- cmd/chisel/cmd_info_test.go | 7 +++++++ internal/setup/setup.go | 1 + internal/setup/setup_test.go | 29 +++++++++++++++++++++++++++++ internal/setup/yaml.go | 6 ++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/cmd/chisel/cmd_find.go b/cmd/chisel/cmd_find.go index 91c3f7f7..c3288396 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 len(s.Hint) > 0 { + 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..3448552f 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: Another-file included contents: /dir/another-file: {} `, @@ -52,6 +53,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Different than myslice1 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -67,6 +69,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Different than myslice1 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -74,6 +77,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: + hint: Another-file included contents: /dir/another-file: {} `, @@ -88,6 +92,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: + hint: Different than myslice1 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -148,6 +153,7 @@ var infoRelease = map[string]string{ contents: /dir/file: myslice2: + hint: Different than myslice1 v3-essential: mypkg2_myslice: {arch: amd64} `, @@ -155,6 +161,7 @@ var infoRelease = map[string]string{ package: mypkg2 slices: myslice: + hint: Another-file included 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..9c0a8c49 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1266,6 +1266,35 @@ var setupTests = []setupTest{{ `, }, relerror: `invalid slice name "cc" in slices/mydir/mypkg.yaml \(start with a-z, len >= 3, only a-z / 0-9 / -\)`, +}, { + 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: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \(len <= 40, no line breaks\)`, +}, { + 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: "On\\nmultiple\\nlines.\\n" \(len <= 40, no line breaks\)`, }, { summary: "Package essentials with same package slice", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index b7fc65b4..88a2204f 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -146,6 +146,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"` @@ -409,9 +410,13 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro 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) } + if len(yamlSlice.Hint) > 40 || strings.ContainsAny(yamlSlice.Hint, "\n") { + return nil, fmt.Errorf("invalid slice hint for %q in %s: %q (len <= 40, no line breaks)", sliceName, pkgPath, yamlSlice.Hint) + } slice := &Slice{ Package: pkgName, Name: sliceName, + Hint: yamlSlice.Hint, Scripts: SliceScripts{ Mutate: yamlSlice.Mutate, }, @@ -631,6 +636,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)), From 8e1697993f9fb3420d55af5934a86c2933cf3bb1 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Fri, 9 Jan 2026 18:06:52 +0100 Subject: [PATCH 02/10] test: hint marshalling --- internal/setup/setup_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 9c0a8c49..572ade9b 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -3731,6 +3731,30 @@ 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: {} + `, + }, + expected: 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{ From 5a14e137b497f8c1bd658ecb45e5573d9746d7ec Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Mon, 12 Jan 2026 08:29:54 +0100 Subject: [PATCH 03/10] refactor: apply PR suggestion --- cmd/chisel/cmd_find.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/chisel/cmd_find.go b/cmd/chisel/cmd_find.go index c3288396..1a208d4b 100644 --- a/cmd/chisel/cmd_find.go +++ b/cmd/chisel/cmd_find.go @@ -60,7 +60,7 @@ func (cmd *cmdFind) Execute(args []string) error { fmt.Fprintf(w, "Slice\tHint\n") for _, s := range slices { hint := "-" - if len(s.Hint) > 0 { + if s.Hint != "" { hint = s.Hint } fmt.Fprintf(w, "%s\t%s\n", s, hint) From 35173f86209fcc20fd0821033376f3459aef4a87 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Mon, 12 Jan 2026 11:10:28 +0100 Subject: [PATCH 04/10] style: apply PR suggestions --- cmd/chisel/cmd_info_test.go | 14 +++++++------- internal/setup/setup_test.go | 4 ++-- internal/setup/yaml.go | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/chisel/cmd_info_test.go b/cmd/chisel/cmd_info_test.go index 3448552f..c123bf73 100644 --- a/cmd/chisel/cmd_info_test.go +++ b/cmd/chisel/cmd_info_test.go @@ -38,7 +38,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: - hint: Another-file included + hint: Hint for myslice contents: /dir/another-file: {} `, @@ -53,7 +53,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Different than myslice1 + hint: Hint for myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -69,7 +69,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Different than myslice1 + hint: Hint for myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -77,7 +77,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: - hint: Another-file included + hint: Hint for myslice contents: /dir/another-file: {} `, @@ -92,7 +92,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Different than myslice1 + hint: Hint for myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -153,7 +153,7 @@ var infoRelease = map[string]string{ contents: /dir/file: myslice2: - hint: Different than myslice1 + hint: Hint for myslice2 v3-essential: mypkg2_myslice: {arch: amd64} `, @@ -161,7 +161,7 @@ var infoRelease = map[string]string{ package: mypkg2 slices: myslice: - hint: Another-file included + hint: Hint for myslice contents: /dir/another-file: `, diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 572ade9b..b4aef76e 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1278,7 +1278,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \(len <= 40, no line breaks\)`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, }, { summary: "Invalid slice hint - line breaks", input: map[string]string{ @@ -1294,7 +1294,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml: "On\\nmultiple\\nlines.\\n" \(len <= 40, no line breaks\)`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks\): "On\\nmultiple\\nlines.\\n"`, }, { summary: "Package essentials with same package slice", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 88a2204f..d3ccdd29 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -411,7 +411,7 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro return nil, fmt.Errorf("invalid slice name %q in %s (start with a-z, len >= 3, only a-z / 0-9 / -)", sliceName, pkgPath) } if len(yamlSlice.Hint) > 40 || strings.ContainsAny(yamlSlice.Hint, "\n") { - return nil, fmt.Errorf("invalid slice hint for %q in %s: %q (len <= 40, no line breaks)", sliceName, pkgPath, yamlSlice.Hint) + return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no line breaks): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, From 92ffeb7a429a8a54108e15520bf7f32f55b4e638 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Mon, 12 Jan 2026 11:15:06 +0100 Subject: [PATCH 05/10] style: improve test hint values --- cmd/chisel/cmd_info_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/chisel/cmd_info_test.go b/cmd/chisel/cmd_info_test.go index c123bf73..36bde44b 100644 --- a/cmd/chisel/cmd_info_test.go +++ b/cmd/chisel/cmd_info_test.go @@ -38,7 +38,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: - hint: Hint for myslice + hint: Hint for mypkg2_myslice contents: /dir/another-file: {} `, @@ -53,7 +53,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Hint for myslice2 + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -69,7 +69,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Hint for myslice2 + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -77,7 +77,7 @@ var infoTests = []infoTest{{ package: mypkg2 slices: myslice: - hint: Hint for myslice + hint: Hint for mypkg2_myslice contents: /dir/another-file: {} `, @@ -92,7 +92,7 @@ var infoTests = []infoTest{{ contents: /dir/file: {} myslice2: - hint: Hint for myslice2 + hint: Hint for mypkg1_myslice2 v3-essential: mypkg1_myslice1: {} mypkg2_myslice: {arch: amd64} @@ -153,7 +153,7 @@ var infoRelease = map[string]string{ contents: /dir/file: myslice2: - hint: Hint for myslice2 + hint: Hint for mypkg1_myslice2 v3-essential: mypkg2_myslice: {arch: amd64} `, @@ -161,7 +161,7 @@ var infoRelease = map[string]string{ package: mypkg2 slices: myslice: - hint: Hint for myslice + hint: Hint for mypkg2_myslice contents: /dir/another-file: `, From 3b29f367d77b8b0c43188422bd0293034d7bf6e3 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 13 Jan 2026 09:03:42 +0100 Subject: [PATCH 06/10] fix: forbid all non-standad spaces from hints --- internal/setup/setup_test.go | 17 +++++++++++++++-- internal/setup/yaml.go | 7 +++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index b4aef76e..2db95560 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1278,7 +1278,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks, no non-standard spaces\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, }, { summary: "Invalid slice hint - line breaks", input: map[string]string{ @@ -1294,7 +1294,20 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks\): "On\\nmultiple\\nlines.\\n"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks, no non-standard spaces\): "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, no line breaks, no non-standard spaces\): "Seperated\\tby\\ttabs."`, }, { summary: "Package essentials with same package slice", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index d3ccdd29..5aeedf44 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" @@ -410,8 +411,10 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro 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) } - if len(yamlSlice.Hint) > 40 || strings.ContainsAny(yamlSlice.Hint, "\n") { - return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no line breaks): %q", sliceName, pkgPath, yamlSlice.Hint) + if len(yamlSlice.Hint) > 40 || strings.ContainsFunc(yamlSlice.Hint, func(r rune) bool { + return unicode.IsSpace(r) && r != ' ' + }) { + return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no line breaks, no non-standard spaces): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, From aec7d72f0df9e4a19bba95b3edd7988e22860657 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 13 Jan 2026 11:16:00 +0100 Subject: [PATCH 07/10] fix: display consistent validation errors --- internal/setup/setup_test.go | 8 ++++---- internal/setup/yaml.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 2db95560..e5a03efe 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1265,7 +1265,7 @@ 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{ @@ -1278,7 +1278,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks, no non-standard spaces\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, }, { summary: "Invalid slice hint - line breaks", input: map[string]string{ @@ -1294,7 +1294,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks, no non-standard spaces\): "On\\nmultiple\\nlines.\\n"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "On\\nmultiple\\nlines.\\n"`, }, { summary: "Invalid slice hint - non-standard spaces", input: map[string]string{ @@ -1307,7 +1307,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no line breaks, no non-standard spaces\): "Seperated\\tby\\ttabs."`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "Seperated\\tby\\ttabs."`, }, { summary: "Package essentials with same package slice", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 5aeedf44..8748b325 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -409,12 +409,12 @@ 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) } if len(yamlSlice.Hint) > 40 || strings.ContainsFunc(yamlSlice.Hint, func(r rune) bool { return unicode.IsSpace(r) && r != ' ' }) { - return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no line breaks, no non-standard spaces): %q", sliceName, pkgPath, yamlSlice.Hint) + return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no non-standard spaces): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, From 93131d91009d6b686b6e48189236fbc6447dfd66 Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Tue, 13 Jan 2026 14:44:31 +0100 Subject: [PATCH 08/10] fix: only allow printable chars and space in hints --- internal/setup/setup_test.go | 6 +++--- internal/setup/yaml.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index e5a03efe..a2e17378 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1278,7 +1278,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, }, { summary: "Invalid slice hint - line breaks", input: map[string]string{ @@ -1294,7 +1294,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "On\\nmultiple\\nlines.\\n"`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "On\\nmultiple\\nlines.\\n"`, }, { summary: "Invalid slice hint - non-standard spaces", input: map[string]string{ @@ -1307,7 +1307,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, no non-standard spaces\): "Seperated\\tby\\ttabs."`, + relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "Seperated\\tby\\ttabs."`, }, { summary: "Package essentials with same package slice", input: map[string]string{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index 8748b325..11fd113f 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -412,9 +412,9 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro return nil, fmt.Errorf("invalid slice name in %s (start with a-z, len >= 3, only a-z / 0-9 / -): %q", pkgPath, sliceName) } if len(yamlSlice.Hint) > 40 || strings.ContainsFunc(yamlSlice.Hint, func(r rune) bool { - return unicode.IsSpace(r) && r != ' ' + return !unicode.IsPrint(r) }) { - return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, no non-standard spaces): %q", sliceName, pkgPath, yamlSlice.Hint) + return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, only printable characters and standard space): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ Package: pkgName, From 56d7085bab60b8c6eef4be79cfb7eb00b22278ca Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Wed, 14 Jan 2026 11:45:56 +0100 Subject: [PATCH 09/10] refactor: apply PR suggestions --- internal/setup/setup_test.go | 11 ----------- internal/setup/yaml.go | 5 +++-- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index a2e17378..8b4eb2f6 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -3757,17 +3757,6 @@ func (s *S) TestPackageYAMLFormat(c *C) { /dir/file: {} `, }, - expected: 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 11fd113f..cffea20b 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -411,9 +411,10 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro if match == nil { return nil, fmt.Errorf("invalid slice name in %s (start with a-z, len >= 3, only a-z / 0-9 / -): %q", pkgPath, sliceName) } - if len(yamlSlice.Hint) > 40 || strings.ContainsFunc(yamlSlice.Hint, func(r rune) bool { + 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 printable characters and standard space): %q", sliceName, pkgPath, yamlSlice.Hint) } slice := &Slice{ From 8ec40a9735bfb76c8aca86bc209b57ce972bd4aa Mon Sep 17 00:00:00 2001 From: Paul Mars Date: Wed, 14 Jan 2026 16:52:42 +0100 Subject: [PATCH 10/10] style: rework invalid hint error --- internal/setup/setup_test.go | 6 +++--- internal/setup/yaml.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/setup/setup_test.go b/internal/setup/setup_test.go index 8b4eb2f6..4572a7b0 100644 --- a/internal/setup/setup_test.go +++ b/internal/setup/setup_test.go @@ -1278,7 +1278,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"`, + 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{ @@ -1294,7 +1294,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "On\\nmultiple\\nlines.\\n"`, + 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{ @@ -1307,7 +1307,7 @@ var setupTests = []setupTest{{ /usr/bin/cc: `, }, - relerror: `invalid slice hint for "slice1" in slices/mydir/mypkg.yaml \(len <= 40, only printable characters and standard space\): "Seperated\\tby\\ttabs."`, + 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{ diff --git a/internal/setup/yaml.go b/internal/setup/yaml.go index cffea20b..bf484396 100644 --- a/internal/setup/yaml.go +++ b/internal/setup/yaml.go @@ -415,7 +415,7 @@ func parsePackage(baseDir, pkgName, pkgPath string, data []byte) (*Package, erro return !unicode.IsPrint(r) }) if len(yamlSlice.Hint) > 40 || hintNotPrintable { - return nil, fmt.Errorf("invalid slice hint for %q in %s (len <= 40, only printable characters and standard space): %q", sliceName, pkgPath, yamlSlice.Hint) + 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,