diff --git a/cmd/rm-main.go b/cmd/rm-main.go index 15a6c4f0..aa403a9a 100644 --- a/cmd/rm-main.go +++ b/cmd/rm-main.go @@ -176,21 +176,20 @@ func checkRmSyntax(ctx *cli.Context, encKeyDB map[string][]prefixSSEPair) { } func removeSingle(url string, isIncomplete bool, isFake bool, olderThan, newerThan string, encKeyDB map[string][]prefixSSEPair) error { - targetAlias, targetURL, _ := mustExpandAlias(url) - clnt, pErr := newClientFromAlias(targetAlias, targetURL) - if pErr != nil { - errorIf(pErr.Trace(url), "Invalid argument `"+url+"`.") - return exitStatus(globalErrorExitStatus) // End of journey. - } - isFetchMeta := true - alias, _ := url2Alias(url) - sseKey := getSSE(url, encKeyDB[alias]) - content, pErr := clnt.Stat(isIncomplete, isFetchMeta, sseKey) + isRecursive := false + contents, pErr := statURL(url, isIncomplete, isRecursive, encKeyDB) if pErr != nil { errorIf(pErr.Trace(url), "Failed to remove `"+url+"`.") return exitStatus(globalErrorExitStatus) } + if len(contents) == 0 { + errorIf(errDummy().Trace(url), "Failed to remove `"+url+"`. Target object is not found") + return exitStatus(globalErrorExitStatus) + } + + content := contents[0] + // Skip objects older than older--than parameter if specified if olderThan != "" && isOlder(content.Time, olderThan) { return nil @@ -207,6 +206,13 @@ func removeSingle(url string, isIncomplete bool, isFake bool, olderThan, newerTh }) if !isFake { + targetAlias, targetURL, _ := mustExpandAlias(url) + clnt, pErr := newClientFromAlias(targetAlias, targetURL) + if pErr != nil { + errorIf(pErr.Trace(url), "Invalid argument `"+url+"`.") + return exitStatus(globalErrorExitStatus) // End of journey. + } + contentCh := make(chan *clientContent, 1) contentCh <- &clientContent{URL: *newClientURL(targetURL)} close(contentCh) diff --git a/cmd/stat-main.go b/cmd/stat-main.go index 3c5166b2..02a2d60b 100644 --- a/cmd/stat-main.go +++ b/cmd/stat-main.go @@ -121,12 +121,18 @@ func mainStat(ctx *cli.Context) error { var cErr error for _, targetURL := range args { - var clnt Client - clnt, err := newClient(targetURL) - fatalIf(err.Trace(targetURL), "Unable to initialize target `"+targetURL+"`.") - - targetAlias, _, _ := mustExpandAlias(targetURL) - return doStat(clnt, isRecursive, targetAlias, targetURL, encKeyDB) + stats, err := statURL(targetURL, false, isRecursive, encKeyDB) + if err != nil { + fatalIf(err, "Unable to stat `"+targetURL+"`.") + } + for _, stat := range stats { + st := parseStat(stat) + if !globalJSON { + printStat(st) + } else { + console.Println(st.JSON()) + } + } } return cErr diff --git a/cmd/stat.go b/cmd/stat.go index f4a117e3..7f577966 100644 --- a/cmd/stat.go +++ b/cmd/stat.go @@ -92,7 +92,7 @@ func (c statMessage) JSON() string { } // parseStat parses client Content container into statMessage struct. -func parseStat(targetAlias string, c *clientContent) statMessage { +func parseStat(c *clientContent) statMessage { content := statMessage{} content.Date = c.Time.Local() // guess file type. @@ -112,8 +112,16 @@ func parseStat(targetAlias string, c *clientContent) statMessage { return content } -// doStat - list all entities inside a folder. -func doStat(clnt Client, isRecursive bool, targetAlias, targetURL string, encKeyDB map[string][]prefixSSEPair) error { +// statURL - simple or recursive listing +func statURL(targetURL string, isIncomplete, isRecursive bool, encKeyDB map[string][]prefixSSEPair) ([]*clientContent, *probe.Error) { + var stats []*clientContent + var clnt Client + clnt, err := newClient(targetURL) + if err != nil { + return nil, err + } + + targetAlias, _, _ := mustExpandAlias(targetURL) prefixPath := clnt.GetURL().Path separator := string(clnt.GetURL().Separator) @@ -121,7 +129,6 @@ func doStat(clnt Client, isRecursive bool, targetAlias, targetURL string, encKey prefixPath = prefixPath[:strings.LastIndex(prefixPath, separator)+1] } var cErr error - isIncomplete := false for content := range clnt.List(isRecursive, isIncomplete, DirNone) { if content.Err != nil { switch content.Err.ToGoError().(type) { @@ -147,6 +154,11 @@ func doStat(clnt Client, isRecursive bool, targetAlias, targetURL string, encKey continue } url := targetAlias + getKey(content) + + if !isRecursive && url != targetURL { + return nil, errTargetNotFound(targetURL) + } + _, stat, err := url2Stat(url, true, encKeyDB) if err != nil { stat = content @@ -157,12 +169,8 @@ func doStat(clnt Client, isRecursive bool, targetAlias, targetURL string, encKey // Trim prefix path from the content path. contentURL = strings.TrimPrefix(contentURL, prefixPath) stat.URL.Path = contentURL - st := parseStat(targetAlias, stat) - if !globalJSON { - printStat(st) - } else { - console.Println(st.JSON()) - } + stats = append(stats, stat) } - return cErr + + return stats, probe.NewError(cErr) } diff --git a/cmd/stat_test.go b/cmd/stat_test.go index c0401427..543bc22f 100644 --- a/cmd/stat_test.go +++ b/cmd/stat_test.go @@ -40,7 +40,7 @@ func (s *TestSuite) TestParseStat(c *C) { "play"}, } for _, testCase := range testCases { - statMsg := parseStat(testCase.targetAlias, &testCase.content) + statMsg := parseStat(&testCase.content) c.Assert(testCase.content.Metadata, DeepEquals, statMsg.Metadata) c.Assert(testCase.content.EncryptionHeaders, DeepEquals, statMsg.EncryptionHeaders) c.Assert(testCase.content.Size, Equals, statMsg.Size) diff --git a/cmd/typed-errors.go b/cmd/typed-errors.go index c1b4114e..731b6100 100644 --- a/cmd/typed-errors.go +++ b/cmd/typed-errors.go @@ -96,6 +96,13 @@ var errInvalidTarget = func(URL string) *probe.Error { return probe.NewError(invalidTargetErr(errors.New(msg))).Untrace() } +type targetNotFoundErr error + +var errTargetNotFound = func(URL string) *probe.Error { + msg := "Target `" + URL + "` not found." + return probe.NewError(targetNotFoundErr(errors.New(msg))).Untrace() +} + type overwriteNotAllowedErr struct { error }