diff --git a/.gitignore b/.gitignore index 0bae412a..8f50f0f6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ src/test/ src/.qshell marker.go marker_test.go +build.sh +build_local.sh # Folders _obj diff --git a/cmd/root.go b/cmd/root.go index 22dd7de1..60d0fd54 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,13 +2,15 @@ package cmd import ( "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/qiniu/qshell/v2/docs" "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/common/config" "github.com/qiniu/qshell/v2/iqshell/common/data" "github.com/qiniu/qshell/v2/iqshell/common/version" - "github.com/spf13/cobra" - "os" ) const ( diff --git a/cmd/rsbatch.go b/cmd/rsbatch.go index ea14c6f6..684be3b5 100644 --- a/cmd/rsbatch.go +++ b/cmd/rsbatch.go @@ -1,11 +1,12 @@ package cmd import ( + "github.com/spf13/cobra" + "github.com/qiniu/qshell/v2/docs" "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/storage/object/batch" "github.com/qiniu/qshell/v2/iqshell/storage/object/operations" - "github.com/spf13/cobra" ) var batchStatCmdBuilder = func(cfg *iqshell.Config) *cobra.Command { @@ -28,6 +29,7 @@ var batchStatCmdBuilder = func(cfg *iqshell.Config) *cobra.Command { setBatchCmdWorkerCountIncreasePeriodFlags(cmd, &info.BatchInfo) setBatchCmdSuccessExportFileFlags(cmd, &info.BatchInfo) setBatchCmdFailExportFileFlags(cmd, &info.BatchInfo) + setBatchCmdResultExportFileFlags(cmd, &info.BatchInfo) setBatchCmdForceFlags(cmd, &info.BatchInfo) setBatchCmdEnableRecordFlags(cmd, &info.BatchInfo) setBatchCmdRecordRedoWhileErrorFlags(cmd, &info.BatchInfo) @@ -257,6 +259,7 @@ var batchSignCmdBuilder = func(cfg *iqshell.Config) *cobra.Command { }, } setBatchCmdInputFileFlags(cmd, &info.BatchInfo) + setBatchCmdResultExportFileFlags(cmd, &info.BatchInfo) setBatchCmdEnableRecordFlags(cmd, &info.BatchInfo) setBatchCmdRecordRedoWhileErrorFlags(cmd, &info.BatchInfo) cmd.Flags().StringVarP(&info.Deadline, "deadline", "e", "3600", "deadline in seconds, default 3600") @@ -340,6 +343,9 @@ func setBatchCmdOverwriteFlags(cmd *cobra.Command, info *batch.Info) { cmd.Flags().BoolVarP(&info.Overwrite, "overwrite", "w", false, "overwrite mode") _ = cmd.Flags().MarkShorthandDeprecated("overwrite", "deprecated and use --overwrite instead") } +func setBatchCmdResultExportFileFlags(cmd *cobra.Command, info *batch.Info) { + cmd.Flags().StringVarP(&info.ResultExportFilePath, "outfile", "o", "", "specifies the file path where the results is saved") +} func init() { registerLoader(rsBatchCmdLoader) diff --git a/cmd_test/fop_test.go b/cmd_test/fop_test.go index 8c34b8f5..400b9147 100644 --- a/cmd_test/fop_test.go +++ b/cmd_test/fop_test.go @@ -34,7 +34,7 @@ func TestFopNoExistBucket(t *testing.T) { func TestFopNoExistKey(t *testing.T) { _, errs := test.RunCmdWithError("pfop", test.Bucket, test.KeyNotExist, fopObjectValue) - if !strings.Contains(errs, "invalid_param") { + if !strings.Contains(errs, "NotFound") { t.Fail() } } diff --git a/cmd_test/sign_test.go b/cmd_test/sign_test.go index c6c531bc..97b78360 100644 --- a/cmd_test/sign_test.go +++ b/cmd_test/sign_test.go @@ -3,8 +3,10 @@ package cmd import ( - "github.com/qiniu/qshell/v2/cmd_test/test" + "path/filepath" "testing" + + "github.com/qiniu/qshell/v2/cmd_test/test" ) func TestBatchSign(t *testing.T) { @@ -13,7 +15,17 @@ func TestBatchSign(t *testing.T) { t.Fatal("create batch sign config file error:", err) } - result, errs := test.RunCmdWithError("batchsign", "-i", path) + resultDir, err := test.ResultPath() + if err != nil { + t.Fatal("get result dir error:", err) + } + + resultLogPath := filepath.Join(resultDir, "batch_result.txt") + + result, errs := test.RunCmdWithError("batchsign", + "-i", path, + "--outfile", resultLogPath, + ) if len(errs) > 0 { t.Fail() } @@ -21,6 +33,14 @@ func TestBatchSign(t *testing.T) { if len(result) == 0 { t.Fail() } + + defer func() { + test.RemoveFile(resultLogPath) + }() + + if !test.IsFileHasContent(resultLogPath) { + t.Fatal("batch result: output to file error: file empty") + } } func TestBatchSignDocument(t *testing.T) { diff --git a/cmd_test/status_test.go b/cmd_test/status_test.go index adfe2533..004352b6 100644 --- a/cmd_test/status_test.go +++ b/cmd_test/status_test.go @@ -3,10 +3,11 @@ package cmd import ( - "github.com/qiniu/qshell/v2/cmd_test/test" "path/filepath" "strings" "testing" + + "github.com/qiniu/qshell/v2/cmd_test/test" ) func TestStatus(t *testing.T) { @@ -76,6 +77,7 @@ func TestBatchStatus(t *testing.T) { successLogPath := filepath.Join(resultDir, "batch_success.txt") failLogPath := filepath.Join(resultDir, "batch_fail.txt") + resultLogPath := filepath.Join(resultDir, "batch_result.txt") path, err := test.CreateFileWithContent("batch_status.txt", batchConfig) if err != nil { @@ -86,6 +88,7 @@ func TestBatchStatus(t *testing.T) { "-i", path, "--success-list", successLogPath, "--failure-list", failLogPath, + "--outfile", resultLogPath, "--worker", "4", "--min-worker", "10", "--worker-count-increase-period", "50", @@ -93,6 +96,7 @@ func TestBatchStatus(t *testing.T) { defer func() { test.RemoveFile(successLogPath) test.RemoveFile(failLogPath) + test.RemoveFile(resultLogPath) }() if !test.IsFileHasContent(successLogPath) { @@ -102,6 +106,10 @@ func TestBatchStatus(t *testing.T) { if !test.IsFileHasContent(failLogPath) { t.Fatal("batch result: fail log to file error: file empty") } + + if !test.IsFileHasContent(resultLogPath) { + t.Fatal("batch result: output to file error: file empty") + } } func TestBatchStatusDocument(t *testing.T) { diff --git a/docs/batchsign.md b/docs/batchsign.md index 5f321fdc..d5bc57d2 100644 --- a/docs/batchsign.md +++ b/docs/batchsign.md @@ -24,6 +24,7 @@ $ qshell batchsign --doc ``` // 资源外链 ``` +- -o/--outfile:指定一个文件,把签名结果导入到此文件中【可选】 - -e/--deadline:接受一个过时的 deadline 参数,如果没有指定该参数,默认为 3600s 。【必选】 - --enable-record:记录任务执行状态,当下次执行命令时会检测任务执行的状态并跳过已执行的任务。 【可选】 - --record-redo-while-error:依赖于 --enable-record;命令重新执行时,命令中所有任务会从头到尾重新执行;每个任务执行前会根据记录先查看当前任务是否已经执行,如果任务已执行且失败,则再执行一次;默认为 false,当任务执行失败则跳过不再重新执行。 【可选】 diff --git a/docs/batchstat.md b/docs/batchstat.md index cd419aea..fbeaec6a 100644 --- a/docs/batchstat.md +++ b/docs/batchstat.md @@ -30,6 +30,7 @@ $ qshell batchstat --doc - -y/--force:该选项控制工具的默认行为。默认情况下,对于批量操作,工具会要求使用者输入一个验证码,确认下要进行批量文件操作了,避免操作失误的发生。如果不需要这个验证码的提示过程可以使用此选项。【可选】 - -s/--success-list:该选项指定一个文件,程序会把操作成功的资源信息导入到该文件;默认不导出。【可选】 - -e/--failure-list:该选项指定一个文件,程序会把操作失败的资源信息加上错误信息导入该文件;默认不导出。【可选】 +- -o/--outfile:该选项指定一个文件,把 stat 结果导入到此文件中。注:输出的内容顺序和 input file 内容的顺序会有不同【可选】 - -c/--worker:该选项可以定义 Batch 任务并发数;1 路并发单次操作对象数为 250 ,如果配置为 10 并发,则 10 路并发单次操作对象数为 2500,此值需要和七牛对您的操作上限相吻合,否则会出现非预期错误,正常情况不需要调节此值,如果需要请谨慎调节;默认为 4。【可选】 - --min-worker:最小 Batch 任务并发数;当并发设置过高时,会触发超限错误,为了缓解此问题,qshell 会自动减小并发度,此值为减小的最低值。默认:1【可选】 - --worker-count-increase-period:为了尽可能快的完成操作 qshell 会周期性尝试增加并发度,此值为尝试增加并发数的周期,单位:秒,最小 10,默认 60。【可选】 @@ -50,17 +51,24 @@ RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000005.ts - 使用如下命令进行批量查询 ``` -$ qshell batchstat 7qiniu -i listFile +$ qshell batchstat 7qiniu --silence -y -i listFile ``` -- 输出 Key、Fsize、Hash、MimeType、PutTime 以 `\t` 分隔: +- 输出 Key、Fsize、Hash、MimeType、PutTime、User 以 `\t` 分隔: ``` -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000000.ts 92308 Fk8Uf2SHbQ4S2-cXHINuRc_rooNA video/mp2t 15003760414606314 -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000001.ts 91556 FpJP2nfipuLVc6QGvvcb868Rd0pO video/mp2t 15003760414789673 -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000002.ts 92496 FvBjZPch6cf52t2x0ZQBngqS1KTp video/mp2t 15003760417159000 -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000003.ts 92308 FoEgsbzdrcLuj_Fo5FeTI3w1jFHJ video/mp2t 15003760419154144 -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000004.ts 92308 FkYNctlf1JOGcJa-WzWgxsqcBjX6 video/mp2t 15003760422258065 -RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000005.ts 92120 Fh4Fwhu3dMUGbd3jE5OmRtfVZLv4 video/mp2t 15003760423842522 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000000.ts 92308 Fk8Uf2SHbQ4S2-cXHINuRc_rooNA video/mp2t 15003760414606314 0 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000001.ts 91556 FpJP2nfipuLVc6QGvvcb868Rd0pO video/mp2t 15003760414789673 0 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000002.ts 92496 FvBjZPch6cf52t2x0ZQBngqS1KTp video/mp2t 15003760417159000 0 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000003.ts 92308 FoEgsbzdrcLuj_Fo5FeTI3w1jFHJ video/mp2t 15003760419154144 0 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000004.ts 92308 FkYNctlf1JOGcJa-WzWgxsqcBjX6 video/mp2t 15003760422258065 0 +RclviFDHaQAUl3aL46jKRskUWbg=/FpwH76F3yfYmFKoPDjoSNWzeLKYp/000005.ts 92120 Fh4Fwhu3dMUGbd3jE5OmRtfVZLv4 video/mp2t 15003760423842522 0 +--------------- Batch Result --------------- + Total: 6 + Success: 6 + Failure: 0 + Skipped: 0 + Duration: 1s +-------------------------------------------- ``` # 注意 diff --git a/docs/expire.md b/docs/expire.md index 30c9fa45..593f3e26 100644 --- a/docs/expire.md +++ b/docs/expire.md @@ -31,6 +31,6 @@ $ qshell expire --doc # 示例 修改 `if-pbl` 空间中 `qiniu.png` 图片的过期时间为:`3天后自动删除` ``` -$ qshell chtype if-pbl qiniu.png 3 +$ qshell expire if-pbl qiniu.png 3 ``` 输入该命令,后该文件就已经被修改为 3 天后自动删除了。 diff --git a/iqshell/common/client/client.go b/iqshell/common/client/client.go index f86a514f..9fb208da 100644 --- a/iqshell/common/client/client.go +++ b/iqshell/common/client/client.go @@ -13,15 +13,15 @@ var defaultClient = storage.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ - Timeout: 10 * time.Second, - KeepAlive: 10 * time.Second, + Timeout: 20 * time.Second, + KeepAlive: 20 * time.Second, }).DialContext, ForceAttemptHTTP2: true, - MaxIdleConns: 4000, + MaxIdleConns: 2000, MaxIdleConnsPerHost: 1000, ResponseHeaderTimeout: 60 * time.Second, - IdleConnTimeout: 10 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, + IdleConnTimeout: 15 * time.Second, + TLSHandshakeTimeout: 15 * time.Second, ExpectContinueTimeout: 1 * time.Second, }, }, diff --git a/iqshell/common/export/file.go b/iqshell/common/export/file.go index 8ff41858..9e6dfe3c 100644 --- a/iqshell/common/export/file.go +++ b/iqshell/common/export/file.go @@ -9,6 +9,7 @@ type FileExporter struct { fail Exporter skip Exporter overwrite Exporter + result Exporter } func (b *FileExporter) Success() Exporter { @@ -27,6 +28,10 @@ func (b *FileExporter) Overwrite() Exporter { return b.overwrite } +func (b *FileExporter) Result() Exporter { + return b.result +} + func (b *FileExporter) Close() *data.CodeError { errS := b.success.Close() errF := b.fail.Close() @@ -41,10 +46,11 @@ func (b *FileExporter) Close() *data.CodeError { } type FileExporterConfig struct { - SuccessExportFilePath string - FailExportFilePath string - SkipExportFilePath string - OverwriteExportFilePath string + SuccessExportFilePath string // 输入列表中的成功部分 + FailExportFilePath string // 输入列表中的失败部分 + SkipExportFilePath string // 输入列表中的跳过部分 + OverwriteExportFilePath string // 输入列表中的覆盖部分 + ResultExportFilePath string // 结果输出 } func NewFileExport(config FileExporterConfig) (export *FileExporter, err *data.CodeError) { @@ -65,6 +71,11 @@ func NewFileExport(config FileExporterConfig) (export *FileExporter, err *data.C } export.overwrite, err = New(config.OverwriteExportFilePath) + if err != nil { + return + } + + export.result, err = New(config.ResultExportFilePath) return } @@ -74,5 +85,6 @@ func EmptyFileExport() *FileExporter { export.fail = empty() export.skip = empty() export.overwrite = empty() + export.result = empty() return export } diff --git a/iqshell/storage/bucket/list.go b/iqshell/storage/bucket/list.go index 69f63909..1c30c1fe 100644 --- a/iqshell/storage/bucket/list.go +++ b/iqshell/storage/bucket/list.go @@ -2,12 +2,6 @@ package bucket import ( "bufio" - "github.com/qiniu/qshell/v2/iqshell/common/alert" - "github.com/qiniu/qshell/v2/iqshell/common/data" - "github.com/qiniu/qshell/v2/iqshell/common/file" - "github.com/qiniu/qshell/v2/iqshell/common/log" - "github.com/qiniu/qshell/v2/iqshell/common/workspace" - "github.com/qiniu/qshell/v2/iqshell/storage/bucket/internal/list" "io" "math" "os" @@ -15,6 +9,13 @@ import ( "strings" "sync" "time" + + "github.com/qiniu/qshell/v2/iqshell/common/alert" + "github.com/qiniu/qshell/v2/iqshell/common/data" + "github.com/qiniu/qshell/v2/iqshell/common/file" + "github.com/qiniu/qshell/v2/iqshell/common/log" + "github.com/qiniu/qshell/v2/iqshell/common/workspace" + "github.com/qiniu/qshell/v2/iqshell/storage/bucket/internal/list" ) type ListApiInfo struct { @@ -63,12 +64,14 @@ func List(info ListApiInfo, objectHandler func(marker string, object ListObject) (shouldContinue bool, err *data.CodeError), errorHandler func(marker string, err *data.CodeError)) { if objectHandler == nil { + data.SetCmdStatus(data.StatusError) log.Error(alert.CannotEmpty("list bucket: object handler", "")) return } if errorHandler == nil { errorHandler = func(marker string, err *data.CodeError) { + data.SetCmdStatus(data.StatusError) log.ErrorF("marker: %s", info.Marker) log.ErrorF("list bucket Error: %v", err) } @@ -258,6 +261,7 @@ type ListToFileApiInfo struct { func ListToFile(info ListToFileApiInfo, errorHandler func(marker string, err *data.CodeError)) { if errorHandler == nil { errorHandler = func(marker string, err *data.CodeError) { + data.SetCmdStatus(data.StatusError) log.ErrorF("marker: %s", marker) log.ErrorF("list bucket Error: %v", err) } diff --git a/iqshell/storage/bucket/operations/list.go b/iqshell/storage/bucket/operations/list.go index 85e21176..a31e910f 100644 --- a/iqshell/storage/bucket/operations/list.go +++ b/iqshell/storage/bucket/operations/list.go @@ -2,6 +2,11 @@ package operations import ( "fmt" + "path/filepath" + "strconv" + "strings" + "time" + "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/common/alert" "github.com/qiniu/qshell/v2/iqshell/common/data" @@ -10,10 +15,6 @@ import ( "github.com/qiniu/qshell/v2/iqshell/common/workspace" "github.com/qiniu/qshell/v2/iqshell/storage/bucket" "github.com/qiniu/qshell/v2/iqshell/storage/bucket/internal/list" - "path/filepath" - "strconv" - "strings" - "time" ) type ListInfo struct { @@ -120,11 +121,13 @@ func List(cfg *iqshell.Config, info ListInfo) { startTime, err := info.getStartDate() if err != nil { log.Error(err) + data.SetCmdStatus(data.StatusError) return } endTime, err := info.getEndDate() if err != nil { log.Error(err) + data.SetCmdStatus(data.StatusError) return } @@ -159,6 +162,7 @@ func List(cfg *iqshell.Config, info ListInfo) { AppendMode: info.AppendMode, Readable: info.Readable, }, func(marker string, err *data.CodeError) { + data.SetCmdStatus(data.StatusError) log.ErrorF("marker: %s", marker) log.ErrorF("list bucket Error: %v", err) }) diff --git a/iqshell/storage/object/download/downloader.go b/iqshell/storage/object/download/downloader.go index 1a6ef696..759c88b3 100644 --- a/iqshell/storage/object/download/downloader.go +++ b/iqshell/storage/object/download/downloader.go @@ -296,9 +296,10 @@ func downloadTempFileWithDownloader(dl downloader, fInfo *fileInfo, info *Downlo if info.RangeFromBytes > 0 { if info.RangeFromBytes > info.FileSize || info.RangeFromBytes > info.RangeToBytes { errorDesc := "download, check fromBytes error: fromBytes bigger than file size, should remove temp file and retry." - log.Error(errorDesc) - _ = fInfo.cleanTempFile() - return data.NewEmptyError().AppendDesc(errorDesc) + log.Warning(errorDesc) + if e := fInfo.cleanTempFile(); e != nil { + return e.HeaderInsertDesc("download, clean temp file error:") + } } else if info.RangeFromBytes == info.FileSize || info.RangeFromBytes == info.RangeToBytes { // 已经完全下载,只不过未修改名称 return nil diff --git a/iqshell/storage/object/operations/private_url.go b/iqshell/storage/object/operations/private_url.go index 66c27f9e..71f748e0 100644 --- a/iqshell/storage/object/operations/private_url.go +++ b/iqshell/storage/object/operations/private_url.go @@ -2,6 +2,11 @@ package operations import ( "fmt" + "path/filepath" + "strconv" + "strings" + "time" + "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/common/alert" "github.com/qiniu/qshell/v2/iqshell/common/data" @@ -12,10 +17,6 @@ import ( "github.com/qiniu/qshell/v2/iqshell/common/workspace" "github.com/qiniu/qshell/v2/iqshell/storage/object/batch" "github.com/qiniu/qshell/v2/iqshell/storage/object/download" - "path/filepath" - "strconv" - "strings" - "time" ) const ( @@ -212,6 +213,7 @@ func BatchPrivateUrl(cfg *iqshell.Config, info BatchPrivateUrlInfo) { r, _ := result.(*download.PublicUrlToPrivateApiResult) exporter.Success().Export(work.Data) + exporter.Result().ExportF(r.Url) log.Alert(r.Url) }). OnWorkFail(func(work *flow.WorkInfo, err *data.CodeError) { diff --git a/iqshell/storage/object/operations/status.go b/iqshell/storage/object/operations/status.go index 624bf918..53cdd8ae 100644 --- a/iqshell/storage/object/operations/status.go +++ b/iqshell/storage/object/operations/status.go @@ -2,6 +2,9 @@ package operations import ( "fmt" + "path/filepath" + "time" + "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/common/alert" "github.com/qiniu/qshell/v2/iqshell/common/data" @@ -11,8 +14,6 @@ import ( "github.com/qiniu/qshell/v2/iqshell/common/utils" "github.com/qiniu/qshell/v2/iqshell/storage/object" "github.com/qiniu/qshell/v2/iqshell/storage/object/batch" - "path/filepath" - "time" ) type StatusInfo object.StatusApiInfo @@ -105,8 +106,10 @@ func BatchStatus(cfg *iqshell.Config, info BatchStatusInfo) { } in := (*StatusInfo)(apiInfo) if result.IsSuccess() { - log.InfoF("%s\t%d\t%s\t%s\t%d\t%d", + infoString := fmt.Sprintf("%s\t%d\t%s\t%s\t%d\t%d", in.Key, result.FSize, result.Hash, result.MimeType, result.PutTime, result.Type) + log.Alert(infoString) + exporter.Result().Export(infoString) } else { data.SetCmdStatusError() log.ErrorF("Status Failed, [%s:%s], Code: %d, Error: %s", in.Bucket, in.Key, result.Code, result.Error) diff --git a/iqshell/storage/object/operations/type_change.go b/iqshell/storage/object/operations/type_change.go index 9e66f7b4..a1de5166 100644 --- a/iqshell/storage/object/operations/type_change.go +++ b/iqshell/storage/object/operations/type_change.go @@ -2,6 +2,9 @@ package operations import ( "fmt" + "path/filepath" + "strconv" + "github.com/qiniu/qshell/v2/iqshell" "github.com/qiniu/qshell/v2/iqshell/common/alert" "github.com/qiniu/qshell/v2/iqshell/common/data" @@ -11,8 +14,6 @@ import ( "github.com/qiniu/qshell/v2/iqshell/common/utils" "github.com/qiniu/qshell/v2/iqshell/storage/object" "github.com/qiniu/qshell/v2/iqshell/storage/object/batch" - "path/filepath" - "strconv" ) type ChangeTypeInfo struct { diff --git a/iqshell/storage/object/upload/operations/batch.go b/iqshell/storage/object/upload/operations/batch.go index f29e25c3..6f4e08b8 100644 --- a/iqshell/storage/object/upload/operations/batch.go +++ b/iqshell/storage/object/upload/operations/batch.go @@ -338,7 +338,7 @@ func batchUploadFlow(info BatchUpload2Info, uploadConfig UploadConfig, dbPath st // 本地文件和服务端文件均没有变化,则不需要重新上传 isServerFileNotChange := true - if uploadConfig.CheckHash { + if uploadConfig.CheckHash || uploadConfig.CheckSize { // 检测 hash 需要调用 Stat 接口查询 hash,如果用户不检测 hash 则认为服务端文件没有变化。 stat, sErr := object.Status(object.StatusApiInfo{ Bucket: uploadInfo.ToBucket, @@ -348,7 +348,12 @@ func batchUploadFlow(info BatchUpload2Info, uploadConfig UploadConfig, dbPath st if sErr != nil { return true, data.NewEmptyError().AppendDesc("get stat from server").AppendError(sErr) } - isServerFileNotChange = stat.Hash == result.ServerFileHash + + if uploadConfig.CheckHash { + isServerFileNotChange = stat.Hash == result.ServerFileHash + } else { + isServerFileNotChange = stat.FSize == result.ServerFileSize + } } // LocalFileModifyTime 单位是 100ns