diff --git a/internal/commands/buildpack_new.go b/internal/commands/buildpack_new.go index 8b3c11849..6904658ce 100644 --- a/internal/commands/buildpack_new.go +++ b/internal/commands/buildpack_new.go @@ -70,7 +70,10 @@ func BuildpackNew(logger logging.Logger, creator BuildpackCreator) *cobra.Comman }) } - targets, err := target.ParseTargets(flags.Targets) + targets, warn, err := target.ParseTargets(flags.Targets) + for _,w := range warn.Messages { + logger.Warn(w) + } if err != nil { return err } diff --git a/internal/target/parse.go b/internal/target/parse.go index edd22ecf5..bb4c893b8 100644 --- a/internal/target/parse.go +++ b/internal/target/parse.go @@ -1,40 +1,46 @@ package target import ( + "fmt" "strings" "github.com/pkg/errors" "github.com/buildpacks/pack/internal/style" + "github.com/buildpacks/pack/internal/warn" "github.com/buildpacks/pack/pkg/dist" ) -func ParseTargets(t []string) (targets []dist.Target, err error) { +func ParseTargets(t []string) (targets []dist.Target, warn *warn.Warn, err error) { for _, v := range t { - target, err := ParseTarget(v) + target, w, err := ParseTarget(v) + warn.AddWarn(w) if err != nil { - return nil, err + return nil, warn, err } targets = append(targets, target) } - return targets, nil + return targets, warn, nil } -func ParseTarget(t string) (output dist.Target, err error) { - nonDistro, distros, err := getTarget(t) +func ParseTarget(t string) (output dist.Target, warn *warn.Warn, err error) { + nonDistro, distros, w, err := getTarget(t) + warn.AddWarn(w) if len(nonDistro) <= 1 && nonDistro[0] == "" { - return output, errors.Errorf("%s", style.Error("os/arch must be defined")) + warn.Add(style.Error("os/arch must be defined")) } if err != nil { - return output, err + return output, warn, err } - os, arch, variant, err := getPlatform(nonDistro) + os, arch, variant,w, err := getPlatform(nonDistro) + warn.AddWarn(w) if err != nil { - return output, err + return output, warn, err } - v, err := ParseDistros(distros) + v, w, err := ParseDistros(distros) + warn.AddWarn(w) if err != nil { - return output, err + return output, warn, err } output = dist.Target{ OS: os, @@ -42,48 +48,51 @@ func ParseTarget(t string) (output dist.Target, err error) { ArchVariant: variant, Distributions: v, } - return output, err + return output, warn, err } -func ParseDistros(distroSlice string) (distros []dist.Distribution, err error) { +func ParseDistros(distroSlice string) (distros []dist.Distribution, warn *warn.Warn, err error) { distro := strings.Split(distroSlice, ";") if l := len(distro); l == 1 && distro[0] == "" { - return nil, nil + return nil, warn, err } for _, d := range distro { - v, err, isWarn := ParseDistro(d) - if err != nil && !isWarn { - return nil, err + v, w, err := ParseDistro(d) + warn.AddWarn(w) + if err != nil { + return nil, warn, err } distros = append(distros, v) } - return distros, nil + return distros, warn, nil } -func ParseDistro(distroString string) (distro dist.Distribution, err error, isWarn bool) { +func ParseDistro(distroString string) (distro dist.Distribution, warn *warn.Warn, err error) { d := strings.Split(distroString, "@") if d[0] == "" || len(d) == 0 { - return distro, errors.Errorf("distro's versions %s cannot be specified without distro's name", style.Symbol("@"+strings.Join(d[1:], "@"))), false + return distro, warn, errors.Errorf("distro's versions %s cannot be specified without distro's name", style.Symbol("@"+strings.Join(d[1:], "@"))) } if len(d) <= 2 && d[0] == "" { - return distro, errors.Errorf("distro with name %s has no specific version!", style.Symbol(d[0])), true + warn.Add(fmt.Sprintf("distro with name %s has no specific version!", style.Symbol(d[0]))) } distro.Name = d[0] distro.Versions = d[1:] - return distro, nil, false + return distro, warn, err } -func getTarget(t string) (nonDistro []string, distros string, err error) { +func getTarget(t string) (nonDistro []string, distros string, warn *warn.Warn, err error) { target := strings.Split(t, ":") - if i, err := getSliceAt[string](target, 0); err != nil || len(target) == 0 { - return nonDistro, distros, errors.Errorf("invalid target %s, atleast one of [os][/arch][/archVariant] must be specified", t) + if i, err := getSliceAt[string](target, 0); err != nil { + return nonDistro, distros, warn, errors.Errorf("invalid target %s, atleast one of [os][/arch][/archVariant] must be specified", t) + } else if len(target) == 2 && target[0] == "" { + warn.Add(style.Warn("adding distros %s without [os][/arch][/variant]", target[2])) } else { nonDistro = strings.Split(i, "/") } if i, err := getSliceAt[string](target, 1); err == nil { distros = i } - return nonDistro, distros, err + return nonDistro, distros, warn, err } func getSliceAt[T interface{}](slice []T, index int) (value T, err error) { diff --git a/internal/target/parse_test.go b/internal/target/parse_test.go index b136f8c31..b4d51ee37 100644 --- a/internal/target/parse_test.go +++ b/internal/target/parse_test.go @@ -26,11 +26,11 @@ func testParseTargets(t *testing.T, when spec.G, it spec.S) { when("target#ParseTarget", func() { it("should throw an error when [os][/arch][/variant] is nil", func() { - _, err := target.ParseTarget(":distro@version") + _,_, err := target.ParseTarget(":distro@version") h.AssertNotNil(t, err) }) it("should parse target as expected", func() { - output, err := target.ParseTarget("linux/arm/v6") + output,_, err := target.ParseTarget("linux/arm/v6") h.AssertNil(t, err) h.AssertEq(t, output, dist.Target{ OS: "linux", @@ -41,11 +41,11 @@ func testParseTargets(t *testing.T, when spec.G, it spec.S) { }) when("target#ParseTargets", func() { it("should throw an error when atleast one target throws error", func() { - _, err := target.ParseTargets([]string{"linux/arm/v6", ":distro@version"}) + _,_, err := target.ParseTargets([]string{"linux/arm/v6", ":distro@version"}) h.AssertNotNil(t, err) }) it("should parse targets as expected", func() { - output, err := target.ParseTargets([]string{"linux/arm/v6", "linux/amd:ubuntu@22.04;debian@8.10@10.06"}) + output,_, err := target.ParseTargets([]string{"linux/arm/v6", "linux/amd:ubuntu@22.04;debian@8.10@10.06"}) h.AssertNil(t, err) h.AssertEq(t, output, []dist.Target{ { @@ -72,7 +72,7 @@ func testParseTargets(t *testing.T, when spec.G, it spec.S) { }) when("target#ParseDistro", func() { it("should parse distro as expected", func() { - output, err, _ := target.ParseDistro("ubuntu@22.04@20.08") + output, _, err := target.ParseDistro("ubuntu@22.04@20.08") h.AssertEq(t, output, dist.Distribution{ Name: "ubuntu", Versions: []string{"22.04", "20.08"}, @@ -82,7 +82,7 @@ func testParseTargets(t *testing.T, when spec.G, it spec.S) { }) when("target#ParseDistros", func() { it("should parse distros as expected", func() { - output, err := target.ParseDistros("ubuntu@22.04@20.08;debian@8.10@10.06") + output, _, err := target.ParseDistros("ubuntu@22.04@20.08;debian@8.10@10.06") h.AssertEq(t, output, []dist.Distribution{ { Name: "ubuntu", @@ -96,7 +96,7 @@ func testParseTargets(t *testing.T, when spec.G, it spec.S) { h.AssertNil(t, err) }) it("result should be nil", func() { - output, err := target.ParseDistros("") + output, _, err := target.ParseDistros("") h.AssertEq(t, output, []dist.Distribution(nil)) h.AssertNil(t, err) }) diff --git a/internal/target/platform.go b/internal/target/platform.go index 9da8c76f8..8ca085d2b 100644 --- a/internal/target/platform.go +++ b/internal/target/platform.go @@ -6,16 +6,26 @@ import ( "github.com/pkg/errors" "github.com/buildpacks/pack/internal/style" + "github.com/buildpacks/pack/internal/warn" ) -func getPlatform(t []string) (os, arch, variant string, err error) { +func getPlatform(t []string) (os, arch, variant string, warn *warn.Warn, err error) { os, _ = getSliceAt[string](t, 0) arch, _ = getSliceAt[string](t, 1) variant, _ = getSliceAt[string](t, 2) + if !supportsOS(os) && supportsVariant(arch, variant) { + warn.Add(style.Warn("unknown os %s, is this a typo", os)) + } + if supportsArch(os, arch) && !supportsVariant(arch, variant) { + warn.Add(style.Warn("unknown variant %s", variant)) + } + if supportsOS(os) && !supportsArch(os, arch) && supportsVariant(arch, variant) { + warn.Add(style.Warn("unknown arch %s", arch)) + } if !SupportsPlatform(os, arch, variant) { - return os, arch, variant, errors.Errorf("unknown target: %s", style.Symbol(strings.Join(t, "/"))) + return os, arch, variant, warn, errors.Errorf("unknown target: %s", style.Symbol(strings.Join(t, "/"))) } - return os, arch, variant, nil + return os, arch, variant, warn, err } var supportedOSArchs = map[string][]string{ diff --git a/internal/warn/warn.go b/internal/warn/warn.go new file mode 100644 index 000000000..5a6f6b18b --- /dev/null +++ b/internal/warn/warn.go @@ -0,0 +1,20 @@ +package warn + +type Warn struct { + Messages []string +} + +func(warn *Warn) Add(mesage string) *Warn { + warn.Messages = append(warn.Messages, mesage) + return warn +} + +func(warn *Warn) AddSlice(messages... string) *Warn { + warn.Messages = append(warn.Messages, messages...) + return warn +} + +func(w *Warn) AddWarn(warn *Warn) *Warn { + w.Messages = append(w.Messages, warn.Messages...) + return w +} \ No newline at end of file