forked from TrueCloudLab/restic
ls: add missing intermediate directories to --ncdu output
This commit is contained in:
parent
894ec9d05d
commit
15419d603d
3 changed files with 29 additions and 16 deletions
|
@ -71,7 +71,7 @@ func init() {
|
||||||
|
|
||||||
type lsPrinter interface {
|
type lsPrinter interface {
|
||||||
Snapshot(sn *restic.Snapshot)
|
Snapshot(sn *restic.Snapshot)
|
||||||
Node(path string, node *restic.Node)
|
Node(path string, node *restic.Node, isPrefixDirectory bool)
|
||||||
LeaveDir(path string)
|
LeaveDir(path string)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,10 @@ func (p *jsonLsPrinter) Snapshot(sn *restic.Snapshot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print node in our custom JSON format, followed by a newline.
|
// Print node in our custom JSON format, followed by a newline.
|
||||||
func (p *jsonLsPrinter) Node(path string, node *restic.Node) {
|
func (p *jsonLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) {
|
||||||
|
if isPrefixDirectory {
|
||||||
|
return
|
||||||
|
}
|
||||||
err := lsNodeJSON(p.enc, path, node)
|
err := lsNodeJSON(p.enc, path, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
Warnf("JSON encode failed: %v\n", err)
|
||||||
|
@ -217,7 +220,7 @@ func lsNcduNode(_ string, node *restic.Node) ([]byte, error) {
|
||||||
return json.Marshal(outNode)
|
return json.Marshal(outNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ncduLsPrinter) Node(path string, node *restic.Node) {
|
func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) {
|
||||||
out, err := lsNcduNode(path, node)
|
out, err := lsNcduNode(path, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
Warnf("JSON encode failed: %v\n", err)
|
||||||
|
@ -249,9 +252,11 @@ type textLsPrinter struct {
|
||||||
func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) {
|
func (p *textLsPrinter) Snapshot(sn *restic.Snapshot) {
|
||||||
Verbosef("%v filtered by %v:\n", sn, p.dirs)
|
Verbosef("%v filtered by %v:\n", sn, p.dirs)
|
||||||
}
|
}
|
||||||
func (p *textLsPrinter) Node(path string, node *restic.Node) {
|
func (p *textLsPrinter) Node(path string, node *restic.Node, isPrefixDirectory bool) {
|
||||||
|
if !isPrefixDirectory {
|
||||||
Printf("%s\n", formatNode(path, node, p.ListLong, p.HumanReadable))
|
Printf("%s\n", formatNode(path, node, p.ListLong, p.HumanReadable))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *textLsPrinter) LeaveDir(_ string) {}
|
func (p *textLsPrinter) LeaveDir(_ string) {}
|
||||||
func (p *textLsPrinter) Close() {}
|
func (p *textLsPrinter) Close() {}
|
||||||
|
@ -369,8 +374,8 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
||||||
|
|
||||||
printedDir := false
|
printedDir := false
|
||||||
if withinDir(nodepath) {
|
if withinDir(nodepath) {
|
||||||
// if we're within a dir, print the node
|
// if we're within a target path, print the node
|
||||||
printer.Node(nodepath, node)
|
printer.Node(nodepath, node, false)
|
||||||
printedDir = true
|
printedDir = true
|
||||||
|
|
||||||
// if recursive listing is requested, signal the walker that it
|
// if recursive listing is requested, signal the walker that it
|
||||||
|
@ -383,12 +388,17 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
||||||
// if there's an upcoming match deeper in the tree (but we're not
|
// if there's an upcoming match deeper in the tree (but we're not
|
||||||
// there yet), signal the walker to descend into any subdirs
|
// there yet), signal the walker to descend into any subdirs
|
||||||
if approachingMatchingTree(nodepath) {
|
if approachingMatchingTree(nodepath) {
|
||||||
|
// print node leading up to the target paths
|
||||||
|
if !printedDir {
|
||||||
|
printer.Node(nodepath, node, true)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, signal the walker to not walk recursively into any
|
// otherwise, signal the walker to not walk recursively into any
|
||||||
// subdirs
|
// subdirs
|
||||||
if node.Type == "dir" {
|
if node.Type == "dir" {
|
||||||
|
// immediately generate leaveDir if the directory is skipped
|
||||||
if printedDir {
|
if printedDir {
|
||||||
printer.LeaveDir(nodepath)
|
printer.LeaveDir(nodepath)
|
||||||
}
|
}
|
||||||
|
@ -401,7 +411,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
||||||
ProcessNode: processNode,
|
ProcessNode: processNode,
|
||||||
LeaveDir: func(path string) {
|
LeaveDir: func(path string) {
|
||||||
// the root path `/` has no corresponding node and is thus also skipped by processNode
|
// the root path `/` has no corresponding node and is thus also skipped by processNode
|
||||||
if withinDir(path) && path != "/" {
|
if path != "/" {
|
||||||
printer.LeaveDir(path)
|
printer.LeaveDir(path)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,13 +35,16 @@ func TestRunLsNcdu(t *testing.T) {
|
||||||
env, cleanup := withTestEnvironment(t)
|
env, cleanup := withTestEnvironment(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
testRunInit(t, env.gopts)
|
testSetupBackupData(t, env)
|
||||||
opts := BackupOptions{}
|
opts := BackupOptions{}
|
||||||
testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
|
testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
|
||||||
|
|
||||||
ncdu := testRunLsWithOpts(t, env.gopts, LsOptions{Ncdu: true}, []string{"latest"})
|
for _, paths := range [][]string{
|
||||||
assertIsValidJSON(t, ncdu)
|
{"latest"},
|
||||||
|
{"latest", "/testdata"},
|
||||||
ncdu = testRunLsWithOpts(t, env.gopts, LsOptions{Ncdu: true}, []string{"latest", "/testdata"})
|
{"latest", "/testdata/0", "/testdata/0/tests"},
|
||||||
|
} {
|
||||||
|
ncdu := testRunLsWithOpts(t, env.gopts, LsOptions{Ncdu: true}, paths)
|
||||||
assertIsValidJSON(t, ncdu)
|
assertIsValidJSON(t, ncdu)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -140,12 +140,12 @@ func TestLsNcdu(t *testing.T) {
|
||||||
printer.Node("/directory", &restic.Node{
|
printer.Node("/directory", &restic.Node{
|
||||||
Type: "dir",
|
Type: "dir",
|
||||||
Name: "directory",
|
Name: "directory",
|
||||||
})
|
}, false)
|
||||||
printer.Node("/directory/data", &restic.Node{
|
printer.Node("/directory/data", &restic.Node{
|
||||||
Type: "file",
|
Type: "file",
|
||||||
Name: "data",
|
Name: "data",
|
||||||
Size: 42,
|
Size: 42,
|
||||||
})
|
}, false)
|
||||||
printer.LeaveDir("/directory")
|
printer.LeaveDir("/directory")
|
||||||
printer.Close()
|
printer.Close()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue