From cf88c1150988df0280288ce6c49b8b8a4c538449 Mon Sep 17 00:00:00 2001 From: Texas Toland Date: Sat, 16 Mar 2024 06:57:05 -0500 Subject: [PATCH] Refactor stdlib-candidate for nupm (#790) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Easier to review individual commits because of renames. Happy to provide DiffNow links if helpful. Involved: 1. Moving scripts to a subdirectory 2. Copying `nupm.nuon` from another directory 3. Making modules work 4. Extracting tests 5. Fixing tests (related to nushell/nushell#12193) To test first set up nupm then: ```console nu_scripts on  std-nupm-integration ❯ $env.NUPM_REGISTRIES.nupm_test = 'https://raw.githubusercontent.com/texastoland/nupm/registry-std-rfc/registry.nuon' nu_scripts on  std-nupm-integration ❯ nupm install std-rfc ╭──────────┬───────────────────────────────────────────╮ │ name │ std-rfc │ │ version │ 0.1.0 │ │ url │ https://github.com/texastoland/nu_scripts │ │ revision │ 65aa7cc │ │ path │ stdlib-candidate │ │ type │ git │ ╰──────────┴───────────────────────────────────────────╯ Cloning into 'nu_scripts-4a047f13a05fe35393f3a8d73377b02c-65aa7cc'... remote: Enumerating objects: 8015, done. remote: Counting objects: 100% (822/822), done. remote: Compressing objects: 100% (333/333), done. remote: Total 8015 (delta 538), reused 641 (delta 445), pack-reused 7193 Receiving objects: 100% (8015/8015), 49.72 MiB | 23.12 MiB/s, done. Resolving deltas: 100% (4605/4605), done. Note: switching to '65aa7cc'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at 65aa7cc Fix nupm test --dir stdlib-candidate 2024-03-12T20:42:49.462|INF|installing package std-rfc nu_scripts on  std-nupm-integration took 4s ❯ use std-rfc set-env nu_scripts on  std-nupm-integration ❯ set-env -h Gracefully set an environment variable or merge a nested option. ...etc. nu_scripts on  std-nupm-integration ❯ nupm test --dir stdlib-candidate Testing package /Users/texas/Developer/nu_scripts/stdlib-candidate tests record filter-name predicate ... SUCCESS tests record filter-value predicate ... SUCCESS tests record list_merge ... SUCCESS tests str append ... SUCCESS tests fs file bulk-rename ... SUCCESS tests str prepend ... SUCCESS tests record filter-name text ... SUCCESS Ran 7 tests. 7 succeeded, 0 failed. ``` --- stdlib-candidate/fs.nu | 84 ------------------- stdlib-candidate/nupm.nuon | 8 ++ stdlib-candidate/record/mod.nu | 69 --------------- stdlib-candidate/std-rfc/fs.nu | 35 ++++++++ stdlib-candidate/std-rfc/mod.nu | 6 ++ .../{ => std-rfc}/record/README.md | 0 stdlib-candidate/std-rfc/record/mod.nu | 46 ++++++++++ stdlib-candidate/{ => std-rfc}/set-env.nu | 0 stdlib-candidate/std-rfc/str.nu | 17 ++++ stdlib-candidate/str.nu | 33 -------- stdlib-candidate/tests/fs.nu | 50 +++++++++++ stdlib-candidate/tests/mod.nu | 3 + stdlib-candidate/tests/record.nu | 20 +++++ stdlib-candidate/tests/str.nu | 12 +++ 14 files changed, 197 insertions(+), 186 deletions(-) delete mode 100644 stdlib-candidate/fs.nu create mode 100644 stdlib-candidate/nupm.nuon delete mode 100644 stdlib-candidate/record/mod.nu create mode 100644 stdlib-candidate/std-rfc/fs.nu create mode 100644 stdlib-candidate/std-rfc/mod.nu rename stdlib-candidate/{ => std-rfc}/record/README.md (100%) create mode 100644 stdlib-candidate/std-rfc/record/mod.nu rename stdlib-candidate/{ => std-rfc}/set-env.nu (100%) create mode 100644 stdlib-candidate/std-rfc/str.nu delete mode 100644 stdlib-candidate/str.nu create mode 100644 stdlib-candidate/tests/fs.nu create mode 100644 stdlib-candidate/tests/mod.nu create mode 100644 stdlib-candidate/tests/record.nu create mode 100644 stdlib-candidate/tests/str.nu diff --git a/stdlib-candidate/fs.nu b/stdlib-candidate/fs.nu deleted file mode 100644 index 70b3fc4e..00000000 --- a/stdlib-candidate/fs.nu +++ /dev/null @@ -1,84 +0,0 @@ -# rename a bulk of files in a directory using a closure -# -# the reason behind this command is quite simple -# - sometimes one receives a bunch of files with integer ids: 1, 2, 3, ... -# - these ids come rarely with padding... i.e. 1 instead of 001 when there are 3-digit ids -# - this means that file with id 9 will be sorted way after file with id 1000 -# -# this command allows to do such a task! -# -# # Examples -# rename files in `/foo` with a name that has an id to have 3 digits with 0-padding -# > file bulk-rename /foo { -# parse "some_format_{id}" -# | get 0 -# | update id { fill --alignment r --character 0 --width 3 } -# | $"some_format_($in.id)" -# } -export def "file bulk-rename" [ - directory: path, # the path where files need to be renamed in bulk - stem_update: closure, # the code to run on the stem of the files: should start with parsing the format and end with reconstructing the same format - --verbose, # be verbose when moving the files around -]: nothing -> nothing { - ls --full-paths $directory | insert new { - get name | path parse | update stem $stem_update | path join - } - | each { - if $verbose { - mv --force --verbose $in.name $in.new - } else { - mv --force $in.name $in.new - } - } - - null -} - -#[test] -def test [] { - use std assert - - let test_dir = $nu.temp-path | path join (random uuid) - - mkdir $test_dir - seq 1 10 | each {|i| touch ($test_dir | path join $"some_($i)_format.txt") } - - let expected = [ - "some_10_format.txt", - "some_1_format.txt", - "some_2_format.txt", - "some_3_format.txt", - "some_4_format.txt", - "some_5_format.txt", - "some_6_format.txt", - "some_7_format.txt", - "some_8_format.txt", - "some_9_format.txt", - ] - let actual = glob $"($test_dir)/*" | str replace $test_dir "" | str trim --left --char "/" - assert equal ($actual | sort) $expected - - file bulk-rename $test_dir { - parse "some_{i}_format" - | get 0 - | update i { fill --alignment r --character 0 --width 3 } - | $"some_($in.i)_format" - } - - let expected = [ - "some_001_format.txt", - "some_002_format.txt", - "some_003_format.txt", - "some_004_format.txt", - "some_005_format.txt", - "some_006_format.txt", - "some_007_format.txt", - "some_008_format.txt", - "some_009_format.txt", - "some_010_format.txt", - ] - let actual = glob $"($test_dir)/*" | str replace $test_dir "" | str trim --left --char "/" - assert equal ($actual | sort) $expected - - rm -rf $test_dir -} diff --git a/stdlib-candidate/nupm.nuon b/stdlib-candidate/nupm.nuon new file mode 100644 index 00000000..1f0c6b61 --- /dev/null +++ b/stdlib-candidate/nupm.nuon @@ -0,0 +1,8 @@ +{ + name: "std-rfc" + description: "Official candidates for Nushell standard library" + documentation: "https://github.com/nushell/nu_scripts/blob/main/stdlib-candidate/std-rfc/README.md" + license: "https://github.com/nushell/nu_scripts/blob/main/LICENSE" + version: 0.1.0 + type: "module" +} diff --git a/stdlib-candidate/record/mod.nu b/stdlib-candidate/record/mod.nu deleted file mode 100644 index f4a3db52..00000000 --- a/stdlib-candidate/record/mod.nu +++ /dev/null @@ -1,69 +0,0 @@ -# Merge a list of records -export def "list merge" []: list -> record { - let list = $in - mut result = {} - for $obj in $list { - $result = ($result | merge $obj) - } - $result -} - -# Filter fields name by predicate -export def "filter-name predicate" [ - pred: closure # Predicate closure that checks fields name -]: record -> record { - let $obj_input = $in - $obj_input - | columns - | where { $in | do $pred } - | each {|input| - { $input: ($obj_input | get $input) } - } - | list merge -} - -# Filter fields name by text checking -export def "filter-name text" [ - filter: string # Text to match with - --regex(-r) # Match by regex -]: record -> record { - let obj = $in - $obj | filter-name predicate { not ($in | (if $regex {find -r $filter} else {find $filter}) | is-empty) } -} - -# Filter fields value by predicate -export def "filter-value predicate" [ - pred: closure # Predicate closure that checks fields value -]: record -> record { - let $obj_input = $in - $obj_input - | columns - | where {|col| $obj_input | get $col | do $pred } - | each {|input| - { $input: ($obj_input | get $input) } - } - | list merge -} - -#[test] -def test_record_list_merge [] { - use std assert - assert equal ([{a:1} {b:2} {c:3} {d:4}] | list merge) {a:1 b:2 c:3 d:4} -} -#[test] -def test_record_filtername_predicate [] { - use std assert - assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name predicate {$in | str contains a}) {aa:1 ab:2 ba:3 ca:5} -} -#[test] -def test_record_filtername_text [] { - use std assert - assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text a) {aa:1 ab:2 ba:3 ca:5} - assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text -r ^a) {aa:1 ab:2} - assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text -r ^A) {} -} -#[test] -def test_record_filtervalue_predicate [] { - use std assert - assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-value predicate { $in mod 2 == 0 }) {ab:2 bb:4 cb:6} -} \ No newline at end of file diff --git a/stdlib-candidate/std-rfc/fs.nu b/stdlib-candidate/std-rfc/fs.nu new file mode 100644 index 00000000..e2fce521 --- /dev/null +++ b/stdlib-candidate/std-rfc/fs.nu @@ -0,0 +1,35 @@ +# rename a bulk of files in a directory using a closure +# +# the reason behind this command is quite simple +# - sometimes one receives a bunch of files with integer ids: 1, 2, 3, ... +# - these ids come rarely with padding... i.e. 1 instead of 001 when there are 3-digit ids +# - this means that file with id 9 will be sorted way after file with id 1000 +# +# this command allows to do such a task! +# +# # Examples +# rename files in `/foo` with a name that has an id to have 3 digits with 0-padding +# > file bulk-rename /foo { +# parse "some_format_{id}" +# | get 0 +# | update id { fill --alignment r --character 0 --width 3 } +# | $"some_format_($in.id)" +# } +export def "file bulk-rename" [ + directory: path, # the path where files need to be renamed in bulk + stem_update: closure, # the code to run on the stem of the files: should start with parsing the format and end with reconstructing the same format + --verbose, # be verbose when moving the files around +]: nothing -> nothing { + ls --full-paths $directory | insert new {|row| + $row.name | path parse | update stem $stem_update | path join + } + | each { + if $verbose { + mv --force --verbose $in.name $in.new + } else { + mv --force $in.name $in.new + } + } + + null +} diff --git a/stdlib-candidate/std-rfc/mod.nu b/stdlib-candidate/std-rfc/mod.nu new file mode 100644 index 00000000..e4e473b6 --- /dev/null +++ b/stdlib-candidate/std-rfc/mod.nu @@ -0,0 +1,6 @@ +# modules +export module record/ +export module str.nu +# commands +export use fs.nu * +export use set-env.nu * diff --git a/stdlib-candidate/record/README.md b/stdlib-candidate/std-rfc/record/README.md similarity index 100% rename from stdlib-candidate/record/README.md rename to stdlib-candidate/std-rfc/record/README.md diff --git a/stdlib-candidate/std-rfc/record/mod.nu b/stdlib-candidate/std-rfc/record/mod.nu new file mode 100644 index 00000000..348a3cba --- /dev/null +++ b/stdlib-candidate/std-rfc/record/mod.nu @@ -0,0 +1,46 @@ +# Merge a list of records +export def "list merge" []: list -> record { + let list = $in + mut result = {} + for $obj in $list { + $result = ($result | merge $obj) + } + $result +} + +# Filter fields name by predicate +export def "filter-name predicate" [ + pred: closure # Predicate closure that checks fields name +]: record -> record { + let $obj_input = $in + $obj_input + | columns + | where { $in | do $pred } + | each {|input| + { $input: ($obj_input | get $input) } + } + | list merge +} + +# Filter fields name by text checking +export def "filter-name text" [ + filter: string # Text to match with + --regex(-r) # Match by regex +]: record -> record { + let obj = $in + $obj | filter-name predicate { not ($in | (if $regex {find -r $filter} else {find $filter}) | is-empty) } +} + +# Filter fields value by predicate +export def "filter-value predicate" [ + pred: closure # Predicate closure that checks fields value +]: record -> record { + let $obj_input = $in + $obj_input + | columns + | where {|col| $obj_input | get $col | do $pred } + | each {|input| + { $input: ($obj_input | get $input) } + } + | list merge +} diff --git a/stdlib-candidate/set-env.nu b/stdlib-candidate/std-rfc/set-env.nu similarity index 100% rename from stdlib-candidate/set-env.nu rename to stdlib-candidate/std-rfc/set-env.nu diff --git a/stdlib-candidate/std-rfc/str.nu b/stdlib-candidate/std-rfc/str.nu new file mode 100644 index 00000000..9c182b1e --- /dev/null +++ b/stdlib-candidate/std-rfc/str.nu @@ -0,0 +1,17 @@ +export def append [tail: string]: [string -> string, list -> list] { + let input = $in + match ($input | describe | str replace --regex '<.*' '') { + "string" => { $input ++ $tail }, + "list" => { $input | each {|el| $el ++ $tail} }, + _ => $input + } +} + +export def prepend [head: string]: [string -> string, list -> list] { + let input = $in + match ($input | describe | str replace --regex '<.*' '') { + "string" => { $head ++ $input }, + "list" => { $input | each {|el| $head ++ $el } }, + _ => $input + } +} diff --git a/stdlib-candidate/str.nu b/stdlib-candidate/str.nu deleted file mode 100644 index 17f054a7..00000000 --- a/stdlib-candidate/str.nu +++ /dev/null @@ -1,33 +0,0 @@ -def "str append" [tail: string]: [string -> string, list -> list] { - let input = $in - match ($input | describe | str replace --regex '<.*' '') { - "string" => { $input ++ $tail }, - "list" => { $input | each {|el| $el ++ $tail} }, - _ => $input - } -} - -def "str prepend" [head: string]: [string -> string, list -> list] { - let input = $in - match ($input | describe | str replace --regex '<.*' '') { - "string" => { $head ++ $input }, - "list" => { $input | each {|el| $head ++ $el } }, - _ => $input - } -} - -#[test] -def test_append [] { - use std assert - assert equal ("foo" | str append "/") "foo/" - assert equal (["foo", "bar", "baz"] | str append "/") ["foo/", "bar/", "baz/"] - -} - -#[test] -def test_prepend [] { - use std assert - assert equal ("foo" | str prepend "/") "/foo" - assert equal (["foo", "bar", "baz"] | str prepend "/") ["/foo", "/bar", "/baz"] - -} diff --git a/stdlib-candidate/tests/fs.nu b/stdlib-candidate/tests/fs.nu new file mode 100644 index 00000000..9af5659f --- /dev/null +++ b/stdlib-candidate/tests/fs.nu @@ -0,0 +1,50 @@ +use std assert +use ../std-rfc "file bulk-rename" + +alias rename = file bulk-rename + +export def "test file bulk-rename" [] { + let test_dir = $nu.temp-path | path join (random uuid) + + mkdir $test_dir + seq 1 10 | each {|i| touch ($test_dir | path join $"some_($i)_format.txt") } + + let expected = [ + "some_10_format.txt", + "some_1_format.txt", + "some_2_format.txt", + "some_3_format.txt", + "some_4_format.txt", + "some_5_format.txt", + "some_6_format.txt", + "some_7_format.txt", + "some_8_format.txt", + "some_9_format.txt", + ] + let actual = glob $"($test_dir)/*" | str replace $test_dir "" | str trim --left --char "/" + assert equal ($actual | sort) $expected + + rename $test_dir { + parse "some_{i}_format" + | get 0 + | update i { fill --alignment r --character 0 --width 3 } + | $"some_($in.i)_format" + } + + let expected = [ + "some_001_format.txt", + "some_002_format.txt", + "some_003_format.txt", + "some_004_format.txt", + "some_005_format.txt", + "some_006_format.txt", + "some_007_format.txt", + "some_008_format.txt", + "some_009_format.txt", + "some_010_format.txt", + ] + let actual = glob $"($test_dir)/*" | str replace $test_dir "" | str trim --left --char "/" + assert equal ($actual | sort) $expected + + rm -rf $test_dir +} diff --git a/stdlib-candidate/tests/mod.nu b/stdlib-candidate/tests/mod.nu new file mode 100644 index 00000000..8f03760e --- /dev/null +++ b/stdlib-candidate/tests/mod.nu @@ -0,0 +1,3 @@ +export module fs.nu +export module record.nu +export module str.nu diff --git a/stdlib-candidate/tests/record.nu b/stdlib-candidate/tests/record.nu new file mode 100644 index 00000000..f297076e --- /dev/null +++ b/stdlib-candidate/tests/record.nu @@ -0,0 +1,20 @@ +use std assert +use ../std-rfc record + +export def "test list_merge" [] { + assert equal ([{a:1} {b:2} {c:3} {d:4}] | record list merge) {a:1 b:2 c:3 d:4} +} + +export def "test filter-name predicate" [] { + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | record filter-name predicate {$in | str contains a}) {aa:1 ab:2 ba:3 ca:5} +} + +export def "test filter-name text" [] { + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | record filter-name text a) {aa:1 ab:2 ba:3 ca:5} + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | record filter-name text -r ^a) {aa:1 ab:2} + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | record filter-name text -r ^A) {} +} + +export def "test filter-value predicate" [] { + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | record filter-value predicate { $in mod 2 == 0 }) {ab:2 bb:4 cb:6} +} diff --git a/stdlib-candidate/tests/str.nu b/stdlib-candidate/tests/str.nu new file mode 100644 index 00000000..0c839886 --- /dev/null +++ b/stdlib-candidate/tests/str.nu @@ -0,0 +1,12 @@ +use std assert +use ../std-rfc str + +export def "test append" [] { + assert equal ("foo" | str append "/") "foo/" + assert equal (["foo", "bar", "baz"] | str append "/") ["foo/", "bar/", "baz/"] +} + +export def "test prepend" [] { + assert equal ("foo" | str prepend "/") "/foo" + assert equal (["foo", "bar", "baz"] | str prepend "/") ["/foo", "/bar", "/baz"] +}