From 6b8a9b4e800d8acc3a167380bb807db98a5d6f6d Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Mon, 28 Aug 2023 18:27:28 +0800 Subject: [PATCH 1/6] feat: support upload multiple files by object put command --- cmd/cmd_object.go | 190 +++++++++++++++++++++++++++++++++++----------- cmd/utils.go | 13 ++++ 2 files changed, 158 insertions(+), 45 deletions(-) diff --git a/cmd/cmd_object.go b/cmd/cmd_object.go index 1e68bc9..f62a0dc 100644 --- a/cmd/cmd_object.go +++ b/cmd/cmd_object.go @@ -25,14 +25,17 @@ func cmdPutObj() *cli.Command { Name: "put", Action: putObject, Usage: "create object on chain and upload payload of object to SP", - ArgsUsage: "[filePath] OBJECT-URL", + ArgsUsage: "[filePath]... OBJECT-URL", Description: ` Send createObject txn to chain and upload the payload of object to the storage provider. -The command need to pass the file path inorder to compute hash roots on client +The command need to pass the file path inorder to compute hash roots on client. +Note that the uploading with recursive flag only support folder. Examples: # create object and upload file to storage provider, the corresponding object is gnfd-object -$ gnfd-cmd object put file.txt gnfd://gnfd-bucket/gnfd-object`, +$ gnfd-cmd object put file.txt gnfd://gnfd-bucket/gnfd-object, +# upload the files inside the folders +$ gnfd-cmd object put --recursive folderName gnfd://bucket-name`, Flags: []cli.Flag{ &cli.StringFlag{ Name: secondarySPFlag, @@ -65,6 +68,11 @@ $ gnfd-cmd object put file.txt gnfd://gnfd-bucket/gnfd-object`, "a file in multiple parts, where each part is uploaded separately.This allows the upload to be resumed from " + "where it left off in case of interruptions or failures, rather than starting the entire upload process from the beginning.", }, + &cli.BoolFlag{ + Name: recursiveFlag, + Value: false, + Usage: "performed on all files or objects under the specified directory or prefix in a recursive way", + }, }, } } @@ -224,71 +232,154 @@ $ gnfd-cmd object mirror --destChainId 97 --bucketName yourBucketName --objectNa // putObject upload the payload of file, finish the third stage of putObject func putObject(ctx *cli.Context) error { - if ctx.NArg() != 1 && ctx.NArg() != 2 { + if ctx.NArg() < 1 { return toCmdErr(fmt.Errorf("args number error")) } var ( - uploadFolder = false + isUploadSingleFolder bool bucketName, objectName, filePath string - fileReader io.Reader objectSize int64 err error - exists bool urlInfo string ) + gnfdClient, err := NewClient(ctx, false) + if err != nil { + return err + } + + supportRecursive := ctx.Bool(recursiveFlag) + if ctx.NArg() == 1 { + // upload an empty folder urlInfo = ctx.Args().Get(0) bucketName, objectName, err = getObjAndBucketNames(urlInfo) if err != nil { return toCmdErr(err) } if strings.HasSuffix(objectName, "/") { - uploadFolder = true + isUploadSingleFolder = true } else { return toCmdErr(errors.New("no file path to upload, if you need create a folder, the folder name should be end with /")) } + + if err = uploadFile(bucketName, objectName, filePath, urlInfo, ctx, gnfdClient, isUploadSingleFolder, true, 0); err != nil { + return toCmdErr(err) + } + } else { - // read the local file payload - filePath = ctx.Args().Get(0) - exists, objectSize, err = pathExists(filePath) - if err != nil { - return err + // upload files in folder in a recursive way + if supportRecursive { + urlInfo = ctx.Args().Get(1) + if err = uploadFolder(urlInfo, ctx, gnfdClient); err != nil { + return toCmdErr(err) + } + return nil } - if !exists { - return fmt.Errorf("upload file not exists") - } else if objectSize > int64(maxFileSize) { - return fmt.Errorf("upload file larger than 10G ") + + filePathList := make([]string, 0) + argNum := ctx.Args().Len() + for i := 0; i < argNum-1; i++ { + filePathList = append(filePathList, ctx.Args().Get(i)) } - // Open the referenced file. - file, err := os.Open(filePath) - if err != nil { - return err + var needUploadMutiFiles bool + if len(filePathList) > 1 { + needUploadMutiFiles = true } - defer file.Close() - fileReader = file - urlInfo = ctx.Args().Get(1) - bucketName, objectName, err = getObjAndBucketNames(urlInfo) - if err != nil { + // upload multiple files + if needUploadMutiFiles { + urlInfo = ctx.Args().Get(argNum - 1) bucketName = ParseBucket(urlInfo) if bucketName == "" { return toCmdErr(errors.New("fail to parse bucket name")) } - // if the object name has not been set, set the file name as object name - objectName = filepath.Base(filePath) + + for idx, fileName := range filePathList { + nameList := strings.Split(fileName, "/") + objectName = nameList[len(nameList)-1] + objectSize, err = parseFileByArg(ctx, idx) + if err != nil { + return toCmdErr(err) + } + + if err = uploadFile(bucketName, objectName, fileName, urlInfo, ctx, gnfdClient, false, false, objectSize); err != nil { + fmt.Println("upload object:", objectName, "err", err) + } + } + } else { + // upload single file + objectSize, err = parseFileByArg(ctx, 0) + if err != nil { + return toCmdErr(err) + } + urlInfo = ctx.Args().Get(1) + bucketName, objectName, err = getObjAndBucketNames(urlInfo) + if err != nil { + bucketName = ParseBucket(urlInfo) + if bucketName == "" { + return toCmdErr(errors.New("fail to parse bucket name")) + } + // if the object name has not been set, set the file name as object name + objectName = filepath.Base(filePathList[0]) + } + if err = uploadFile(bucketName, objectName, filePathList[0], urlInfo, ctx, gnfdClient, false, true, objectSize); err != nil { + return toCmdErr(err) + } } } - gnfdClient, err := NewClient(ctx, false) + return nil +} + +// uploadFolder upload folder and the files inside to bucket in a recursive way +func uploadFolder(urlInfo string, ctx *cli.Context, + gnfdClient client.Client) error { + // upload folder with recursive flag + bucketName := ParseBucket(urlInfo) + if bucketName == "" { + return errors.New("fail to parse bucket name") + } + + folderName := ctx.Args().Get(0) + fileInfo, err := os.Stat(folderName) if err != nil { return err } - c, cancelCreateBucket := context.WithCancel(globalContext) - defer cancelCreateBucket() + if !fileInfo.IsDir() { + return errors.New("failed to parse folder path with recursive flag") + } + fileInfos := make([]os.FileInfo, 0) + filePaths := make([]string, 0) + listFolderErr := filepath.Walk(folderName, func(path string, info os.FileInfo, err error) error { + if !info.IsDir() { + fileInfos = append(fileInfos, info) + filePaths = append(filePaths, path) + } + return nil + }) + + if listFolderErr != nil { + return listFolderErr + } + // upload folder + for id, info := range fileInfos { + // pathList := strings.Split(info.Name(), "/") + objectName := filePaths[id] + if uploadErr := uploadFile(bucketName, objectName, filePaths[id], urlInfo, ctx, gnfdClient, false, false, info.Size()); uploadErr != nil { + fmt.Printf("failed to upload object: %s, error:%v \n", objectName, uploadErr) + } + } + + return nil +} + +func uploadFile(bucketName, objectName, filePath, urlInfo string, ctx *cli.Context, + gnfdClient client.Client, uploadSigleFolder, printTxnHash bool, objectSize int64) error { + fmt.Println("uploading file path:", filePath, "object name:", objectName) contentType := ctx.String(contentTypeFlag) secondarySPAccs := ctx.String(secondarySPFlag) @@ -319,23 +410,34 @@ func putObject(ctx *cli.Context) error { opts.SecondarySPAccs = addrList } - _, err = gnfdClient.HeadObject(c, bucketName, objectName) + c, cancelPutObject := context.WithCancel(globalContext) + defer cancelPutObject() + + _, err := gnfdClient.HeadObject(c, bucketName, objectName) var txnHash string // if err==nil, object exist on chain, no need to createObject if err != nil { - if uploadFolder { + if uploadSigleFolder { txnHash, err = gnfdClient.CreateFolder(c, bucketName, objectName, opts) if err != nil { return toCmdErr(err) } } else { - txnHash, err = gnfdClient.CreateObject(c, bucketName, objectName, fileReader, opts) + // Open the referenced file. + file, err := os.Open(filePath) + if err != nil { + return err + } + defer file.Close() + txnHash, err = gnfdClient.CreateObject(c, bucketName, objectName, file, opts) if err != nil { return toCmdErr(err) } } - fmt.Printf("object %s created on chain \n", objectName) - fmt.Println("transaction hash: ", txnHash) + if printTxnHash { + fmt.Printf("object %s created on chain \n", objectName) + fmt.Println("transaction hash: ", txnHash) + } } else { fmt.Printf("object %s already exist \n", objectName) } @@ -361,8 +463,7 @@ func putObject(ctx *cli.Context) error { if err = gnfdClient.PutObject(c, bucketName, objectName, objectSize, reader, opt); err != nil { - fmt.Println("put object fail:", err.Error()) - return nil + return toCmdErr(err) } // Check if object is sealed @@ -374,9 +475,9 @@ func putObject(ctx *cli.Context) error { case <-timeout: return toCmdErr(errors.New("object not sealed after 15 seconds")) case <-ticker.C: - headObjOutput, err := gnfdClient.HeadObject(c, bucketName, objectName) - if err != nil { - return err + headObjOutput, queryErr := gnfdClient.HeadObject(c, bucketName, objectName) + if queryErr != nil { + return queryErr } if headObjOutput.ObjectInfo.GetObjectStatus().String() == "OBJECT_STATUS_SEALED" { @@ -386,7 +487,6 @@ func putObject(ctx *cli.Context) error { } } } - } // getObject download the object payload from sp @@ -553,8 +653,8 @@ func listObjectByPage(cli client.Client, c context.Context, bucketName, prefixNa if err != nil { return toCmdErr(err) } - printListResult(listResult) - if listResult.IsTruncated { + + if !listResult.IsTruncated { break } @@ -665,7 +765,7 @@ func pathExists(path string) (bool, int64, error) { if err == nil { if stat.IsDir() { - return false, 0, fmt.Errorf("not support upload dir") + return false, 0, fmt.Errorf("not support upload dir without recursive flag") } return true, stat.Size(), nil } diff --git a/cmd/utils.go b/cmd/utils.go index 0527b84..c0322e3 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -523,3 +523,16 @@ func getUserAddress(ctx *cli.Context) (string, error) { } return userAddress, nil } + +func parseFileByArg(ctx *cli.Context, argIndex int) (int64, error) { + exists, objectSize, err := pathExists(ctx.Args().Get(argIndex)) + if err != nil { + return 0, err + } + if !exists { + return 0, fmt.Errorf("upload file not exists") + } else if objectSize > int64(maxFileSize) { + return 0, fmt.Errorf("upload file larger than 10G ") + } + return objectSize, nil +} From 7a0207acc0c80ca629b38049603f56786a4ff546 Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Mon, 28 Aug 2023 18:50:46 +0800 Subject: [PATCH 2/6] fix: fix list object --- README.md | 22 ++++++++++++++++++++++ cmd/cmd_object.go | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a36580..7a000bb 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,28 @@ gnfd-cmd object get gnfd://gnfd-bucket/gnfd-object file-path The filepath can be a specific file path, a directory path, or not set at all. If not set, the command will download the content to a file with the same name as the object name in the current directory. If it is set as a directory, the command will download the object file into the directory. +(3) create empty folder + +Please note that the object name corresponding to the folder needs to start with "/" as suffix +``` +gnfd-cmd object put gnfd://gnfd-bucket/folder/ +``` + +(4) upload local folder + +To upload a local folder (including all the files in it), you can use --recursive flag and specify the local folder path +``` +gnfd-cmd object put --recursive local-folder-path gnfd://gnfd-bucket/ +``` + +(5) upload multiple files + +To upload multiple files by one command, you can specify all the file paths that need to be uploaded in gnfd://bucket-name +``` +gnfd-cmd object put filepath1 filepath2 ... gnfd://gnfd-bucket/ +``` + + #### Group Operations The group commands is used to create group, update group members, delete group and query group info. diff --git a/cmd/cmd_object.go b/cmd/cmd_object.go index f62a0dc..ca8a9bb 100644 --- a/cmd/cmd_object.go +++ b/cmd/cmd_object.go @@ -627,7 +627,6 @@ func listObjects(ctx *cli.Context) error { } return nil - } func listObjectByPage(cli client.Client, c context.Context, bucketName, prefixName string, isRecursive bool) error { @@ -654,6 +653,7 @@ func listObjectByPage(cli client.Client, c context.Context, bucketName, prefixNa return toCmdErr(err) } + printListResult(listResult) if !listResult.IsTruncated { break } From 7f56a6ba398ab2e47c0641cc3aca8ed9acef452f Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Mon, 28 Aug 2023 18:51:13 +0800 Subject: [PATCH 3/6] fix: upadte readme with new API --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7a000bb..652246a 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,11 @@ gnfd-cmd bucket ls // list objects of the bucket gnfd-cmd object ls gnfd://gnfd-bucket +// list objects of the bucket in a recursive way +gnfd-cmd object ls --recursive gnfd://gnfd-bucket + +// list the objects by prefix +gnfd-cmd object ls --recursive gnfd://gnfd-bucket/prefixName ``` #### Delete Operations ``` From 771e1b119b63f2513638d075fcfe3c9715979e75 Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Tue, 29 Aug 2023 17:39:24 +0800 Subject: [PATCH 4/6] fix: update dependency of sdk to v0.2.4 --- cmd/cmd_object.go | 1 - cmd/utils.go | 2 +- go.mod | 16 ++++++++-------- go.sum | 36 +++++++++++++++++------------------- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/cmd/cmd_object.go b/cmd/cmd_object.go index ca8a9bb..4ebeaee 100644 --- a/cmd/cmd_object.go +++ b/cmd/cmd_object.go @@ -379,7 +379,6 @@ func uploadFolder(urlInfo string, ctx *cli.Context, func uploadFile(bucketName, objectName, filePath, urlInfo string, ctx *cli.Context, gnfdClient client.Client, uploadSigleFolder, printTxnHash bool, objectSize int64) error { - fmt.Println("uploading file path:", filePath, "object name:", objectName) contentType := ctx.String(contentTypeFlag) secondarySPAccs := ctx.String(secondarySPFlag) diff --git a/cmd/utils.go b/cmd/utils.go index c0322e3..9ed5848 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -28,7 +28,7 @@ import ( ) const ( - Version = "v0.1.0-alpha.2" + Version = "v0.1.0" maxFileSize = 10 * 1024 * 1024 * 1024 publicReadType = "public-read" privateType = "private" diff --git a/go.mod b/go.mod index 83383a0..7db9d69 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,10 @@ go 1.20 require ( cosmossdk.io/math v1.0.1 github.com/BurntSushi/toml v1.3.2 - github.com/bnb-chain/greenfield v0.2.4-alpha.2 - github.com/bnb-chain/greenfield-go-sdk v0.2.4-alpha.3 + github.com/bnb-chain/greenfield v0.2.4 + github.com/bnb-chain/greenfield-go-sdk v0.2.4 github.com/cosmos/cosmos-sdk v0.47.3 - github.com/ethereum/go-ethereum v1.10.22 + github.com/ethereum/go-ethereum v1.10.26 github.com/urfave/cli/v2 v2.10.2 golang.org/x/term v0.9.0 ) @@ -88,14 +88,14 @@ require ( github.com/linxGnu/grocksdb v1.7.16 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -119,7 +119,7 @@ require ( github.com/spf13/viper v1.15.0 // indirect github.com/stretchr/testify v1.8.4 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 // indirect + github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect @@ -150,10 +150,10 @@ replace ( cosmossdk.io/api => github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210 cosmossdk.io/math => github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210 github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.23.0 - github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.3-alpha.1 + github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-cometbft v0.0.3 github.com/cometbft/cometbft-db => github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4-alpha.2 + github.com/cosmos/cosmos-sdk => github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4 github.com/cosmos/iavl => github.com/bnb-chain/greenfield-iavl v0.20.1 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/go.sum b/go.sum index a3c2f9d..da13678 100644 --- a/go.sum +++ b/go.sum @@ -154,24 +154,22 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/bnb-chain/greenfield v0.2.4-alpha.2 h1:l/GkTKN3M6TnxC3Ak9Tm8Yd/6qW9bxSMc+/pUGvLgTU= -github.com/bnb-chain/greenfield v0.2.4-alpha.2/go.mod h1:rqUmxfdTvIwqa56H9QASdKQ7zrytbEY3zLMQAl2FMiU= -github.com/bnb-chain/greenfield-cometbft v0.0.3-alpha.1 h1:nCLXxYdkDIh5bQMxtb14TBwiut/xq2e0DqPVTLy9vtI= -github.com/bnb-chain/greenfield-cometbft v0.0.3-alpha.1/go.mod h1:3nGT4Z9fHwgRlBY/rofn0rSarnIcNbuhz/eq0XlLlkg= +github.com/bnb-chain/greenfield v0.2.4 h1:3knYY3KbEYoysnTAp3+oh2YyeWG2Au0kXYSdZHyzV+k= +github.com/bnb-chain/greenfield v0.2.4/go.mod h1:7FzduaDVOXpbiWMo0JoH8odXgwEfGJ3ug20BIgPDVKE= +github.com/bnb-chain/greenfield-cometbft v0.0.3 h1:tv8NMy3bzX/1urqXGQIIAZSLy83loiI+dG0VKeyh1CY= +github.com/bnb-chain/greenfield-cometbft v0.0.3/go.mod h1:f35mk/r5ab6yvzlqEWZt68LfUje68sYgMpVlt2CUYMk= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1 h1:XcWulGacHVRiSCx90Q8Y//ajOrLNBQWR/KDB89dy3cU= github.com/bnb-chain/greenfield-cometbft-db v0.8.1-alpha.1/go.mod h1:ey1CiK4bYo1RBNJLRiVbYr5CMdSxci9S/AZRINLtppI= github.com/bnb-chain/greenfield-common/go v0.0.0-20230809025353-fd0519705054 h1:74pdUdHjo9QNgjSifIgzbDcloqFJ2I+qo715tOXy/oM= github.com/bnb-chain/greenfield-common/go v0.0.0-20230809025353-fd0519705054/go.mod h1:GEjCahULmz99qx5k8WGWa7cTXIUjoNMNW+J92I+kTWg= -github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4-alpha.2 h1:mCojTDXd//s34SiHqRolG7saZSG9YHQ9WzPFF8rL4Zo= -github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4-alpha.2/go.mod h1:2jk2ijERIAv8wxQ/IJSmzQKazCnR6YGvICk4O1YrT9M= +github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4 h1:09ST+MTEAyjyBSc4ZjZzHxpNLMnIIkZ518jJVRtrKFc= +github.com/bnb-chain/greenfield-cosmos-sdk v0.2.4/go.mod h1:y3hDhQhil5hMIhwBTpu07RZBF30ZITkoE+GHhVZChtY= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210 h1:GHPbV2bC+gmuO6/sG0Tm8oGal3KKSRlyE+zPscDjlA8= github.com/bnb-chain/greenfield-cosmos-sdk/api v0.0.0-20230816082903-b48770f5e210/go.mod h1:vhsZxXE9tYJeYB5JR4hPhd6Pc/uPf7j1T8IJ7p9FdeM= github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210 h1:FLVOn4+OVbsKi2+YJX5kmD27/4dRu4FW7xCXFhzDO5s= github.com/bnb-chain/greenfield-cosmos-sdk/math v0.0.0-20230816082903-b48770f5e210/go.mod h1:An0MllWJY6PxibUpnwGk8jOm+a/qIxlKmL5Zyp9NnaM= -github.com/bnb-chain/greenfield-go-sdk v0.2.4-alpha.2 h1:lxrcKghW/Qz8mRvLti5R6/VGTpl4O8hd+xhtnr5EL58= -github.com/bnb-chain/greenfield-go-sdk v0.2.4-alpha.2/go.mod h1:PO+JKqXkzk2hjC8UDVFExGkscCwmOdAIzNTnQiGrUBU= -github.com/bnb-chain/greenfield-go-sdk v0.2.4-alpha.3 h1:Fr4MV809IE9IjaDSNS0bMSSBqCbq6pAuBVRpY6kKpRw= -github.com/bnb-chain/greenfield-go-sdk v0.2.4-alpha.3/go.mod h1:PO+JKqXkzk2hjC8UDVFExGkscCwmOdAIzNTnQiGrUBU= +github.com/bnb-chain/greenfield-go-sdk v0.2.4 h1:cYts8MZ8+jiW/+3uTRJAT7OKbex5YnViDebizLYcqAs= +github.com/bnb-chain/greenfield-go-sdk v0.2.4/go.mod h1:nd5oQUIuWMi3U0KJRbmM1dJClKLQed5l5GnooiRcFxw= github.com/bnb-chain/greenfield-iavl v0.20.1 h1:y3L64GU99otNp27/xLVBTDbv4eroR6CzoYz0rbaVotM= github.com/bnb-chain/greenfield-iavl v0.20.1/go.mod h1:oLksTs8dfh7DYIKBro7hbRQ+ewls7ghJ27pIXlbEXyI= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= @@ -330,8 +328,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= -github.com/ethereum/go-ethereum v1.10.22 h1:HbEgsDo1YTGIf4KB/NNpn+XH+PiNJXUZ9ksRxiqWyMc= -github.com/ethereum/go-ethereum v1.10.22/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= +github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqBmytw72s= +github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -900,8 +898,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -1066,8 +1064,8 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= -github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= @@ -1273,14 +1271,14 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 h1:m+8fKfQwCAy1QjzINvKe/pYtLjo2dl59x2w9YSEJxuY= -github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= From c11cb617044e8ab93d21648b79382bdae001862d Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Wed, 30 Aug 2023 11:55:13 +0800 Subject: [PATCH 5/6] fix: fix readme and add change log --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 652246a..858b703 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To obtain the latest release, please visit the following URL: https://github.com git clone https://github.com/bnb-chain/greenfield-cmd.git cd greenfield-cmd # Find the latest release here: https://github.com/bnb-chain/greenfield-cmd/releases -git checkout -b branch-name v0.0.9 +git checkout -b branch-name v0.1.0 make build cd build ./gnfd-cmd -h @@ -182,7 +182,7 @@ If not set, the command will download the content to a file with the same name a (3) create empty folder -Please note that the object name corresponding to the folder needs to start with "/" as suffix +Please note that the object name corresponding to the folder needs to end with "/" as suffix ``` gnfd-cmd object put gnfd://gnfd-bucket/folder/ ``` @@ -191,14 +191,16 @@ gnfd-cmd object put gnfd://gnfd-bucket/folder/ To upload a local folder (including all the files in it), you can use --recursive flag and specify the local folder path ``` -gnfd-cmd object put --recursive local-folder-path gnfd://gnfd-bucket/ +gnfd-cmd object put --recursive local-folder-path gnfd://gnfd-bucket ``` (5) upload multiple files -To upload multiple files by one command, you can specify all the file paths that need to be uploaded in gnfd://bucket-name +To upload multiple files by one command, you can specify all the file paths that need to be uploaded one by one. +The files will be uploaded to the same bucket. + ``` -gnfd-cmd object put filepath1 filepath2 ... gnfd://gnfd-bucket/ +gnfd-cmd object put filepath1 filepath2 ... gnfd://gnfd-bucket ``` From 994774b6ef4025c344990c8a33f295575ea7f7f7 Mon Sep 17 00:00:00 2001 From: flywukong <2229306838@qq.com> Date: Wed, 30 Aug 2023 12:59:56 +0800 Subject: [PATCH 6/6] fix: fix policy ls cmd --- CHANGELOG.md | 5 ++++- cmd/cmd_policy.go | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5429bd7..b4ea148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,15 @@ # Changelog +## v0.1.0 + +FEATURES +* [#83](https://github.com/bnb-chain/greenfield-cmd/pull/83) support uploading multiple files or folder by one command ## v0.1.0-alpha.2 FEATURES * [#80](https://github.com/bnb-chain/greenfield-cmd/pull/80) update depenency and support group new API, including "group ls ", "group ls-member", "group ls-belong" and "policy ls" - ## v0.1.0-alpha.1 FEATURES diff --git a/cmd/cmd_policy.go b/cmd/cmd_policy.go index eec2ca4..2cdbf04 100644 --- a/cmd/cmd_policy.go +++ b/cmd/cmd_policy.go @@ -532,6 +532,10 @@ func listObjectPolicy(ctx *cli.Context, cli client.Client, bucketName, objectNam // get the latest policy from chain groupId := ctx.Uint64(groupIDFlag) grantee := ctx.String(granteeFlag) + + if groupId == 0 && grantee == "" { + return toCmdErr(errors.New("failed to parse group id or grantee info")) + } c, cancelPolicy := context.WithCancel(globalContext) defer cancelPolicy() var policyInfo *permTypes.Policy @@ -585,7 +589,7 @@ func listBucketPolicy(ctx *cli.Context, cli client.Client, bucketName, resourceN if err != nil { return err } - + listPolicyInfo(groupId, grantee, resourceName, *policyInfo) return nil }