forked from buildpacks/pack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from WYGIN/image-index
WIP added pack manifest cli
- Loading branch information
Showing
45 changed files
with
2,794 additions
and
537 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,67 @@ | ||
package commands | ||
|
||
import ( | ||
"path/filepath" | ||
"errors" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/buildpacks/pack/internal/config" | ||
"github.com/buildpacks/pack/internal/style" | ||
"github.com/buildpacks/pack/pkg/client" | ||
"github.com/buildpacks/pack/pkg/logging" | ||
) | ||
|
||
// ManifestAddFlags define flags provided to the ManifestAdd | ||
type ManifestAddFlags struct { | ||
All bool | ||
Architecture string | ||
OS string | ||
Variant string | ||
os, osVersion, osArch, osVariant string | ||
osFeatures, features []string | ||
annotations map[string]string | ||
all bool | ||
} | ||
|
||
// ManifestAdd modifies a manifest list (Image index) and add a new image to the list of manifests. | ||
func ManifestAdd(logger logging.Logger, pack PackClient) *cobra.Command { | ||
var flags ManifestAddFlags | ||
cmd := &cobra.Command{ | ||
Use: "add [OPTIONS] <manifest-list> <manifest>", | ||
Short: "Add a new image to the manifest list", | ||
Args: cobra.MatchAll(cobra.ExactArgs(2)), | ||
Example: `pack manifest add cnbs/sample-package:hello-multiarch-universe \ | ||
cnbs/sample-package:hello-universe-riscv-linux`, | ||
Long: "manifest add modifies a manifest list (Image index) and add a new image to the list of manifests.", | ||
RunE: logError(logger, func(cmd *cobra.Command, args []string) error { | ||
if err := validateManifestAddFlags(&flags); err != nil { | ||
return err | ||
} | ||
|
||
indexName := args[0] | ||
manifest := args[1] | ||
|
||
packHome, err := config.PackHome() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
manifestDir := filepath.Join(packHome, "manifests") | ||
|
||
if err := pack.AddManifest(cmd.Context(), client.AddManifestOptions{ | ||
Index: indexName, | ||
Path: manifestDir, | ||
Manifest: manifest, | ||
All: flags.All, | ||
}); err != nil { | ||
cmd := &cobra.Command{ | ||
Use: "add [OPTIONS] <manifest-list> <manifest> [flags]", | ||
Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs), | ||
Short: "Add an image to a manifest list or image index.", | ||
Example: `pack manifest add cnbs/sample-package:hello-multiarch-universe \ | ||
cnbs/sample-package:hello-universe-riscv-linux`, | ||
Long: `manifest add modifies a manifest list (Image index) and add a new image to the list of manifests.`, | ||
RunE: logError(logger, func(cmd *cobra.Command, args []string) (err error) { | ||
if err := validateManifestAddFlags(flags); err != nil { | ||
return err | ||
} | ||
logger.Infof("Successfully added the image %s to the image index %s", style.Symbol(manifest), style.Symbol(indexName)) | ||
|
||
return nil | ||
return pack.AddManifest(cmd.Context(), args[0], args[1], client.ManifestAddOptions{ | ||
OS: flags.os, | ||
OSVersion: flags.osVersion, | ||
OSArch: flags.osArch, | ||
OSVariant: flags.osVariant, | ||
OSFeatures: flags.osFeatures, | ||
Features: flags.features, | ||
Annotations: flags.annotations, | ||
All: flags.all, | ||
}) | ||
}), | ||
} | ||
|
||
cmd.Flags().BoolVar(&flags.All, "all", false, `add all of the contents to the local list (applies only if <manifest> is an index)`) | ||
cmd.Flags().StringVar(&flags.Architecture, "arch", "", "Set the architecture") | ||
cmd.Flags().StringVar(&flags.OS, "os", "", "Set the operating system") | ||
cmd.Flags().StringVar(&flags.Variant, "variant", "", "Set the architecture variant") | ||
cmd.Flags().BoolVar(&flags.all, "all", false, "add all of the contents to the local list (applies only if <manifest> is an index)") | ||
cmd.Flags().StringVar(&flags.os, "os", "", "Set the operating system") | ||
cmd.Flags().StringVar(&flags.osArch, "arch", "", "Set the architecture") | ||
cmd.Flags().StringVar(&flags.osVariant, "variant", "", "Set the architecture variant") | ||
cmd.Flags().StringVar(&flags.osVersion, "os-version", "", "Set the os-version") | ||
cmd.Flags().StringSliceVar(&flags.osFeatures, "os-features", make([]string, 0), "Set the OSFeatures") | ||
cmd.Flags().StringSliceVar(&flags.features, "features", make([]string, 0), "Set the Features") | ||
cmd.Flags().StringToStringVar(&flags.annotations, "annotations", make(map[string]string, 0), "Set the annotations") | ||
|
||
AddHelpFlag(cmd, "add") | ||
return cmd | ||
} | ||
|
||
func validateManifestAddFlags(p *ManifestAddFlags) error { | ||
func validateManifestAddFlags(flags ManifestAddFlags) error { | ||
if (flags.os != "" && flags.osArch == "") || (flags.os == "" && flags.osArch != "") { | ||
return errors.New("'os' or 'arch' is undefined") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package commands_test | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/golang/mock/gomock" | ||
"github.com/heroku/color" | ||
"github.com/sclevine/spec" | ||
"github.com/sclevine/spec/report" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/buildpacks/pack/internal/commands" | ||
"github.com/buildpacks/pack/internal/commands/testmocks" | ||
"github.com/buildpacks/pack/pkg/logging" | ||
h "github.com/buildpacks/pack/testhelpers" | ||
) | ||
|
||
func TestManifestAddCommand(t *testing.T) { | ||
color.Disable(true) | ||
defer color.Disable(false) | ||
|
||
spec.Run(t, "Commands", testManifestAddCommand, spec.Random(), spec.Report(report.Terminal{})) | ||
} | ||
|
||
func testManifestAddCommand(t *testing.T, when spec.G, it spec.S) { | ||
var ( | ||
command *cobra.Command | ||
logger *logging.LogWithWriters | ||
outBuf bytes.Buffer | ||
mockController *gomock.Controller | ||
mockClient *testmocks.MockPackClient | ||
) | ||
|
||
it.Before(func() { | ||
logger = logging.NewLogWithWriters(&outBuf, &outBuf) | ||
mockController = gomock.NewController(t) | ||
mockClient = testmocks.NewMockPackClient(mockController) | ||
|
||
command = commands.ManifestAdd(logger, mockClient) | ||
}) | ||
it("should add image with current platform specs", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl"}) | ||
err := command.Execute() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, outBuf.String(), "") | ||
}) | ||
it("should add images with given platform", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{ | ||
"some-index", | ||
"busybox:1.36-musl", | ||
"--os", | ||
"linux", | ||
"--arch", | ||
"arm", | ||
"--variant", | ||
"v6", | ||
"--os-version", | ||
"22.04", | ||
}) | ||
err := command.Execute() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, outBuf.String(), "") | ||
}) | ||
it("should add return an error when platform's os and arch not defined", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--os", "linux"}) | ||
err := command.Execute() | ||
h.AssertEq(t, err.Error(), "'os' or 'arch' is undefined") | ||
h.AssertEq(t, outBuf.String(), "ERROR: 'os' or 'arch' is undefined\n") | ||
}) | ||
it("should add all images", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--all"}) | ||
err := command.Execute() | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, outBuf.String(), "") | ||
}) | ||
it("should return an error when features defined invalidly", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--features"}) | ||
err := command.Execute() | ||
h.AssertEq(t, err.Error(), "flag needs an argument: --features") | ||
}) | ||
it("should return an error when osFeatures defined invalidly", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--os-features"}) | ||
err := command.Execute() | ||
h.AssertEq(t, err.Error(), "flag needs an argument: --os-features") | ||
}) | ||
it("should return an error when invalid arg passed", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--urls"}) | ||
err := command.Execute() | ||
h.AssertEq(t, err.Error(), "unknown flag: --urls") | ||
}) | ||
it("should return an error when annotations defined invalidly", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"some-index", "busybox:1.36-musl", "--annotations", "some-key"}) | ||
err := command.Execute() | ||
h.AssertEq(t, err.Error(), `invalid argument "some-key" for "--annotations" flag: some-key must be formatted as key=value`) | ||
}) | ||
it("should have help flag", func() { | ||
prepareAddManifest(t, mockClient) | ||
|
||
command.SetArgs([]string{"--help"}) | ||
h.AssertNilE(t, command.Execute()) | ||
h.AssertEq(t, outBuf.String(), "") | ||
}) | ||
} | ||
|
||
func prepareAddManifest(t *testing.T, mockClient *testmocks.MockPackClient) { | ||
mockClient. | ||
EXPECT(). | ||
AddManifest( | ||
gomock.Any(), | ||
gomock.Any(), | ||
gomock.Any(), | ||
gomock.Any(), | ||
). | ||
AnyTimes(). | ||
Return(nil) | ||
} |
Oops, something went wrong.