diff --git a/cmd/oras/main.go b/cmd/oras/main.go index 038dfcd74..dd688c6fb 100644 --- a/cmd/oras/main.go +++ b/cmd/oras/main.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "oras.land/oras/cmd/oras/manifest" "oras.land/oras/cmd/oras/repository" + "oras.land/oras/cmd/oras/tag" ) func main() { @@ -23,6 +24,7 @@ func main() { copyCmd(), attachCmd(), manifest.Cmd(), + tag.TagCmd(), repository.Cmd(), ) if err := cmd.Execute(); err != nil { diff --git a/cmd/oras/tag/tag.go b/cmd/oras/tag/tag.go new file mode 100644 index 000000000..9ab9b1b4e --- /dev/null +++ b/cmd/oras/tag/tag.go @@ -0,0 +1,74 @@ +/* +Copyright The ORAS Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tag + +import ( + "github.com/spf13/cobra" + "oras.land/oras-go/v2" + "oras.land/oras/cmd/oras/internal/errors" + "oras.land/oras/cmd/oras/internal/option" +) + +type tagOptions struct { + option.Common + option.Remote + + srcRef string + targetRef string +} + +func TagCmd() *cobra.Command { + var opts tagOptions + cmd := &cobra.Command{ + Use: "tag name<:tag|@digest> new_tag", + Short: "[Preview] tag a manifest in the remote registry", + Long: `[Preview] tag a manifest in the remote registry + +** This command is in preview and under development. ** + +Example - Tag the manifest 'v1.0.1' in 'locahost:5000/hello' to 'v1.0.2': + oras tag localhost:5000/hello:v1.0.1 v1.0.2 + +Example - Tag the manifest with digest sha256:9463e0d192846bc994279417b50114606712d516aab45f4d8b31cbc6e46aad71 to 'v1.0.3' + oras tag localhost:5000/hello@sha256:9463e0d192846bc994279417b50114606712d516aab45f4d8b31cbc6e46aad71 v1.0.3 +`, + Args: cobra.ExactArgs(2), + PreRunE: func(cmd *cobra.Command, args []string) error { + return opts.ReadPassword() + }, + RunE: func(_ *cobra.Command, args []string) error { + opts.srcRef = args[0] + opts.targetRef = args[1] + return tagManifest(opts) + }, + } + option.ApplyFlags(&opts, cmd.Flags()) + return cmd +} + +func tagManifest(opts tagOptions) error { + ctx, _ := opts.SetLoggerLevel() + repo, err := opts.NewRepository(opts.srcRef, opts.Common) + if err != nil { + return err + } + + if repo.Reference.Reference == "" { + return errors.NewErrInvalidReference(repo.Reference) + } + + return oras.Tag(ctx, repo, opts.srcRef, opts.targetRef) +}