mirror of
https://github.com/nushell/nu_scripts.git
synced 2024-08-16 08:50:31 +03:00
Refactor stdlib-candidate for nupm (#790)
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 <new-branch-name> 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. ```
This commit is contained in:
parent
13a73ab635
commit
cf88c11509
@ -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
|
||||
}
|
8
stdlib-candidate/nupm.nuon
Normal file
8
stdlib-candidate/nupm.nuon
Normal file
@ -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"
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
# Merge a list of records
|
||||
export def "list merge" []: list<record> -> 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}
|
||||
}
|
35
stdlib-candidate/std-rfc/fs.nu
Normal file
35
stdlib-candidate/std-rfc/fs.nu
Normal file
@ -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
|
||||
}
|
6
stdlib-candidate/std-rfc/mod.nu
Normal file
6
stdlib-candidate/std-rfc/mod.nu
Normal file
@ -0,0 +1,6 @@
|
||||
# modules
|
||||
export module record/
|
||||
export module str.nu
|
||||
# commands
|
||||
export use fs.nu *
|
||||
export use set-env.nu *
|
46
stdlib-candidate/std-rfc/record/mod.nu
Normal file
46
stdlib-candidate/std-rfc/record/mod.nu
Normal file
@ -0,0 +1,46 @@
|
||||
# Merge a list of records
|
||||
export def "list merge" []: list<record> -> 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
|
||||
}
|
17
stdlib-candidate/std-rfc/str.nu
Normal file
17
stdlib-candidate/std-rfc/str.nu
Normal file
@ -0,0 +1,17 @@
|
||||
export def append [tail: string]: [string -> string, list<string> -> list<string>] {
|
||||
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<string> -> list<string>] {
|
||||
let input = $in
|
||||
match ($input | describe | str replace --regex '<.*' '') {
|
||||
"string" => { $head ++ $input },
|
||||
"list" => { $input | each {|el| $head ++ $el } },
|
||||
_ => $input
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
def "str append" [tail: string]: [string -> string, list<string> -> list<string>] {
|
||||
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<string> -> list<string>] {
|
||||
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"]
|
||||
|
||||
}
|
50
stdlib-candidate/tests/fs.nu
Normal file
50
stdlib-candidate/tests/fs.nu
Normal file
@ -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
|
||||
}
|
3
stdlib-candidate/tests/mod.nu
Normal file
3
stdlib-candidate/tests/mod.nu
Normal file
@ -0,0 +1,3 @@
|
||||
export module fs.nu
|
||||
export module record.nu
|
||||
export module str.nu
|
20
stdlib-candidate/tests/record.nu
Normal file
20
stdlib-candidate/tests/record.nu
Normal file
@ -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}
|
||||
}
|
12
stdlib-candidate/tests/str.nu
Normal file
12
stdlib-candidate/tests/str.nu
Normal file
@ -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"]
|
||||
}
|
Loading…
Reference in New Issue
Block a user