diff --git a/Makefile b/Makefile index 05db445..2dbe4cd 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,6 @@ build: ## Build binary env GO111MODULE=on GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(S3HUB) cmd/s3hub/main.go env GO111MODULE=on GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(SPARE) cmd/spare/main.go - clean: ## Clean project -rm -rf $(S3HUB) $(SPARE) cover.out cover.html @@ -42,6 +41,7 @@ generate: ## Generate code from templates gif: docker ## Generate gif image vhs < doc/img/vhs/s3hub-mb.tape vhs < doc/img/vhs/s3hub-ls.tape + vhs < doc/img/vhs/s3hub-ls.tape vhs < doc/img/vhs/s3hub-rm-all.tape docker: ## Start docker (localstack) diff --git a/app/domain/model/s3.go b/app/domain/model/s3.go index 66f5d77..71a6324 100644 --- a/app/domain/model/s3.go +++ b/app/domain/model/s3.go @@ -322,6 +322,16 @@ func (s S3ObjectIdentifierSets) Len() int { return len(s) } +// Less defines the ordering of S3ObjectIdentifier instances. +func (s S3ObjectIdentifierSets) Less(i, j int) bool { + return s[i].S3Key < s[j].S3Key +} + +// Swap swaps the elements with indexes i and j. +func (s S3ObjectIdentifierSets) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + // ToS3ObjectIdentifiers converts the S3ObjectSets to the ObjectIdentifiers. func (s S3ObjectIdentifierSets) ToS3ObjectIdentifiers() []types.ObjectIdentifier { ids := make([]types.ObjectIdentifier, 0, s.Len()) diff --git a/cmd/subcmd/s3hub/ls.go b/cmd/subcmd/s3hub/ls.go index 0b84d7d..10d5683 100644 --- a/cmd/subcmd/s3hub/ls.go +++ b/cmd/subcmd/s3hub/ls.go @@ -1,6 +1,10 @@ package s3hub import ( + "errors" + "fmt" + "sort" + "github.com/fatih/color" "github.com/nao1215/rainbow/app/domain/model" "github.com/nao1215/rainbow/app/usecase" @@ -30,12 +34,29 @@ type lsCmd struct { *s3hub // bucket is the name of the bucket. bucket model.Bucket + // lsMode is the mode for listing. + mode lsMode } +// lsMode is the mode for listing. +type lsMode int + +const ( + // lsModeBucket is the mode for listing buckets. + lsModeBucket lsMode = 0 + // lsModeObject is the mode for listing objects. + lsModeObject lsMode = 1 +) + // Parse parses command line arguments. func (l *lsCmd) Parse(cmd *cobra.Command, args []string) error { if len(args) >= 1 { - l.bucket = model.Bucket(args[0]) + l.bucket = model.NewBucketWithoutProtocol(args[0]) + } + + if !l.bucket.Empty() { + l.mode = lsModeObject + l.bucket, _ = l.bucket.Split() } l.s3hub = newS3hub() @@ -43,6 +64,18 @@ func (l *lsCmd) Parse(cmd *cobra.Command, args []string) error { } func (l *lsCmd) Do() error { + switch l.mode { + case lsModeBucket: + return l.printBucket() + case lsModeObject: + return l.printObject() + default: + return errors.New("invalid mode: please report this bug: https://github.com/nao1215/rainbow") + } +} + +// printBucket prints buckets. +func (l *lsCmd) printBucket() error { out, err := l.s3hub.S3BucketLister.ListS3Buckets(l.ctx, &usecase.S3BucketListerInput{}) if err != nil { return err @@ -61,3 +94,37 @@ func (l *lsCmd) Do() error { } return nil } + +// printObject prints objects. +func (l *lsCmd) printObject() error { + listBuckets, err := l.s3hub.S3BucketLister.ListS3Buckets(l.ctx, &usecase.S3BucketListerInput{}) + if err != nil { + return err + } + if !listBuckets.Buckets.Contains(l.bucket) { + return fmt.Errorf("bucket not found: %s", color.YellowString("%s", l.bucket)) + } + + listS3Objects, err := l.s3hub.S3BucketObjectsLister.ListS3BucketObjects(l.ctx, &usecase.S3BucketObjectsListerInput{ + Bucket: l.bucket, + }) + if err != nil { + return err + } + + l.printf("[S3Objects (profile=%s)]\n", l.profile.String()) + if len(listS3Objects.Objects) == 0 { + l.printf(" No S3 Objects\n") + return nil + } + + sort.Sort(listS3Objects.Objects) + for _, o := range listS3Objects.Objects { + if o.VersionID == "" { + l.printf(" %s/%s\n", l.bucket, o.S3Key) + continue + } + l.printf(" %s/%s (version id=%s)\n", l.bucket, o.S3Key, o.VersionID) + } + return nil +} diff --git a/doc/img/s3hub-ls-objects.gif b/doc/img/s3hub-ls-objects.gif new file mode 100644 index 0000000..ecabc5b Binary files /dev/null and b/doc/img/s3hub-ls-objects.gif differ diff --git a/doc/img/vhs/s3hub-ls-objects.tape b/doc/img/vhs/s3hub-ls-objects.tape new file mode 100644 index 0000000..fe04120 --- /dev/null +++ b/doc/img/vhs/s3hub-ls-objects.tape @@ -0,0 +1,69 @@ +# VHS documentation +# +# Output: +# Output .gif Create a GIF output at the given +# Output .mp4 Create an MP4 output at the given +# Output .webm Create a WebM output at the given +# +# Require: +# Require Ensure a program is on the $PATH to proceed +# +# Settings: +# Set FontSize Set the font size of the terminal +# Set FontFamily Set the font family of the terminal +# Set Height Set the height of the terminal +# Set Width Set the width of the terminal +# Set LetterSpacing Set the font letter spacing (tracking) +# Set LineHeight Set the font line height +# Set LoopOffset % Set the starting frame offset for the GIF loop +# Set Theme Set the theme of the terminal +# Set Padding Set the padding of the terminal +# Set Framerate Set the framerate of the recording +# Set PlaybackSpeed Set the playback speed of the recording +# Set MarginFill Set the file or color the margin will be filled with. +# Set Margin Set the size of the margin. Has no effect if MarginFill isn't set. +# Set BorderRadius Set terminal border radius, in pixels. +# Set WindowBar Set window bar type. (one of: Rings, RingsRight, Colorful, ColorfulRight) +# Set WindowBarSize Set window bar size, in pixels. Default is 40. +# Set TypingSpeed