Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions cmd/ls-main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ var (
Name: "incomplete, I",
Usage: "list incomplete uploads",
},
cli.BoolFlag{
Name: "summarize",
Usage: "display summary information (number of objects, total size)",
},
}
)

Expand Down Expand Up @@ -93,6 +97,9 @@ EXAMPLES:

8. List all contents versions if the bucket versioning is enabled.
{{.Prompt}} {{.HelpName}} --versions s3/mybucket

9. List all objects on mybucket, summarize the number of objects and total size.
{{.Prompt}} {{.HelpName}} --summarize s3/mybucket/
`,
}

Expand Down Expand Up @@ -138,7 +145,7 @@ func parseRewindFlag(rewind string) (timeRef time.Time) {
}

// checkListSyntax - validate all the passed arguments
func checkListSyntax(ctx context.Context, cliCtx *cli.Context) ([]string, bool, bool, time.Time, bool) {
func checkListSyntax(ctx context.Context, cliCtx *cli.Context) ([]string, bool, bool, bool, time.Time, bool) {
args := cliCtx.Args()
if !cliCtx.Args().Present() {
args = []string{"."}
Expand All @@ -152,13 +159,14 @@ func checkListSyntax(ctx context.Context, cliCtx *cli.Context) ([]string, bool,
isRecursive := cliCtx.Bool("recursive")
isIncomplete := cliCtx.Bool("incomplete")
withOlderVersions := cliCtx.Bool("versions")
isSummary := cliCtx.Bool("summarize")

timeRef := parseRewindFlag(cliCtx.String("rewind"))
if timeRef.IsZero() && withOlderVersions {
timeRef = time.Now().UTC()
}

return args, isRecursive, isIncomplete, timeRef, withOlderVersions
return args, isRecursive, isIncomplete, isSummary, timeRef, withOlderVersions
}

// mainList - is a handler for mc ls command
Expand All @@ -175,9 +183,10 @@ func mainList(cliCtx *cli.Context) error {
console.SetColor("Dir", color.New(color.FgCyan, color.Bold))
console.SetColor("Size", color.New(color.FgYellow))
console.SetColor("Time", color.New(color.FgGreen))
console.SetColor("Summarize", color.New(color.Bold))

// check 'ls' cliCtx arguments.
args, isRecursive, isIncomplete, timeRef, withOlderVersions := checkListSyntax(ctx, cliCtx)
args, isRecursive, isIncomplete, isSummary, timeRef, withOlderVersions := checkListSyntax(ctx, cliCtx)

var cErr error
for _, targetURL := range args {
Expand All @@ -192,8 +201,7 @@ func mainList(cliCtx *cli.Context) error {
fatalIf(err.Trace(targetURL), "Unable to initialize target `"+targetURL+"`.")
}
}

if e := doList(ctx, clnt, isRecursive, isIncomplete, timeRef, withOlderVersions); e != nil {
if e := doList(ctx, clnt, isRecursive, isIncomplete, isSummary, timeRef, withOlderVersions); e != nil {
cErr = e
}
}
Expand Down
40 changes: 36 additions & 4 deletions cmd/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,28 @@ func sortObjectVersions(ctntVersions []*ClientContent) {
})
}

// summaryMessage container for summary message structure
type summaryMessage struct {
TotalObjects int64 `json:"totalObjects"`
TotalSize int64 `json:"totalSize"`
}

// String colorized string message
func (s summaryMessage) String() string {
msg := console.Colorize("Summarize", fmt.Sprintf("\nTotal Size: %s", humanize.IBytes(uint64(s.TotalSize))))
msg += "\n" + console.Colorize("Summarize", fmt.Sprintf("Total Objects: %d", s.TotalObjects))
return msg
}

// JSON jsonified summary message
func (s summaryMessage) JSON() string {
jsonMessageBytes, e := json.MarshalIndent(s, "", "")
fatalIf(probe.NewError(e), "Unable to marshal into JSON")
return string(jsonMessageBytes)
}

// Pretty print the list of versions belonging to one object
func printObjectVersions(clntURL ClientURL, ctntVersions []*ClientContent, printAllVersions bool) {
func printObjectVersions(clntURL ClientURL, ctntVersions []*ClientContent, printAllVersions, isSummary bool) {
sortObjectVersions(ctntVersions)
msgs := generateContentMessages(clntURL, ctntVersions, printAllVersions)
for _, msg := range msgs {
Expand All @@ -181,12 +201,14 @@ func printObjectVersions(clntURL ClientURL, ctntVersions []*ClientContent, print
}

// doList - list all entities inside a folder.
func doList(ctx context.Context, clnt Client, isRecursive, isIncomplete bool, timeRef time.Time, withOlderVersions bool) error {
func doList(ctx context.Context, clnt Client, isRecursive, isIncomplete, isSummary bool, timeRef time.Time, withOlderVersions bool) error {

var (
lastPath string
perObjectVersions []*ClientContent
cErr error
totalSize int64
totalObjects int64
)

for content := range clnt.List(ctx, ListOptions{
Expand Down Expand Up @@ -224,14 +246,24 @@ func doList(ctx context.Context, clnt Client, isRecursive, isIncomplete bool, ti

if lastPath != content.URL.Path {
// Print any object in the current list before reinitializing it
printObjectVersions(clnt.GetURL(), perObjectVersions, withOlderVersions)
printObjectVersions(clnt.GetURL(), perObjectVersions, withOlderVersions, isSummary)
lastPath = content.URL.Path
perObjectVersions = []*ClientContent{}
}

perObjectVersions = append(perObjectVersions, content)
totalSize += content.Size
totalObjects++
}

printObjectVersions(clnt.GetURL(), perObjectVersions, withOlderVersions, isSummary)

if isSummary {
printMsg(summaryMessage{
TotalObjects: totalObjects,
TotalSize: totalSize,
})
}

printObjectVersions(clnt.GetURL(), perObjectVersions, withOlderVersions)
return cErr
}
2 changes: 1 addition & 1 deletion cmd/tree-main.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func mainTree(cliCtx *cli.Context) error {
}
clnt, err := newClientFromAlias(targetAlias, targetURL)
fatalIf(err.Trace(targetURL), "Unable to initialize target `"+targetURL+"`.")
if e := doList(ctx, clnt, true, false, timeRef, false); e != nil {
if e := doList(ctx, clnt, true, false, false, timeRef, false); e != nil {
cErr = e
}
}
Expand Down