Skip to content

Commit

Permalink
[filesystem] Add a way to determine all parents of a path (#503)
Browse files Browse the repository at this point in the history
<!--
Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors.
All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->
### Description
try to give the same functionality as
[pathlib](https://github.com/python/cpython/blob/3.12/Lib/pathlib.py#L263)

### Test Coverage

<!--
Please put an `x` in the correct box e.g. `[x]` to indicate the testing
coverage of this change.
-->

- [x]  This change is covered by existing or additional automated tests.
- [ ] Manual testing has been performed (and evidence provided) as
automated testing was not feasible.
- [ ] Additional tests are not required for this change (e.g.
documentation update).
  • Loading branch information
acabarbaye authored Sep 5, 2024
1 parent 2f440e0 commit d518f3b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 1 deletion.
1 change: 1 addition & 0 deletions changes/20240905230606.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:sparkles: [filesystem] Add a way to determine all parents of a path similar to python's [pathlib](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parents)
30 changes: 29 additions & 1 deletion utils/filesystem/filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,39 @@ import (
"github.com/ARM-software/golang-utils/utils/reflection"
)

// FilepathStem returns the final path component, without its suffix.
// FilepathStem returns the final path component, without its suffix. It's similar to `stem` in python's [pathlib](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.stem)
func FilepathStem(fp string) string {
return strings.TrimSuffix(filepath.Base(fp), filepath.Ext(fp))
}

// FilepathParents returns a list of to the logical ancestors of the path and it's similar to `parents` in python's [pathlib](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parents)
func FilepathParents(fp string) []string {
return FilePathParentsOnFilesystem(GetGlobalFileSystem(), fp)
}

// FilePathParentsOnFilesystem is similar to FilepathParents but with the ability to be applied to a particular filesystem.
func FilePathParentsOnFilesystem(fs FS, fp string) (parents []string) {
cleanFp := filepath.Clean(fp)
elements := strings.Split(cleanFp, string(fs.PathSeparator()))
if len(elements) <= 1 {
return
}
path := elements[0]
if path == "" {
elements = elements[1:]
if len(elements) <= 1 {
return
}
path = elements[0]
}
parents = append(parents, path)
for i := 1; i < len(elements)-1; i++ {
path = strings.Join([]string{path, elements[i]}, string(fs.PathSeparator()))
parents = append(parents, path)
}
return
}

// FileTreeDepth returns the depth of a file in a tree starting from root
func FileTreeDepth(fs FS, root, filePath string) (depth int64, err error) {
if reflection.IsEmpty(filePath) {
Expand Down
56 changes: 56 additions & 0 deletions utils/filesystem/filepath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ARM-software/golang-utils/utils/commonerrors"
"github.com/ARM-software/golang-utils/utils/commonerrors/errortest"
"github.com/ARM-software/golang-utils/utils/platform"
)

func TestFilepathStem(t *testing.T) {
Expand All @@ -29,6 +30,61 @@ func TestFilepathStem(t *testing.T) {
})
}

func TestFilepathParents(t *testing.T) {
type PathTest struct {
path string
expectedParents []string
}
tests := []PathTest{
{},
{
path: " ",
expectedParents: nil,
},
{
path: "/",
expectedParents: nil,
},
{
path: ".",
expectedParents: nil,
},
{
path: "./",
expectedParents: nil,
},
{
path: "./blah",
expectedParents: nil,
},
{
path: filepath.Join("a", "great", "fake", "path", "blah"),
expectedParents: []string{"a", filepath.Join("a", "great"), filepath.Join("a", "great", "fake"), filepath.Join("a", "great", "fake", "path")},
},
{
path: "/foo/bar/setup.py",
expectedParents: []string{`foo`, filepath.Join(`foo`, `bar`)},
},
}

if platform.IsWindows() {
tests = append(tests, PathTest{
path: "C:/foo/bar/setup.py",
expectedParents: []string{"C:", filepath.Join(`C:`, `\foo`), filepath.Join(`C:`, `\foo`, `bar`)},
})
} else {
tests = append(tests, PathTest{
path: "C:/foo/bar/setup.py",
expectedParents: []string{"C:", filepath.Join(`C:`, `foo`), filepath.Join(`C:`, `foo`, `bar`)},
})
}
for _, tt := range tests {
t.Run(tt.path, func(t *testing.T) {
assert.ElementsMatch(t, tt.expectedParents, FilepathParents(tt.path))
})
}
}

func TestFileTreeDepth(t *testing.T) {
random := fmt.Sprintf("%v %v %v", faker.Name(), faker.Name(), faker.Name())
complexRandom := fmt.Sprintf("%v&#~@£*-_()^+!%v %v", faker.Name(), faker.Name(), faker.Name())
Expand Down

0 comments on commit d518f3b

Please sign in to comment.