diff --git a/cmd/oras/root/attach.go b/cmd/oras/root/attach.go index eb757cc94..73c19e056 100644 --- a/cmd/oras/root/attach.go +++ b/cmd/oras/root/attach.go @@ -106,7 +106,13 @@ func runAttach(cmd *cobra.Command, opts *attachOptions) error { return err } if len(opts.FileRefs) == 0 && len(annotations[option.AnnotationManifest]) == 0 { - return errors.New("no blob or manifest annotation are provided") + return &oerrors.Error{ + Err: errors.New(`neither file nor annotation provided in the command`), + Usage: fmt.Sprintf("%s %s", cmd.Parent().CommandPath(), cmd.Use), + Recommendation: `To attach to an existing artifact, please provide files + via argument or annotations via flag "--annotation". Run "oras attach -h" + for more options and examples`, + } } // prepare manifest diff --git a/test/e2e/suite/command/attach.go b/test/e2e/suite/command/attach.go index 269337b04..e70bf0eed 100644 --- a/test/e2e/suite/command/attach.go +++ b/test/e2e/suite/command/attach.go @@ -51,13 +51,13 @@ var _ = Describe("ORAS beginners:", func() { It("should fail if no file reference or manifest annotation provided for registry", func() { ORAS("attach", "--artifact-type", "oras/test", RegistryRef(ZOTHost, ImageRepo, foobar.Tag)). - ExpectFailure().MatchErrKeyWords("Error: no blob or manifest annotation are provided").Exec() + ExpectFailure().MatchErrKeyWords("Error: neither file nor annotation", "Usage:").Exec() }) It("should fail if no file reference or manifest annotation provided for OCI layout", func() { root := GinkgoT().TempDir() ORAS("attach", "--artifact-type", "oras/test", LayoutRef(root, foobar.Tag)). - ExpectFailure().MatchErrKeyWords("Error: no blob or manifest annotation are provided").Exec() + ExpectFailure().MatchErrKeyWords("Error: neither file nor annotation", "Usage:").Exec() }) It("should fail if distribution spec is unknown", func() {