mirror of
https://github.com/minio/mc.git
synced 2025-11-14 23:42:27 +03:00
Add ListOnChannel() for fs{unix,windows} and cmd-ls
This commit is contained in:
11
cmd-ls.go
11
cmd-ls.go
@@ -59,22 +59,11 @@ func doList(clnt client.Client, targetURL string) (string, error) {
|
|||||||
}
|
}
|
||||||
printItem(itemOnChannel.Item.Time, itemOnChannel.Item.Size, itemOnChannel.Item.Name)
|
printItem(itemOnChannel.Item.Time, itemOnChannel.Item.Size, itemOnChannel.Item.Name)
|
||||||
}
|
}
|
||||||
switch iodine.ToError(err).(type) {
|
|
||||||
case client.APINotImplemented:
|
|
||||||
items, err := clnt.List()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = iodine.New(err, nil)
|
err = iodine.New(err, nil)
|
||||||
msg := fmt.Sprintf("mc: listing objects for URL [%s] failed with following reason: [%s]\n", targetURL, iodine.ToError(err))
|
msg := fmt.Sprintf("mc: listing objects for URL [%s] failed with following reason: [%s]\n", targetURL, iodine.ToError(err))
|
||||||
return msg, err
|
return msg, err
|
||||||
}
|
}
|
||||||
printItems(items)
|
|
||||||
default:
|
|
||||||
if err != nil {
|
|
||||||
err = iodine.New(err, nil)
|
|
||||||
msg := fmt.Sprintf("mc: listing objects for URL [%s] failed with following reason: [%s]\n", targetURL, iodine.ToError(err))
|
|
||||||
return msg, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
cmd_test.go
21
cmd_test.go
@@ -292,13 +292,14 @@ func (s *CmdTestSuite) TestLsCmdWithBucket(c *C) {
|
|||||||
itemCh := make(chan client.ItemOnChannel)
|
itemCh := make(chan client.ItemOnChannel)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(itemCh)
|
defer close(itemCh)
|
||||||
|
for _, item := range items {
|
||||||
itemCh <- client.ItemOnChannel{
|
itemCh <- client.ItemOnChannel{
|
||||||
Item: nil,
|
Item: item,
|
||||||
Err: client.APINotImplemented{},
|
Err: nil,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
cl1.On("ListOnChannel").Return(itemCh).Once()
|
cl1.On("ListOnChannel").Return(itemCh).Once()
|
||||||
cl1.On("List").Return(items, nil).Once()
|
|
||||||
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
||||||
c.Assert(msg, Equals, "")
|
c.Assert(msg, Equals, "")
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
@@ -335,13 +336,14 @@ func (s *CmdTestSuite) TestLsCmdWithFilePath(c *C) {
|
|||||||
itemCh := make(chan client.ItemOnChannel)
|
itemCh := make(chan client.ItemOnChannel)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(itemCh)
|
defer close(itemCh)
|
||||||
|
for _, item := range items {
|
||||||
itemCh <- client.ItemOnChannel{
|
itemCh <- client.ItemOnChannel{
|
||||||
Item: nil,
|
Item: item,
|
||||||
Err: client.APINotImplemented{},
|
Err: nil,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
cl1.On("ListOnChannel").Return(itemCh).Once()
|
cl1.On("ListOnChannel").Return(itemCh).Once()
|
||||||
cl1.On("List").Return(items, nil).Once()
|
|
||||||
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
||||||
c.Assert(msg, Equals, "")
|
c.Assert(msg, Equals, "")
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
@@ -372,13 +374,14 @@ func (s *CmdTestSuite) TestLsCmdListsBuckets(c *C) {
|
|||||||
itemCh := make(chan client.ItemOnChannel)
|
itemCh := make(chan client.ItemOnChannel)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(itemCh)
|
defer close(itemCh)
|
||||||
|
for _, bucket := range buckets {
|
||||||
itemCh <- client.ItemOnChannel{
|
itemCh <- client.ItemOnChannel{
|
||||||
Item: nil,
|
Item: bucket,
|
||||||
Err: client.APINotImplemented{},
|
Err: nil,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
cl1.On("ListOnChannel").Return(itemCh).Once()
|
cl1.On("ListOnChannel").Return(itemCh).Once()
|
||||||
cl1.On("List").Return(buckets, nil).Once()
|
|
||||||
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
msg, err := doListCmd(manager, sourceURL, sourceConfig, false)
|
||||||
c.Assert(msg, Equals, "")
|
c.Assert(msg, Equals, "")
|
||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@@ -78,6 +79,7 @@ type Item struct {
|
|||||||
Name string
|
Name string
|
||||||
Time time.Time
|
Time time.Time
|
||||||
Size int64
|
Size int64
|
||||||
|
FileType os.FileMode
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidBucketName reports whether bucket is a valid bucket name, per Amazon's naming restrictions.
|
// IsValidBucketName reports whether bucket is a valid bucket name, per Amazon's naming restrictions.
|
||||||
@@ -97,18 +99,6 @@ func IsValidBucketName(bucket string) bool {
|
|||||||
return match
|
return match
|
||||||
}
|
}
|
||||||
|
|
||||||
// BySize implements sort.Interface for []Item based on the Size field.
|
|
||||||
type BySize []*Item
|
|
||||||
|
|
||||||
// Len -
|
|
||||||
func (a BySize) Len() int { return len(a) }
|
|
||||||
|
|
||||||
// Swap -
|
|
||||||
func (a BySize) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
||||||
|
|
||||||
// Less -
|
|
||||||
func (a BySize) Less(i, j int) bool { return a[i].Size < a[j].Size }
|
|
||||||
|
|
||||||
// IsValidObject - verify object name in accordance with
|
// IsValidObject - verify object name in accordance with
|
||||||
// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
|
// - http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
|
||||||
func IsValidObject(object string) bool {
|
func IsValidObject(object string) bool {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -118,9 +117,31 @@ func (f *fsClient) ListOnChannel() <-chan client.ItemOnChannel {
|
|||||||
|
|
||||||
func (f *fsClient) listInGoroutine(itemCh chan client.ItemOnChannel) {
|
func (f *fsClient) listInGoroutine(itemCh chan client.ItemOnChannel) {
|
||||||
defer close(itemCh)
|
defer close(itemCh)
|
||||||
|
visitFS := func(fp string, fi os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
if os.IsPermission(err) { // skip inaccessible files
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err // fatal
|
||||||
|
}
|
||||||
|
item := &client.Item{
|
||||||
|
Name: fp,
|
||||||
|
Time: fi.ModTime(),
|
||||||
|
Size: fi.Size(),
|
||||||
|
FileType: fi.Mode(),
|
||||||
|
}
|
||||||
|
itemCh <- client.ItemOnChannel{
|
||||||
|
Item: item,
|
||||||
|
Err: nil,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := filepath.Walk(f.path, visitFS)
|
||||||
|
if err != nil {
|
||||||
itemCh <- client.ItemOnChannel{
|
itemCh <- client.ItemOnChannel{
|
||||||
Item: nil,
|
Item: nil,
|
||||||
Err: iodine.New(client.APINotImplemented{API: "ListOnChannel"}, nil),
|
Err: iodine.New(err, nil),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +167,6 @@ func (f *fsClient) List() (items []*client.Item, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, iodine.New(err, nil)
|
return nil, iodine.New(err, nil)
|
||||||
}
|
}
|
||||||
sort.Sort(client.BySize(items))
|
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package fs
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -133,9 +132,31 @@ func (f *fsClient) ListOnChannel() <-chan client.ItemOnChannel {
|
|||||||
|
|
||||||
func (f *fsClient) listInGoroutine(itemCh chan client.ItemOnChannel) {
|
func (f *fsClient) listInGoroutine(itemCh chan client.ItemOnChannel) {
|
||||||
defer close(itemCh)
|
defer close(itemCh)
|
||||||
|
visitFS := func(fp string, fi os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
if os.IsPermission(err) { // skip inaccessible files
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err // fatal
|
||||||
|
}
|
||||||
|
item := &client.Item{
|
||||||
|
Name: fp,
|
||||||
|
Time: fi.ModTime(),
|
||||||
|
Size: fi.Size(),
|
||||||
|
FileType: fi.Mode(),
|
||||||
|
}
|
||||||
|
itemCh <- client.ItemOnChannel{
|
||||||
|
Item: item,
|
||||||
|
Err: nil,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := filepath.Walk(f.path, visitFS)
|
||||||
|
if err != nil {
|
||||||
itemCh <- client.ItemOnChannel{
|
itemCh <- client.ItemOnChannel{
|
||||||
Item: nil,
|
Item: nil,
|
||||||
Err: iodine.New(client.APINotImplemented{API: "ListOnChannel"}, nil),
|
Err: iodine.New(err, nil),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +187,6 @@ func (f *fsClient) List() (items []*client.Item, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, iodine.New(err, nil)
|
return nil, iodine.New(err, nil)
|
||||||
}
|
}
|
||||||
sort.Sort(client.BySize(items))
|
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user