Skip to content
Open
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
13 changes: 13 additions & 0 deletions cmd/ls-main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ var (
Name: "zip",
Usage: "list files inside zip archive (MinIO servers only)",
},
cli.StringFlag{
Name: "sort",
Usage: "sort by field. Only possible value for now: size",
},
}
)

Expand Down Expand Up @@ -177,6 +181,14 @@ func checkListSyntax(cliCtx *cli.Context) ([]string, doListOptions) {

timeRef := parseRewindFlag(cliCtx.String("rewind"))

sortBy := cliCtx.String("sort")
switch sortBy {
case "":
case "size":
default:
fatalIf(errInvalidArgument().Trace(args...), "Unsupported sort option '"+sortBy+"'. Only 'size' is supported.")
}

if listZip && (withVersions || !timeRef.IsZero()) {
fatalIf(errInvalidArgument().Trace(args...), "Zip file listing can only be performed on the latest version")
}
Expand All @@ -189,6 +201,7 @@ func checkListSyntax(cliCtx *cli.Context) ([]string, doListOptions) {
withVersions: withVersions,
listZip: listZip,
filter: storageClasss,
sortBy: sortBy,
}
return args, opts
}
Expand Down
67 changes: 59 additions & 8 deletions cmd/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"context"
"fmt"
"path/filepath"
"slices"
"sort"
"strings"
"time"
Expand Down Expand Up @@ -198,12 +199,10 @@ func (s summaryMessage) JSON() string {
}

// Pretty print the list of versions belonging to one object
func printObjectVersions(clntURL ClientURL, ctntVersions []*ClientContent, printAllVersions bool) {
func getObjectVersions(clntURL ClientURL, ctntVersions []*ClientContent, printAllVersions bool) []contentMessage {
sortObjectVersions(ctntVersions)
msgs := generateContentMessages(clntURL, ctntVersions, printAllVersions)
for _, msg := range msgs {
printMsg(msg)
}
return msgs
}

type doListOptions struct {
Expand All @@ -214,10 +213,11 @@ type doListOptions struct {
withVersions bool
listZip bool
filter string
sortBy string
}

// doList - list all entities inside a folder.
func doList(ctx context.Context, clnt Client, o doListOptions) error {
// Will loop over entities listed and call fn() for every object with all their versions
func loopOverObjects(ctx context.Context, clnt Client, fn func(content *[]contentMessage) error, o doListOptions) (int64, int64, error) {
var (
lastPath string
perObjectVersions []*ClientContent
Expand Down Expand Up @@ -245,9 +245,11 @@ func doList(ctx context.Context, clnt Client, o doListOptions) error {
continue
}

// Check if we have moved to a new object (or if this is another version of the last iteration's object)
if lastPath != content.URL.Path {
// Print any object in the current list before reinitializing it
printObjectVersions(clnt.GetURL(), perObjectVersions, o.withVersions)
objects := getObjectVersions(clnt.GetURL(), perObjectVersions, o.withVersions)
fn(&objects)
lastPath = content.URL.Path
perObjectVersions = []*ClientContent{}
}
Expand All @@ -257,7 +259,56 @@ func doList(ctx context.Context, clnt Client, o doListOptions) error {
totalObjects++
}

printObjectVersions(clnt.GetURL(), perObjectVersions, o.withVersions)
objects := getObjectVersions(clnt.GetURL(), perObjectVersions, o.withVersions)
fn(&objects)
return totalObjects, totalSize, cErr
}

// doList - list all entities inside a folder.
func doList(ctx context.Context, clnt Client, o doListOptions) error {
var cErr error
isAccumulating := o.sortBy == "size" // should objects be accumulated instead of printed directly
var accumulatedObjects []contentMessage

var processFn func(objects *[]contentMessage) error
if isAccumulating {
processFn = func(newObjects *[]contentMessage) error {
// Accumulate all objects for sorting later
accumulatedObjects = append(accumulatedObjects, *newObjects...)
return nil
}
} else {
processFn = func(objects *[]contentMessage) error {
// Print objects as they come
for _, obj := range *objects {
printMsg(obj)
}
return nil
}
}

totalObjects, totalSize, cErr := loopOverObjects(ctx, clnt, processFn, o)

// if isAccumulating is true, objects have been accumulated instead of printed
if isAccumulating {
// Sort if requested
switch o.sortBy {
case "size":
slices.SortFunc(accumulatedObjects, func(a, b contentMessage) int {
if a.Size < b.Size {
return -1
} else if a.Size > b.Size {
return 1
}
return 0
})
}

// Print all objects
for _, obj := range accumulatedObjects {
printMsg(obj)
}
}

if o.isSummary {
printMsg(summaryMessage{
Expand Down
Loading