diff --git a/src/nu-git-manager/fs/path.nu b/src/nu-git-manager/fs/path.nu index 051d67f2..6613dcbe 100644 --- a/src/nu-git-manager/fs/path.nu +++ b/src/nu-git-manager/fs/path.nu @@ -2,3 +2,17 @@ export def "path sanitize" []: path -> path { str replace --regex '^.:' '' | str replace --all '\' '/' } + +# remove a prefix from a path or a list of paths +# +# /!\ paths need to be sanitized /!\ +export def "path remove-prefix" [prefix: string]: [path -> string, list -> list] { + str replace --regex ('^' + $prefix + '/') '' +} + +# remove the trailing `/` from a path or a list of paths +# +# /!\ paths need to be sanitized /!\ +export def "path remove-trailing-path-sep" []: [path -> path , list -> list] { + str trim --right --char "/" +} diff --git a/src/nu-git-manager/fs/store.nu b/src/nu-git-manager/fs/store.nu index 51ccaeea..542d18c9 100644 --- a/src/nu-git-manager/fs/store.nu +++ b/src/nu-git-manager/fs/store.nu @@ -1,5 +1,5 @@ use std log -use path.nu "path sanitize" +use path.nu ["path sanitize", "path remove-trailing-path-sep"] # get the root of the local repo store # @@ -44,5 +44,5 @@ export def list-repos-in-store []: nothing -> list { | filter {|it| not ($it.0 | str starts-with $it.1)} | each { get 0 } | prepend $sorted.0 - | str trim --right --char "/" + | path remove-trailing-path-sep } diff --git a/src/nu-git-manager/mod.nu b/src/nu-git-manager/mod.nu index 663f16ed..dbd5b74f 100644 --- a/src/nu-git-manager/mod.nu +++ b/src/nu-git-manager/mod.nu @@ -6,7 +6,7 @@ use fs/cache.nu [ save-cache, clean-cache-dir ] use fs/dir.nu [clean-empty-directories-rec] -use fs/path.nu ["path sanitize"] +use fs/path.nu ["path sanitize", "path remove-prefix"] use git/url.nu [parse-git-url, get-fetch-push-urls] use git/repo.nu [is-grafted, get-root-commit, list-remotes] use error/error.nu [throw-error, throw-warning] @@ -152,9 +152,7 @@ export def "gm clone" [ $"this repo is a fork of (ansi cyan)($msg)(ansi reset) because they share the same root commit: (ansi magenta)($repo.root_hash)(ansi reset)\n" + ( $forks | get path | each { - let repo = $in - | str replace (get-repo-store-path) '' - | str trim --left --char "/" + let repo = $in | path remove-prefix (get-repo-store-path) $"- (ansi cyan)($repo)(ansi reset)" } | str join "\n" ) @@ -193,9 +191,7 @@ export def "gm list" [ if $full_path { open-cache $cache_file | get path } else { - open-cache $cache_file | get path | each { - str replace (get-repo-store-path) '' | str trim --left --char "/" - } + open-cache $cache_file | get path | path remove-prefix (get-repo-store-path) } } @@ -302,11 +298,7 @@ export def "gm remove" [ --no-confirm # do not ask for confirmation: useful in scripts but requires a single match ]: nothing -> nothing { let root = get-repo-store-path - let choices = gm list - | each { - str replace $root '' | str trim --left --char "/" - } - | find $pattern + let choices = gm list | path remove-prefix $root | find $pattern let repo_to_remove = match ($choices | length) { 0 => { @@ -438,8 +430,7 @@ export def "gm squash-forks" [ let default = $non_interactive_preselect | get --ignore-errors $forks.root_hash.0 let main = if $default == null { let choice = $forks.path - | str replace $status.root.path '' - | str trim --char '/' + | path remove-prefix $status.root.path | input list $"Please choose a main fork to squash ($forks.root_hash.0)" if ($choice | is-empty) { log warning $"skipping ($forks.root_hash.0)" @@ -458,7 +449,7 @@ export def "gm squash-forks" [ let fork_origin = list-remotes $fork | where remote == "origin" | into record let fork_name = $fork | path split | reverse | get 1 - let fork_full_name = $fork | str replace $status.root.path '' | str trim --char '/' + let fork_full_name = $fork | path remove-prefix $status.root.path log debug $" squashing ($fork_full_name)" diff --git a/tests/mod.nu b/tests/mod.nu index 5bd39bb1..200f163c 100644 --- a/tests/mod.nu +++ b/tests/mod.nu @@ -7,13 +7,30 @@ use ../src/nu-git-manager/fs/cache.nu [ get-repo-store-cache-path, check-cache-file, add-to-cache, remove-from-cache, open-cache, save-cache, clean-cache-dir ] -use ../src/nu-git-manager/fs/path.nu "path sanitize" +use ../src/nu-git-manager/fs/path.nu [ + "path sanitize", "path remove-prefix", "path remove-trailing-path-sep" +] use ../src/nu-git-manager/fs/dir.nu [clean-empty-directories-rec] use common/setup.nu [get-random-test-dir] -export def path-sanitization [] { - assert equal ('\foo\bar' | path sanitize) "/foo/bar" +export module path { + export def sanitization [] { + assert equal ('\foo\bar' | path sanitize) "/foo/bar" + } + + export def remove-prefix [] { + assert equal ("/foo/bar" | path remove-prefix "/foo") "bar" + assert equal ("/foo/bar" | path remove-prefix "/bar") "/foo/bar" + assert equal ("/foo/bar/baz" | path remove-prefix "/foo") "bar/baz" + assert equal (["/foo/bar", "/foo/bar/baz"] | path remove-prefix "/foo") ["bar", "bar/baz"] + } + + export def remove-trailing-path-sep [] { + assert equal ("/foo/bar/" | path remove-trailing-path-sep) "/foo/bar" + assert equal ("/foo/bar" | path remove-trailing-path-sep) "/foo/bar" + assert equal (["/foo/bar", "/foo/bar/"] | path remove-trailing-path-sep) ["/foo/bar", "/foo/bar"] + } } export def git-url-parsing [] { @@ -158,13 +175,9 @@ export def list-all-repos-in-store [] { } # NOTE: remove the path to BASE so that the test output is easy to read - let actual = with-env {GIT_REPOS_HOME: $BASE} { list-repos-in-store } | each { - str replace $BASE '' | str trim --left --char "/" - } - let expected = $store | where in_store | get path | each { - # NOTE: `list-repos-in-store` does not add `/` at the end of the paths - str trim --right --char "/" - } + let actual = with-env {GIT_REPOS_HOME: $BASE} { list-repos-in-store } | path remove-prefix $BASE + # NOTE: `list-repos-in-store` does not add `/` at the end of the paths + let expected = $store | where in_store | get path | path remove-trailing-path-sep # NOTE: need to sort the result to make sure the order of the `git init` does not influence the # results of the test @@ -184,16 +197,11 @@ export def cache-manipulation [] { } def "assert cache" [cache: list]: nothing -> nothing { - let actual = open-cache $CACHE - | update path { str replace (pwd | path sanitize) '' | str trim --left --char '/' } + let actual = open-cache $CACHE | update path { path remove-prefix (pwd | path sanitize) } let expected = $cache | each {|it| $BASE_REPO | update path { - $it - | path expand - | path sanitize - | str replace (pwd | path sanitize) '' - | str trim --left --char '/' + $it | path expand | path sanitize | path remove-prefix (pwd | path sanitize) } } assert equal $actual $expected @@ -330,8 +338,8 @@ export def store-cleaning [] { $path } | clean-empty-directories-rec - | str replace ($env.GIT_REPOS_HOME | path sanitize) '' - | str trim --char '/' + | path remove-prefix ($env.GIT_REPOS_HOME | path sanitize) + | path remove-trailing-path-sep let expected = [ "foo/bar", "bar", @@ -339,7 +347,7 @@ export def store-cleaning [] { "foo", "baz/foo", "baz", - "", + ($env.GIT_REPOS_HOME | path sanitize), ] assert equal $actual $expected