Skip to content

Commit 18cd86e

Browse files
committed
groot/riofs: provide a stable top-dir to Walk
Signed-off-by: Sebastien Binet <binet@cern.ch>
1 parent 853be00 commit 18cd86e

File tree

3 files changed

+98
-2
lines changed

3 files changed

+98
-2
lines changed

groot/rcmd/merge.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,15 @@ func (cmd *mergeCmd) mergeTasksFrom(o *riofs.File, fname string) ([]task, error)
109109
}
110110
defer f.Close()
111111

112+
// handle relative/absolute path
113+
top := stdpath.Join(f.Name(), ".")
114+
112115
var tsks []task
113116
err = riofs.Walk(f, func(path string, obj root.Object, err error) error {
114117
if err != nil {
115118
return err
116119
}
117-
name := path[len(f.Name()):]
120+
name := path[len(top):]
118121
if name == "" {
119122
return nil
120123
}

groot/riofs/walk.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,20 @@ var SkipDir = errors.New("riofs: skip this directory") //lint:ignore ST1012 EOF-
2323
//
2424
// If an object exists with multiple cycle values, only the latest one is considered.
2525
func Walk(dir Directory, walkFn WalkFunc) error {
26-
err := walk(dir.(root.Named).Name(), dir.(root.Object), walkFn)
26+
// prepare a "stable" top directory.
27+
// depending on whether the dir is rooted in a file that was created
28+
// with an absolute path, the call to Name() may return a path like:
29+
// ./data/file.root
30+
// the first call to walkFn will be given "./data/file.root" as a 'path'
31+
// argument.
32+
// but the subsequent calls (walking through directories' hierarchy) will
33+
// be given "data/file.root/dir11", instead of the probably expected
34+
// "./data/file.root/dir11".
35+
//
36+
// side-step this by providing directly the "stable" top directory in a
37+
// more regularized form.
38+
top := stdpath.Join(dir.(root.Named).Name(), ".")
39+
err := walk(top, dir.(root.Object), walkFn)
2740
if err == SkipDir {
2841
return nil
2942
}

groot/riofs/walk_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313
"testing"
1414

15+
"github.com/google/go-cmp/cmp"
1516
"go-hep.org/x/hep/groot/rbase"
1617
"go-hep.org/x/hep/groot/rhist"
1718
"go-hep.org/x/hep/groot/root"
@@ -403,6 +404,85 @@ func TestFileOf(t *testing.T) {
403404
}
404405
}
405406

407+
func TestWalk(t *testing.T) {
408+
tmp, err := os.MkdirTemp("", "groot-riofs-")
409+
if err != nil {
410+
t.Fatal(err)
411+
}
412+
defer os.RemoveAll(tmp)
413+
414+
err = os.MkdirAll(stdpath.Join(tmp, "data"), 0755)
415+
if err != nil {
416+
t.Fatal(err)
417+
}
418+
419+
pwd, err := os.Getwd()
420+
if err != nil {
421+
t.Fatalf("could not get working directory: %+v", err)
422+
}
423+
defer os.Chdir(pwd)
424+
425+
err = os.Chdir(tmp)
426+
if err != nil {
427+
t.Fatal(err)
428+
}
429+
430+
fname := "./data/file.root"
431+
432+
f, err := Create(fname)
433+
if err != nil {
434+
t.Fatalf("could not create ROOT file: %+v", err)
435+
}
436+
defer f.Close()
437+
438+
err = os.Chdir(pwd)
439+
if err != nil {
440+
t.Fatal(err)
441+
}
442+
443+
rd := Dir(f)
444+
445+
display := func() string {
446+
o := new(strings.Builder)
447+
err := Walk(f, func(path string, obj root.Object, err error) error {
448+
fmt.Fprintf(o, "%s (%s)\n", path, obj.Class())
449+
return nil
450+
})
451+
if err != nil {
452+
return fmt.Errorf("could not display file content: %w", err).Error()
453+
}
454+
return o.String()
455+
}
456+
457+
for _, name := range []string{
458+
"dir1/dir11/dir111",
459+
"dir1/dir12/dir121",
460+
"dir2/dir21",
461+
"dir2/dir22",
462+
} {
463+
_, err = rd.Mkdir(name)
464+
if err != nil {
465+
t.Fatalf("could not create dir %q: %+v", name, err)
466+
}
467+
}
468+
469+
got := display()
470+
want := `data/file.root (TFile)
471+
data/file.root/dir1 (TDirectoryFile)
472+
data/file.root/dir1/dir11 (TDirectoryFile)
473+
data/file.root/dir1/dir11/dir111 (TDirectoryFile)
474+
data/file.root/dir1/dir12 (TDirectoryFile)
475+
data/file.root/dir1/dir12/dir121 (TDirectoryFile)
476+
data/file.root/dir2 (TDirectoryFile)
477+
data/file.root/dir2/dir21 (TDirectoryFile)
478+
data/file.root/dir2/dir22 (TDirectoryFile)
479+
`
480+
if got != want {
481+
diff := cmp.Diff(want, got)
482+
t.Fatalf("invalid Walk display: -- (-ref +got)\n%s", diff)
483+
}
484+
}
485+
406486
type unknownDirImpl struct{}
407487

408488
func (dir *unknownDirImpl) Get(namecycle string) (root.Object, error) { panic("not implemented") }

0 commit comments

Comments
 (0)