Skip to content

Commit 059d74e

Browse files
authored
Rename path replace-extension to path with-extension, add with-stem and with-parent (#1011)
Extends #1002. Renames `path replace-extension` to `path with-extension`, in following with other languages ([Rust](https://doc.rust-lang.org/std/path/struct.Path.html#method.with_extension), [Python](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.with_suffix)), and adds `path with-stem` and `path with-parent`. Also moves the `path` module into `std-rfc` so it can be used like `use std-rfc/path`. Adds a private helper function, `with-field`, that `with-extension`, `with-stem`, and `with-parent` can use. These can each be dead simple functions, while giving users more options for path manipulation. The motivation for separate `with-extension`, `with-stem`, and `with-parent` functions, rather than a more general function like `path with` is the following: - `with-extension` has special behavior for stripping periods - you can tab-complete `path with<TAB>` to immediately see all the possible options - you can't accidentally pass an invalid field to `path with` - there can be separate examples for `with-extension`, `with-stem`, `with-parent` for only the relevant functionality
1 parent 66c9995 commit 059d74e

File tree

3 files changed

+96
-37
lines changed

3 files changed

+96
-37
lines changed

stdlib-candidate/path/mod.nu

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Helper function for `path with` commands
2+
def with-field [field: string, value: string] {
3+
path parse
4+
| update $field $value
5+
| path join
6+
}
7+
8+
# Replace extension of input file paths.
9+
#
10+
# Note that it doesn't change the file name locally.
11+
#
12+
# # Example
13+
# - setting path ext to `rs`
14+
# ```nushell
15+
# > "ab.txt" | path with-extension "rs"
16+
# ab.rs
17+
# > "ab.txt" | path with-extension ".rs"
18+
# ab.rs
19+
#
20+
# - setting a list of input path ext to `rs`
21+
# > ["ab.txt", "cd.exe"] | path with-extension "rs"
22+
# ╭───┬──────────╮
23+
# │ 0 │ ab.rs │
24+
# │ 1 │ cd.rs │
25+
# ╰───┴──────────╯
26+
# ```
27+
export def with-extension [ext: string] {
28+
let path = $in
29+
let ext_trim = if $ext starts-with "." {
30+
$ext | str substring 1..
31+
} else {
32+
$ext
33+
}
34+
$path | with-field extension $ext_trim
35+
}
36+
37+
# Replace stem of input file paths.
38+
#
39+
# Note that it doesn't change the file name locally.
40+
#
41+
# # Example
42+
# - replace stem with "share"
43+
# ```nushell
44+
# > "/usr/bin" | path with-stem "share"
45+
# /usr/share
46+
#
47+
# - replace stem with "nushell"
48+
# > ["/home/alice/", "/home/bob/secret.txt"] | path with-stem "nushell"
49+
# ╭───┬───────────────────────╮
50+
# │ 0 │ /home/nushell │
51+
# │ 1 │ /home/bob/nushell.txt │
52+
# ╰───┴───────────────────────╯
53+
# ```
54+
export def with-stem [stem: string] { with-field stem $stem }
55+
56+
# Replace parent field of input file paths.
57+
#
58+
# # Example
59+
# - replace parent path with `/usr/share`
60+
# ```nushell
61+
# > "/etc/foobar" | path with-parent "/usr/share/"
62+
# /usr/share/foobar
63+
#
64+
# - replace parent path with `/root/` for all filenames in list
65+
# > ["/home/rose/meow", "/home/fdncred/"] | path with-parent "/root/"
66+
# ╭───┬────────────╮
67+
# │ 0 │ /root/meow │
68+
# │ 1 │ /root/spam │
69+
# ╰───┴────────────╯
70+
# ```
71+
export def with-parent [parent: string] { with-field parent $parent }

stdlib-candidate/tests/path.nu

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,39 @@
1-
use path
1+
use std-rfc/path
22
use std/assert
33

44
#[test]
5-
def path_replace_extension [] {
6-
let new_path = "ab.txt" | path replace-extension "rs"
5+
def path_with_extension [] {
6+
let new_path = "ab.txt" | path with-extension "rs"
77
assert equal $new_path "ab.rs"
88

9-
let new_path = "ab.txt" | path replace-extension ".rs"
9+
let new_path = "ab.txt" | path with-extension ".rs"
1010
assert equal $new_path "ab.rs"
1111
}
1212

1313
#[test]
14-
def path_replace_extension_for_list [] {
15-
let new_path = ["ab.txt", "cd.exe"] | path replace-extension "rs"
14+
def path_with_extension_for_list [] {
15+
let new_path = ["ab.txt", "cd.exe"] | path with-extension "rs"
1616
assert equal $new_path ["ab.rs", "cd.rs"]
1717

1818

19-
let new_path = ["ab.txt", "cd.exe"] | path replace-extension ".rs"
19+
let new_path = ["ab.txt", "cd.exe"] | path with-extension ".rs"
2020
assert equal $new_path ["ab.rs", "cd.rs"]
2121
}
22+
23+
#[test]
24+
def path_with_stem [] {
25+
let new_path = "/usr/bin" | path with-stem "share"
26+
assert equal $new_path "/usr/share"
27+
28+
let new_path = ["/home/alice/", "/home/bob/secret.txt"] | path with-stem "nushell"
29+
assert equal $new_path ["/home/nushell", "/home/bob/nushell.txt"]
30+
}
31+
32+
#[test]
33+
def path_with_parent [] {
34+
let new_path = "/etc/foobar" | path with-parent "/usr/share/"
35+
assert equal $new_path "/usr/share/foobar"
36+
37+
let new_path = ["/home/rose/meow", "/home/fdncred/"] | path with-parent "/root/"
38+
assert equal $new_path ["/root/meow", "/root/fdncred"]
39+
}

0 commit comments

Comments
 (0)