Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toolkit.nu in nushell repo root problems #1

Closed
fdncred opened this issue Oct 31, 2024 · 26 comments
Closed

toolkit.nu in nushell repo root problems #1

fdncred opened this issue Oct 31, 2024 · 26 comments

Comments

@fdncred
Copy link

fdncred commented Oct 31, 2024

First of all, I'm super excited for this. I realize it's not 100% yet because tree-sitter-nu isn't 100% yet but I'm still excited nonetheless.

When I tried to run topiary fmt toolkit.nu from the nushell repo root. It produces this error.

❯ topiary fmt toolkit.nu
[2024-10-31T12:42:20Z ERROR topiary] Nickel error: ParseErrors(ParseErrors { errors: [InvalidEscapeSequence(RawSpan { src_id: FileId(2), start: ByteIndex(33), end: ByteIndex(34) })] })

I haven't dug in to see what's going on yet, but I thought I'd post it.

Thanks for working on this and supporting nushell! ❤️

@fdncred
Copy link
Author

fdncred commented Oct 31, 2024

Hmmm, this could be because it's not finding the config file or something like that? Seems like it's ignoring my $env.TOPIARY_blah settings. 🤔

@fdncred
Copy link
Author

fdncred commented Oct 31, 2024

I think it's finding my config now, but I have no idea what's going on here and why it things the languages.ncl is invalid. It looks good to me.

❯ topiary config
[2024-10-31T13:05:46Z ERROR topiary] Nickel error: ParseErrors(ParseErrors { errors: [InvalidEscapeSequence(RawSpan { src_id: FileId(2), start: ByteIndex(33), end: ByteIndex(34) })] })

@blindFS
Copy link
Owner

blindFS commented Oct 31, 2024

I think your topiary version is out of date, maybe try to install the github version with cargo?

@blindFS
Copy link
Owner

blindFS commented Oct 31, 2024

@fdncred Current style is a little bit off the track from the guideline, but that's the easy part.

@fdncred
Copy link
Author

fdncred commented Oct 31, 2024

I think your topiary version is out of date, maybe try to install the github version with cargo?

That was definitely the case. Now it just doesn't compile on Windows.

C:\Users\username\source\repos\forks\nushell [main ≡]> topiary fmt .\toolkit.nu
Cloning into 'D:\Temp\.tmpvgbYQS\nushell'...
remote: Enumerating objects: 1407, done.
remote: Counting objects: 100% (409/409), done.
remote: Compressing objects: 100% (89/89), done.
remote: Total 1407 (delta 327), reused 326 (delta 316), pack-reused 998 (from 1)
Receiving objects: 100% (1407/1407), 28.69 MiB | 13.20 MiB/s, done.
Resolving deltas: 100% (810/810), done.
Note: switching to '1561a947a5505d373e11ca337898e048ac2e389e'.

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 1561a94 Allow variables as external command (#127)
[2024-10-31T15:21:03Z ERROR topiary] Error Fetching Language: Subprocess("\"parser.c\\r\\n   Creating library C:\\\\Users\\\\username\\\\AppData\\\\Local\\\\topiary\\\\cache\\\\nushell\\\\1561a947a5505d373e11ca337898e048ac2e389e.lib and object C:\\\\Users\\\\username\\\\AppData\\\\Local\\\\topiary\\\\cache\\\\nushell\\\\1561a947a5505d373e11ca337898e048ac2e389e.exp\\r\\nLINK : fatal error LNK1561: entry point must be defined\\r\\n\", \"cl : Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release\\r\\ncl : Command line warning D9002 : ignoring unknown option '-shared'\\r\\ncl : Command line warning D9002 : ignoring unknown option '-fPIC'\\r\\ncl : Command line warning D9002 : ignoring unknown option '-fno-exceptions'\\r\\ncl : Command line warning D9002 : ignoring unknown option '-xc'\\r\\ncl : Command line warning D9002 : ignoring unknown option '-std=c11'\\r\\n\"")

@blindFS
Copy link
Owner

blindFS commented Dec 3, 2024

Just found out that latest topiary supports referring grammar to local path like this:

  grammar = {
    # source.git = {
    #   git = "https://github.com/nushell/tree-sitter-nu.git",
    #   rev = "7e0f16f608a9e804fae61430ade734f9f849fb80",
    # },
    source.path = "<local-directory>/libtree-sitter-nu.dylib",
    symbol = "tree_sitter_nu",
  },

Maybe you can try manually compiling the parser with make on windows.

Remember to checkout the commit above since the latest grammar is not well-supported by this project (still struggling with annoying whitespaces issues).

@fdncred
Copy link
Author

fdncred commented Dec 3, 2024

Interesting. I was able to get it to do something at least.

  1. make/nmake doesn't work with the makefile
  2. tree-sitter build works fine and creates a nu.dll
  3. added source.path to nu.dll
  4. topiary format file.nu doesn't work, gives errors. sharing violation i assume
  5. open file.nu | topiary format --language nushell --verbose --tolerate-parsing-errors works and prints to the screen

I did all that on the hash you specified above. On the latest main I get this:

❯ open toolkit.nu | topiary format --language nushell --verbose --tolerate-parsing-errors
[2024-12-03T17:03:03Z ERROR topiary] Error parsing query file
[2024-12-03T17:03:03Z ERROR topiary] Cause: QueryError { row: 4, column: 7, offset: 65, message: "long_flag_equals_value", kind: NodeType }

@blindFS
Copy link
Owner

blindFS commented Dec 3, 2024

You need to run tree-sitter generate before the build, otherwise the grammar is still the latest.

Make doesn't require that because it directly use the generated c files, which is git tracked.

Actually I'm not sure how tree-sitter build works, but the error message definitely suggests that the built parser is newer than that commit point, maybe even need to cleanup something before tree-sitter generate.

@blindFS
Copy link
Owner

blindFS commented Dec 3, 2024

ifeq ($(OS),Windows_NT)
$(error Windows is not supported)
endif

Aha, so the makefile is designed to not work on windows, interesting.

@fdncred
Copy link
Author

fdncred commented Dec 3, 2024

ifeq ($(OS),Windows_NT)
$(error Windows is not supported)
endif

Aha, so the makefile is designed to not work on windows, interesting.

Ya, I noticed that too.

You need to run tree-sitter generate before the build, otherwise the grammar is still the latest.

I tried that and it didn't make a difference.

 tree-sitter generate
 rm nu.dll
 tree-sitter build
 z nush
toolkit module detected...
activating toolkit module with `use toolkit.nu`
 open toolkit.nu | topiary format --language nushell --verbose --tolerate-parsing-errors
[2024-12-03T18:07:44Z ERROR topiary] Error parsing query file
[2024-12-03T18:07:44Z ERROR topiary] Cause: QueryError { row: 4, column: 7, offset: 65, message: "long_flag_equals_value", kind: NodeType }

@blindFS
Copy link
Owner

blindFS commented Dec 3, 2024

Yeah I realized my guess was wrong, it doesn't make any sense to me, if tree-sitter-nu is at the correct head, it should contain the rule for long-flag-equals-value (removed recently by me).

@blindFS
Copy link
Owner

blindFS commented Dec 20, 2024

@fdncred I think this is now compatible with the latest parser, if you have the tree-sitter-nu dll file compiled.
Would you like to test it again?
Please also reinstall the latest topiary just in case.

I've tested all nu_scripts files (skipped few having parsing errors) with this script

export def test_format [
path: path # path to test
break: bool = false # break on first error
] {
let files = glob $'($path | str trim -r -c '/')/**/*.nu'
let target = "./test.nu"
for file in $files {
try {
cp $file $target
topiary format $target
let errors = nu --ide-check 9999 $target
| lines
| each {$in | from json}
| flatten
| (
where severity? == Error
and message? !~ '((File|Module|Variable) not found|Unknown command)'
)
if ($errors | length) > 0 {
print $errors
}
assert (($errors | length) == 0)
} catch {
print $file
if $break {
break
}
}
}
}
, it works fine for me.

@fdncred
Copy link
Author

fdncred commented Dec 20, 2024

@blindFS I wonder what I'm doing wrong.

  1. I pulled the latest from the topiary repo and installed topiary-cli.
  2. I pulled the latest from the tree-sitter-nu and did tree-sitter generate, tree-sitter build.
  3. I have a nu.dll.
  4. I have these env vars set.
 $env.TOPIARY_CONFIG_FILE
C:/Users/fdncred/source/repos/topiary-nushell/languages.ncl
 $env.TOPIARY_LANGUAGE_DIR
C:/Users/fdncred/source/repos/topiary-nushell/languages
 open toolkit.nu | topiary format --language nushell --verbose --tolerate-parsing-errors
[2024-12-20T14:43:28Z ERROR topiary] Error parsing query file
[2024-12-20T14:43:28Z ERROR topiary] Cause: QueryError { row: 4, column: 7, offset: 65, message: "long_flag_equals_value", kind: NodeType }
 topiary format toolkit.nu
[2024-12-20T14:44:22Z ERROR topiary] Error parsing query file
[2024-12-20T14:44:22Z ERROR topiary] Cause: QueryError { row: 4, column: 7, offset: 65, message: "long_flag_equals_value", kind: NodeType }

@blindFS
Copy link
Owner

blindFS commented Dec 20, 2024

@fdncred This topiary-nushell on main branch with latest commit?
And with languages.ncl 's source path pointed to the dll?
e.g.

{
  languages = {
    nu = {
      extensions = ["nu"],
      grammar.source.path = ".../tree-sitter-nu/nu.dylib",
    },
  },
}

@blindFS
Copy link
Owner

blindFS commented Dec 20, 2024

I think the language name on the main branch has changed to nu. It should report error with --language nushell.

@fdncred
Copy link
Author

fdncred commented Dec 20, 2024

I didn't have the topiary-nushell latest but I do now. This is what I get

This is my languages.ncl

{
  languages = {
    nu = {
      extensions = ["nu"],
      grammar.source.path = "C:/Users/fdncred/source/repos/tree-sitter-nu/nu.dll",
      symbol = "tree_sitter_nu",
    },
  },
}

It tried to do something

❯ topiary format toolkit.nu
[2024-12-20T15:29:41Z ERROR topiary] Could not persist output to disk
[2024-12-20T15:29:41Z ERROR topiary] Cause: Access is denied. (os error 5)

and

❯ open toolkit.nu | topiary format --language nu --verbose --tolerate-parsing-errors
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (14,9) - (14,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (18,9) - (18,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (38,9) - (38,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (47,26) - (47,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (54,9) - (54,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (63,26) - (63,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (68,9) - (68,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (93,9) - (93,13)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (94,13) - (94,22)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (97,45) - (97,53)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (100,13) - (100,22)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (103,38) - (103,46)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (114,50) - (114,60)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (120,52) - (120,54)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (120,52) - (120,54)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,13) - (142,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (143,18) - (143,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (144,18) - (144,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (145,18) - (145,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (146,18) - (146,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (151,14) - (151,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (151,16) - (151,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (151,16) - (151,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (151,16) - (151,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (153,20) - (153,22)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (153,22) - (153,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (153,22) - (153,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (153,22) - (153,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (160,15) - (160,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (160,17) - (160,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (160,17) - (160,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (160,17) - (160,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (160,36) - (160,38)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (160,38) - (160,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (160,38) - (160,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (160,38) - (160,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (259,9) - (259,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (259,9) - (259,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (259,9) - (259,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (260,9) - (260,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (260,9) - (260,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (260,9) - (260,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (261,9) - (261,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (261,9) - (261,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (261,9) - (261,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (270,28) - (270,36)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (277,13) - (277,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (278,18) - (278,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (281,34) - (281,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (284,18) - (284,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (287,34) - (287,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (328,30) - (328,38)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (332,19) - (332,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (332,19) - (332,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (334,33) - (334,39)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (337,19) - (337,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (346,21) - (346,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (348,13) - (348,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (361,20) - (361,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (362,10) - (362,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (393,19) - (393,36)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (394,41) - (394,46)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (396,26) - (396,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (405,19) - (405,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (405,19) - (405,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (407,35) - (407,41)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (410,38) - (410,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (419,42) - (419,50)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (420,13) - (420,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (433,20) - (433,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (434,10) - (434,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (439,8) - (439,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (439,8) - (439,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (439,8) - (439,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (439,16) - (439,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (450,24) - (450,35)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (452,10) - (452,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (453,39) - (453,50)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (457,20) - (457,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (459,36) - (459,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (460,25) - (460,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (462,49) - (462,55)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (462,61) - (462,64)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (462,64) - (462,68)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (462,64) - (462,68)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (462,64) - (462,68)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (520,9) - (520,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (520,9) - (520,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (520,9) - (520,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (525,40) - (525,43)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (525,47) - (525,52)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (536,22) - (536,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (538,19) - (538,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (538,37) - (538,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (540,31) - (540,37)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (540,49) - (540,58)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (542,26) - (542,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (542,26) - (542,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (542,26) - (542,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (543,24) - (543,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (543,52) - (543,61)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (544,24) - (544,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (544,52) - (544,58)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (547,41) - (547,47)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (548,19) - (548,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (549,20) - (549,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (552,41) - (552,50)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (553,19) - (553,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (554,20) - (554,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (558,19) - (558,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (561,26) - (561,37)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (562,23) - (562,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (563,7) - (563,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (563,27) - (563,40)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (563,59) - (563,69)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (574,19) - (574,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (574,37) - (574,44)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (575,31) - (575,37)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (577,26) - (577,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (577,26) - (577,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (577,26) - (577,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (578,21) - (578,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (578,49) - (578,55)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (581,9) - (581,15)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (581,20) - (581,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (582,23) - (582,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (584,20) - (584,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (588,9) - (588,15)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (588,20) - (588,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (589,23) - (589,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (593,23) - (593,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (594,7) - (594,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (594,43) - (594,53)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (606,9) - (606,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (606,9) - (606,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (606,9) - (606,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (607,9) - (607,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (607,9) - (607,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (607,9) - (607,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (610,9) - (610,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (610,9) - (610,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (610,9) - (610,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (611,9) - (611,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (611,9) - (611,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (611,9) - (611,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (612,9) - (612,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (612,9) - (612,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (612,9) - (612,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (614,12) - (614,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (616,13) - (616,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (616,13) - (616,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (616,13) - (616,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (616,24) - (616,30)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,26) - (620,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,37) - (620,43)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,67) - (620,80)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (624,30) - (624,37)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (624,41) - (624,47)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (624,71) - (624,84)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (14,7) - (14,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (18,7) - (18,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (38,7) - (38,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (48,20) - (48,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (55,9) - (55,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (64,20) - (64,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (69,9) - (69,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (93,7) - (93,11)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (94,9) - (94,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (97,39) - (97,47)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (100,9) - (100,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (103,32) - (103,40)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (114,50) - (114,60)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (120,50) - (120,52)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (120,50) - (120,52)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,9) - (142,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,50) - (142,58)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,93) - (142,104)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,139) - (142,148)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (142,183) - (142,199)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (146,10) - (146,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (146,12) - (146,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (146,12) - (146,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (146,12) - (146,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (148,16) - (148,18)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (148,18) - (148,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (148,18) - (148,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (148,18) - (148,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (155,11) - (155,13)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (155,13) - (155,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (155,13) - (155,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (155,13) - (155,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (155,32) - (155,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (155,34) - (155,40)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (155,34) - (155,40)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (155,34) - (155,40)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (254,7) - (254,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (254,7) - (254,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (254,7) - (254,31)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (255,7) - (255,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (255,7) - (255,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (255,7) - (255,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (256,7) - (256,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (256,7) - (256,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (256,7) - (256,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (265,24) - (265,32)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (272,9) - (272,13)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (273,12) - (273,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (276,26) - (276,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (279,12) - (279,20)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (282,26) - (282,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (324,28) - (324,36)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (328,17) - (328,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (328,17) - (328,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (330,31) - (330,37)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (333,17) - (333,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (342,19) - (342,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (344,11) - (344,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (357,18) - (357,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (358,6) - (358,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (389,17) - (389,34)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (390,33) - (390,38)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (392,22) - (392,27)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (401,17) - (401,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "in" (401,17) - (401,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (403,33) - (403,39)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (406,36) - (406,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (415,40) - (415,48)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (416,11) - (416,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (429,18) - (429,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (430,6) - (430,12)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (435,6) - (435,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (435,6) - (435,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (435,6) - (435,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (435,14) - (435,19)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (446,22) - (446,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (448,8) - (448,15)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (449,35) - (449,46)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (453,18) - (453,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (455,30) - (455,36)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (456,19) - (456,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (458,43) - (458,49)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (458,55) - (458,58)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (458,58) - (458,62)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (458,58) - (458,62)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (458,58) - (458,62)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (516,7) - (516,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (516,7) - (516,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (516,7) - (516,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (521,38) - (521,41)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (521,45) - (521,50)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (532,20) - (532,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (534,17) - (534,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (534,35) - (534,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (536,29) - (536,35)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (536,47) - (536,56)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (538,24) - (538,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (538,24) - (538,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (538,24) - (538,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (539,22) - (539,32)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (539,50) - (539,59)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (540,22) - (540,32)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (540,50) - (540,56)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (543,39) - (543,45)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (544,17) - (544,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (545,18) - (545,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (548,39) - (548,48)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (549,17) - (549,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (550,18) - (550,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (554,17) - (554,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (557,24) - (557,35)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (558,21) - (558,32)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (559,5) - (559,15)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (559,25) - (559,38)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (559,57) - (559,67)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (570,17) - (570,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (570,35) - (570,42)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (571,29) - (571,35)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (573,24) - (573,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (573,24) - (573,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (573,24) - (573,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (574,19) - (574,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (574,47) - (574,53)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (577,7) - (577,13)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (577,18) - (577,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (578,19) - (578,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (580,18) - (580,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (584,7) - (584,13)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (584,18) - (584,25)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (585,19) - (585,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (589,21) - (589,28)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (590,5) - (590,14)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (590,41) - (590,51)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (602,7) - (602,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (602,7) - (602,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (602,7) - (602,17)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (603,7) - (603,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (603,7) - (603,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (603,7) - (603,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (606,7) - (606,10)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (606,7) - (606,10)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (606,7) - (606,10)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (607,7) - (607,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (607,7) - (607,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (607,7) - (607,24)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (608,7) - (608,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (608,7) - (608,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (608,7) - (608,21)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (610,10) - (610,23)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (612,9) - (612,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "cell_path" (612,9) - (612,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "path" (612,9) - (612,16)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (612,20) - (612,26)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (616,22) - (616,29)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (616,33) - (616,39)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (616,63) - (616,76)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,26) - (620,33)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,37) - (620,43)}
[2024-12-20T15:29:45Z WARN  topiary_core::atom_collection] Skipping because the match occurred below a leaf node: {Node "identifier" (620,67) - (620,80)}
# this module regroups a bunch of development tools to make the development
# process easier for anyone.
#
# the main purpose of `toolkit` is to offer an easy to use interface for the
# developer during a PR cycle, namely to (**1**) format the source base,
# (**2**) catch classical flaws in the new changes with *clippy* and (**3**)
# make sure all the tests pass.

# check standard code formatting and apply the changes
export def fmt [
  --check # do not apply the format changes, only check the syntax
  --verbose # print extra information about the command's progress
] {
  if $verbose {
    print $"running ('toolkit fmt' | pretty-format-command)"
  }

  if $check {
    try {
      ^cargo fmt --all -- --check
    } catch {
      error make --unspanned {
        msg: $"\nplease run ('toolkit fmt' | pretty-format-command) to fix formatting!"
      }
    }
  } else {
    ^cargo fmt --all
  }
}

# check that you're using the standard code style
#
# > it is important to make `clippy` happy :relieved:
export def clippy [
  --verbose # print extra information about the command's progress
  --features: list<string> # the list of features to run *Clippy* on
] {
  if $verbose {
    print $"running ('toolkit clippy' | pretty-format-command)"
  }

  # If changing these settings also change CI settings in .github/workflows/ci.yml
  try {
    (
      ^cargo clippy
      --workspace
      --exclude nu_plugin_*
      --features ($features | str join ",")
      --
      -D warnings
      -D clippy::unwrap_used
      -D clippy::unchecked_duration_subtraction
    )

    if $verbose {
      print $"running ('toolkit clippy' | pretty-format-command) on tests"
    }
    # In tests we don't have to deny unwrap
    (
      ^cargo clippy
      --tests
      --workspace
      --exclude nu_plugin_*
      --features ($features | str join ",")
      --
      -D warnings
    )

    if $verbose {
      print $"running ('toolkit clippy' | pretty-format-command) on plugins"
    }
    (
      ^cargo clippy
      --package nu_plugin_*
      --
      -D warnings
      -D clippy::unwrap_used
      -D clippy::unchecked_duration_subtraction
    )
  } catch {
    error make --unspanned {
      msg: $"\nplease fix the above ('clippy' | pretty-format-command) errors before continuing!"
    }
  }
}

# check that all the tests pass
export def test [
  --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
  --features: list<string> # the list of features to run the tests on
  --workspace # run the *Clippy* command on the whole workspace (overrides `--features`)
] {
  if $fast {
    if $workspace {
      ^cargo nextest run --all
    } else {
      ^cargo nextest run --features ($features | str join ",")
    }
  } else {
    if $workspace {
      ^cargo test --workspace
    } else {
      ^cargo test --features ($features | str join ",")
    }
  }
}

# run the tests for the standard library
export def "test stdlib" [
  --extra-args: string= ''
] {
  ^cargo run -- --no-config-file -c $"
        use crates/nu-std/testing.nu
        testing run-tests --path crates/nu-std ($extra_args)
    "
}

# formats the pipe input inside backticks, dimmed and italic, as a pretty command
def pretty-format-command [] {
  $"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`"
}

# return a report about the check stage
#
# - fmt comes first
# - then clippy
# - and finally the tests
#
# without any option, `report` will return an empty report.
# otherwise, the truth values will be incremental, following
# the order above.
def report [
  --fail-fmt
  --fail-clippy
  --fail-test
  --fail-test-stdlib
  --no-fail
] {
  [fmt clippy test "test stdlib"]
  | wrap stage
  | merge (
    if $no_fail {[true true true true]} else if $fail_fmt {[false null null null]} else if $fail_clippy {[true false null null]} else if $fail_test {[true true false null]} else if $fail_test_stdlib {[true true true false]} else {[null null null null]}
    | wrap success
  )
  | upsert emoji {|it|
    if ($it.success == null) {
      ":black_circle:"
    } else if $it.success {
      ":green_circle:"
    } else {
      ":red_circle:"
    }
  }
  | each {|it|
    $"- ($it.emoji) `toolkit ($it.stage)`"
  }
  | to text
}

# run all the necessary checks and tests to submit a perfect PR
#
# # Example
# let us say we apply a change that
# - breaks the formatting, e.g. with extra newlines everywhere
# - makes clippy sad, e.g. by adding unnecessary string conversions with `.to_string()`
# - breaks the tests by output bad string data from a data structure conversion
#
# > the following diff breaks all of the three checks!
# > ```diff
# > diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs
# > index abe34c054..927d6a3de 100644
# > --- a/crates/nu-command/src/formats/to/nuon.rs
# > +++ b/crates/nu-command/src/formats/to/nuon.rs
# > @@ -131,7 +131,8 @@ pub fn value_to_string(v: &Value, span: Span) -> Result<String, ShellError> {
# >                          }
# >                      })
# >                      .collect();
# > -                let headers_output = headers.join(", ");
# > +                let headers_output = headers.join(&format!("x {}", "")
# > +                    .to_string());
# >
# >                  let mut table_output = vec![];
# >                  for val in vals {
# > ```
#
# > **Note**
# > at every stage, the `toolkit check pr` will return a report of the few stages being run.
#
# - we run the toolkit once and it fails...
# ```nushell
# >_ toolkit check pr
# running `toolkit fmt`
# Diff in /home/amtoine/.local/share/git/store/github.com/amtoine/nushell/crates/nu-command/src/formats/to/nuon.rs at line 131:
#                          }
#                      })
#                      .collect();
# -                let headers_output = headers.join(&format!("x {}", "")
# -                    .to_string());
# +                let headers_output = headers.join(&format!("x {}", "").to_string());
#
#                  let mut table_output = vec![];
#                  for val in vals {
#
# please run toolkit fmt to fix the formatting
# ```
# - we run `toolkit fmt` as proposed and rerun the toolkit... to see clippy is sad...
# ```nushell
# running `toolkit fmt`
# running `toolkit clippy`
# ...
# error: redundant clone
#    --> crates/nu-command/src/formats/to/nuon.rs:134:71
#     |
# 134 |                 let headers_output = headers.join(&format!("x {}", "").to_string());
#     |                                                                       ^^^^^^^^^^^^ help: remove this
#     |
# note: this value is dropped without further use
#    --> crates/nu-command/src/formats/to/nuon.rs:134:52
#     |
# 134 |                 let headers_output = headers.join(&format!("x {}", "").to_string());
#     |                                                    ^^^^^^^^^^^^^^^^^^^
#     = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
#     = note: `-D clippy::redundant-clone` implied by `-D warnings`
#
# error: could not compile `nu-command` due to previous error
# ```
# - we remove the useless `.to_string()`, and in that cases, the whole format is useless, only `"x "` is useful!
# but now the tests do not pass :sob:
# ```nushell
# running `toolkit fmt`
# running `toolkit clippy`
# ...
# running `toolkit test`
# ...
# failures:
#     commands::insert::insert_uses_enumerate_index
#     commands::merge::multi_row_table_overwrite
#     commands::merge::single_row_table_no_overwrite
#     commands::merge::single_row_table_overwrite
#     commands::update::update_uses_enumerate_index
#     commands::upsert::upsert_uses_enumerate_index_inserting
#     commands::upsert::upsert_uses_enumerate_index_updating
#     commands::where_::where_uses_enumerate_index
#     format_conversions::nuon::does_not_quote_strings_unnecessarily
#     format_conversions::nuon::to_nuon_table
# ```
# - finally let's fix the tests by removing the `x`, essentially removing the whole diff we applied at the top!
#
# now the whole `toolkit check pr` passes! :tada:
export def "check pr" [
  --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
  --features: list<string> # the list of features to check the current PR on
] {
  $env.NU_TEST_LOCALE_OVERRIDE = 'en_US.utf8'
  $env.LANG = 'en_US.UTF-8'
  $env.LANGUAGE = 'en'

  try {
    fmt --check --verbose
  } catch {
    return (report --fail-fmt)
  }

  try {
    clippy --features $features --verbose
  } catch {
    return (report --fail-clippy)
  }

  print $"running ('toolkit test' | pretty-format-command)"
  try {
    if $fast {
      if ($features | is-empty) {
        test --workspace --fast
      } else {
        test --features $features --fast
      }
    } else {
      if ($features | is-empty) {
        test --workspace
      } else {
        test --features $features
      }
    }
  } catch {
    return (report --fail-test)
  }

  print $"running ('toolkit test stdlib' | pretty-format-command)"
  try {
    test stdlib
  } catch {
    return (report --fail-test-stdlib)
  }

  report --no-fail
}

# run Nushell from source with a right indicator
export def run [] {
  ^cargo run -- ...[
    -e
    "$env.PROMPT_COMMAND_RIGHT = $'(ansi magenta_reverse)trying Nushell inside Cargo(ansi reset)'"
  ]
}

# set up git hooks to run:
# - `toolkit fmt --check --verbose` on `git commit`
# - `toolkit fmt --check --verbose` and `toolkit clippy --verbose` on `git push`
export def setup-git-hooks [] {
  print "This command will change your local git configuration and hence modify your development workflow. Are you sure you want to continue? [y]"
  if (input) == "y" {
    print $"running ('toolkit setup-git-hooks' | pretty-format-command)"
    git config --local core.hooksPath .githooks
  } else {
    print $"aborting ('toolkit setup-git-hooks' | pretty-format-command)"
  }
}

def build-nushell [features: string] {
  print $'(char nl)Building nushell'
  print '----------------------------'

  ^cargo build --features $features --locked
}

def build-plugin [] {
  let plugin = $in

  print $'(char nl)Building ($plugin)'
  print '----------------------------'

  cd $"crates/($plugin)"
  ^cargo build
}

# build Nushell and plugins with some features
export def build [
  ...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
  --all # build all plugins with Nushell
] {
  build-nushell ($features | str join ",")

  if not $all {
    return
  }

  let plugins = [
    nu_plugin_inc
    nu_plugin_gstat
    nu_plugin_query
    nu_plugin_example
    nu_plugin_custom_values
    nu_plugin_formats
  ]

  for plugin in $plugins {
    $plugin | build-plugin
  }
}

# build crates for wasm
export def "build wasm" [] {
  ^rustup target add wasm32-unknown-unknown

  # these crates should compile for wasm
  let compatible_crates = [
    "nu-cmd-base"
    "nu-cmd-extra"
    "nu-cmd-lang"
    "nu-color-config"
    "nu-command"
    "nu-derive-value"
    "nu-engine"
    "nu-glob"
    "nu-json"
    "nu-parser"
    "nu-path"
    "nu-pretty-hex"
    "nu-protocol"
    "nu-std"
    "nu-system"
    "nu-table"
    "nu-term-grid"
    "nu-utils"
    "nuon"
  ]

  for crate in $compatible_crates {
    print $'(char nl)Building ($crate) for wasm'
    print '----------------------------'
    ^cargo build -p $crate --target wasm32-unknown-unknown --no-default-features
  }
}

def "nu-complete list features" [] {
  open Cargo.toml | get features | transpose feature dependencies | get feature
}

def install-plugin [] {
  let plugin = $in

  print $'(char nl)Installing ($plugin)'
  print '----------------------------'

  ^cargo install --path $"crates/($plugin)"
}

# install Nushell and features you want
export def install [
  ...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
  --all # install all plugins with Nushell
] {
  touch crates/nu-cmd-lang/build.rs # needed to make sure `version` has the correct `commit_hash`
  ^cargo install --path . --features ($features | str join ",") --locked --force
  if not $all {
    return
  }

  let plugins = [
    nu_plugin_inc
    nu_plugin_gstat
    nu_plugin_query
    nu_plugin_example
    nu_plugin_custom_values
    nu_plugin_formats
  ]

  for plugin in $plugins {
    $plugin | install-plugin
  }
}

def windows? [] {
  $nu.os-info.name == windows
}

# filter out files that end in .d
def keep-plugin-executables [] {
  if (windows?) { where name ends-with '.exe'} else { where name !~ '\.d'}
}

# add all installed plugins
export def "add plugins" [] {
  let plugin_path = (which nu | get path.0 | path dirname)
  let plugins = (ls $plugin_path | where name =~ nu_plugin | keep-plugin-executables | get name)

  if ($plugins | is-empty) {
    print $"no plugins found in ($plugin_path)..."
    return
  }

  for plugin in $plugins {
    try {
      print $"> plugin add ($plugin)"
      plugin add $plugin
    } catch {|err|
      print -e $"(ansi rb)Failed to add ($plugin):\n($err.msg)(ansi reset)"
    }
  }

  print $"\n(ansi gb)plugins registered, please restart nushell(ansi reset)"
}

def compute-coverage [] {
  print "Setting up environment variables for coverage"
  # Enable LLVM coverage tracking through environment variables
  # show env outputs .ini/.toml style description of the variables
  # In order to use from toml, we need to make sure our string literals are single quoted
  # This is especially important when running on Windows since "C:\blah" is treated as an escape
  ^cargo llvm-cov show-env | str replace (char dq) (char sq) -a | from toml | load-env

  print "Cleaning up coverage data"
  ^cargo llvm-cov clean --workspace

  print "Building with workspace and profile=ci"
  # Apparently we need to explicitly build the necessary parts
  # using the `--profile=ci` is basically `debug` build with unnecessary symbols stripped
  # leads to smaller binaries and potential savings when compiling and running
  ^cargo build --workspace --profile=ci

  print "Running tests with --workspace and profile=ci"
  ^cargo test --workspace --profile=ci

  # You need to provide the used profile to find the raw data
  print "Generating coverage report as lcov.info"
  ^cargo llvm-cov report --lcov --output-path lcov.info --profile=ci
}

# Script to generate coverage locally
#
# Output: `lcov.info` file
#
# Relies on `cargo-llvm-cov`. Install via `cargo install cargo-llvm-cov`
# https://github.com/taiki-e/cargo-llvm-cov
#
# You probably have to run `cargo llvm-cov clean` once manually,
# as you have to confirm to install additional tooling for your rustup toolchain.
# Else the script might stall waiting for your `y<ENTER>`
#
# Some of the internal tests rely on the exact cargo profile
# (This is somewhat criminal itself)
# but we have to signal to the tests that we use the `ci` `--profile`
#
# Manual gathering of coverage to catch invocation of the `nu` binary.
# This is relevant for tests using the `nu!` macro from `nu-test-support`
# see: https://github.com/taiki-e/cargo-llvm-cov#get-coverage-of-external-tests
#
# To display the coverage in your editor see:
#
# - https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters
# - https://github.com/umaumax/vim-lcov
# - https://github.com/andythigpen/nvim-coverage (probably needs some additional config)
export def cov [] {
  let start = (date now)
  $env.NUSHELL_CARGO_PROFILE = "ci"

  compute-coverage

  let end = (date now)
  print $"Coverage generation took ($end - $start)."
}

# Benchmark a target revision (default: current branch) against a reference revision (default: main branch)
#
# Results are saved in a `./tango` directory
# Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
export def benchmark-compare [
  target?: string # which branch to compare (default: current branch)
  reference?: string # the reference to compare against (default: main branch)
] {
  let reference = $reference | default "main"
  let current = git branch --show-current
  let target = $target | default $current

  print $'-- Benchmarking ($target) against ($reference)'

  let export_dir = $env.PWD | path join "tango"
  let ref_bin_dir = $export_dir | path join bin $reference
  let tgt_bin_dir = $export_dir | path join bin $target

  # benchmark the target revision
  print $'-- Running benchmarks for ($target)'
  git checkout $target
  ^cargo export $tgt_bin_dir -- bench

  # benchmark the comparison reference revision
  print $'-- Running benchmarks for ($reference)'
  git checkout $reference
  ^cargo export $ref_bin_dir -- bench

  # return back to the whatever revision before benchmarking
  print '-- Done'
  git checkout $current

  # report results
  let reference_bin = $ref_bin_dir | path join benchmarks
  let target_bin = $tgt_bin_dir | path join benchmarks
  ^$target_bin compare $reference_bin -o -s 50 --dump ($export_dir | path join samples)
}

# Benchmark the current branch and logs the result in `./tango/samples`
#
# Results are saved in a `./tango` directory
# Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
export def benchmark-log [
  target?: string # which branch to compare (default: current branch)
] {
  let current = git branch --show-current
  let target = $target | default $current
  print $'-- Benchmarking ($target)'

  let export_dir = $env.PWD | path join "tango"
  let bin_dir = ($export_dir | path join bin $target)

  # benchmark the target revision
  if $target != $current {
    git checkout $target
  }
  ^cargo export $bin_dir -- bench

  # return back to the whatever revision before benchmarking
  print '-- Done'
  if $target != $current {
    git checkout $current
  }

  # report results
  let bench_bin = ($bin_dir | path join benchmarks)
  ^$bench_bin compare -o -s 50 --dump ($export_dir | path join samples)
}

# Build all Windows archives and MSIs for release manually
#
# This builds std and full distributions for both aarch64 and x86_64.
#
# You need to have the cross-compilers for MSVC installed (see Visual Studio).
# If compiling on x86_64, you need ARM64 compilers and libs too, and vice versa.
export def 'release-pkg windows' [
  --artifacts-dir= "artifacts" # Where to copy the final msi and zip files to
] {
  $env.RUSTFLAGS = ""
  $env.CARGO_TARGET_DIR = ""
  hide-env RUSTFLAGS
  hide-env CARGO_TARGET_DIR
  $env.OS = "windows-latest"
  $env.GITHUB_WORKSPACE = ("." | path expand)
  $env.GITHUB_OUTPUT = ("./output/out.txt" | path expand)
  let version = (open Cargo.toml | get package.version)
  mkdir $artifacts_dir
  for target in ["aarch64" "x86_64"] {
    $env.TARGET = $target ++ "-pc-windows-msvc"

    rm -rf output
    _EXTRA_=bin nu .github/workflows/release-pkg.nu
    cp $"output/nu-($version)-($target)-pc-windows-msvc.zip" $artifacts_dir

    rm -rf output
    _EXTRA_=msi nu .github/workflows/release-pkg.nu
    cp $"target/wix/nu-($version)-($target)-pc-windows-msvc.msi" $artifacts_dir
  }
}

export def main [] {help toolkit}

@blindFS
Copy link
Owner

blindFS commented Dec 20, 2024

@fdncred I think it's working, except for the write access.
open toolkit.nu | topiary format --language nu | save toolkit_formatted.nu should generate the formatted doc.

I'll ask the owners of topiary to see what's going on with the write accessibility.

@fdncred
Copy link
Author

fdncred commented Dec 20, 2024

yup, you're right. yay! it's interesting to see what it changed. 99.9% is fine but the section with if $no_fail is kind of funny how it reformatted it. Either way, this is a great tool and I'm glad to see it's working on windows now. Thanks so much!

diff --git a/toolkit.nu b/toolkit.nu
index d848dce18..6096879a5 100644
--- a/toolkit.nu
+++ b/toolkit.nu
@@ -8,108 +8,108 @@
 
 # check standard code formatting and apply the changes
 export def fmt [
-    --check # do not apply the format changes, only check the syntax
-    --verbose  # print extra information about the command's progress
+  --check # do not apply the format changes, only check the syntax
+  --verbose # print extra information about the command's progress
 ] {
-    if $verbose {
-        print $"running ('toolkit fmt' | pretty-format-command)"
-    }
+  if $verbose {
+    print $"running ('toolkit fmt' | pretty-format-command)"
+  }
 
-    if $check {
-        try {
-            ^cargo fmt --all -- --check
-        } catch {
-            error make --unspanned {
-                msg: $"\nplease run ('toolkit fmt' | pretty-format-command) to fix formatting!"
-            }
-        }
-    } else {
-        ^cargo fmt --all
+  if $check {
+    try {
+      ^cargo fmt --all -- --check
+    } catch {
+      error make --unspanned {
+        msg: $"\nplease run ('toolkit fmt' | pretty-format-command) to fix formatting!"
+      }
     }
+  } else {
+    ^cargo fmt --all
+  }
 }
 
 # check that you're using the standard code style
 #
 # > it is important to make `clippy` happy :relieved:
 export def clippy [
-    --verbose # print extra information about the command's progress
-    --features: list<string> # the list of features to run *Clippy* on
+  --verbose # print extra information about the command's progress
+  --features: list<string> # the list of features to run *Clippy* on
 ] {
-    if $verbose {
-        print $"running ('toolkit clippy' | pretty-format-command)"
-    }
+  if $verbose {
+    print $"running ('toolkit clippy' | pretty-format-command)"
+  }
 
-    # If changing these settings also change CI settings in .github/workflows/ci.yml
-    try {(
-        ^cargo clippy
-            --workspace
-            --exclude nu_plugin_*
-            --features ($features | str join ",")
-            --
-            -D warnings
-            -D clippy::unwrap_used
-            -D clippy::unchecked_duration_subtraction
+  # If changing these settings also change CI settings in .github/workflows/ci.yml
+  try {
+    (
+      ^cargo clippy
+      --workspace
+      --exclude nu_plugin_*
+      --features ($features | str join ",")
+      --
+      -D warnings
+      -D clippy::unwrap_used
+      -D clippy::unchecked_duration_subtraction
     )
 
     if $verbose {
-        print $"running ('toolkit clippy' | pretty-format-command) on tests"
+      print $"running ('toolkit clippy' | pretty-format-command) on tests"
     }
     # In tests we don't have to deny unwrap
     (
-        ^cargo clippy
-            --tests
-            --workspace
-            --exclude nu_plugin_*
-            --features ($features | str join ",")
-            --
-            -D warnings
+      ^cargo clippy
+      --tests
+      --workspace
+      --exclude nu_plugin_*
+      --features ($features | str join ",")
+      --
+      -D warnings
     )
 
     if $verbose {
-        print $"running ('toolkit clippy' | pretty-format-command) on plugins"
+      print $"running ('toolkit clippy' | pretty-format-command) on plugins"
     }
     (
-        ^cargo clippy
-            --package nu_plugin_*
-            --
-            -D warnings
-            -D clippy::unwrap_used
-            -D clippy::unchecked_duration_subtraction
+      ^cargo clippy
+      --package nu_plugin_*
+      --
+      -D warnings
+      -D clippy::unwrap_used
+      -D clippy::unchecked_duration_subtraction
     )
-
-    } catch {
-        error make --unspanned {
-            msg: $"\nplease fix the above ('clippy' | pretty-format-command) errors before continuing!"
-        }
+  } catch {
+    error make --unspanned {
+      msg: $"\nplease fix the above ('clippy' | pretty-format-command) errors before continuing!"
     }
+  }
 }
 
 # check that all the tests pass
 export def test [
-    --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
-    --features: list<string> # the list of features to run the tests on
-    --workspace # run the *Clippy* command on the whole workspace (overrides `--features`)
+  --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
+  --features: list<string> # the list of features to run the tests on
+  --workspace # run the *Clippy* command on the whole workspace (overrides `--features`)
 ] {
-    if $fast {
-        if $workspace {
-            ^cargo nextest run --all
-        } else {
-            ^cargo nextest run --features ($features | str join ",")
-        }
+  if $fast {
+    if $workspace {
+      ^cargo nextest run --all
+    } else {
+      ^cargo nextest run --features ($features | str join ",")
+    }
+  } else {
+    if $workspace {
+      ^cargo test --workspace
     } else {
-        if $workspace {
-            ^cargo test --workspace
-        } else {
-            ^cargo test --features ($features | str join ",")
-        }
+      ^cargo test --features ($features | str join ",")
     }
+  }
 }
 
 # run the tests for the standard library
 export def "test stdlib" [
-    --extra-args: string = ''
+  --extra-args: string= ''
 ] {
-    ^cargo run -- --no-config-file -c $"
+  ^cargo run -- --no-config-file -c $"
         use crates/nu-std/testing.nu
         testing run-tests --path crates/nu-std ($extra_args)
     "
@@ -117,7 +117,7 @@ export def "test stdlib" [
 
 # formats the pipe input inside backticks, dimmed and italic, as a pretty command
 def pretty-format-command [] {
-    $"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`"
+  $"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`"
 }
 
 # return a report about the check stage
@@ -130,36 +130,31 @@ def pretty-format-command [] {
 # otherwise, the truth values will be incremental, following
 # the order above.
 def report [
-    --fail-fmt
-    --fail-clippy
-    --fail-test
-    --fail-test-stdlib
-    --no-fail
+  --fail-fmt
+  --fail-clippy
+  --fail-test
+  --fail-test-stdlib
+  --no-fail
 ] {
-    [fmt clippy test "test stdlib"]
-    | wrap stage
-    | merge (
-        if $no_fail               { [true     true     true     true] }
-        else if $fail_fmt         { [false    null null null] }
-        else if $fail_clippy      { [true     false    null null] }
-        else if $fail_test        { [true     true     false    null] }
-        else if $fail_test_stdlib { [true     true     true     false] }
-        else                      { [null null null null] }
-        | wrap success
-    )
-    | upsert emoji {|it|
-        if ($it.success == null) {
-            ":black_circle:"
-        } else if $it.success {
-            ":green_circle:"
-        } else {
-            ":red_circle:"
-        }
-    }
-    | each {|it|
-        $"- ($it.emoji) `toolkit ($it.stage)`"
+  [fmt clippy test "test stdlib"]
+  | wrap stage
+  | merge (
+    if $no_fail {[true true true true]} else if $fail_fmt {[false null null null]} else if $fail_clippy {[true false null null]} else if $fail_test {[true true false null]} else if $fail_test_stdlib {[true true true false]} else {[null null null null]}
+    | wrap success
+  )
+  | upsert emoji {|it|
+    if ($it.success == null) {
+      ":black_circle:"
+    } else if $it.success {
+      ":green_circle:"
+    } else {
+      ":red_circle:"
     }
-    | to text
+  }
+  | each {|it|
+    $"- ($it.emoji) `toolkit ($it.stage)`"
+  }
+  | to text
 }
 
 # run all the necessary checks and tests to submit a perfect PR
@@ -253,242 +248,243 @@ def report [
 #
 # now the whole `toolkit check pr` passes! :tada:
 export def "check pr" [
-    --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
-    --features: list<string> # the list of features to check the current PR on
+  --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
+  --features: list<string> # the list of features to check the current PR on
 ] {
-    $env.NU_TEST_LOCALE_OVERRIDE = 'en_US.utf8'
-    $env.LANG = 'en_US.UTF-8'
-    $env.LANGUAGE = 'en'
-
-    try {
-        fmt --check --verbose
-    } catch {
-        return (report --fail-fmt)
-    }
-
-    try {
-        clippy --features $features --verbose
-    } catch {
-        return (report --fail-clippy)
-    }
-
-    print $"running ('toolkit test' | pretty-format-command)"
-    try {
-        if $fast {
-            if ($features | is-empty) {
-                test --workspace --fast
-            } else {
-                test --features $features --fast
-            }
-        } else {
-            if ($features | is-empty) {
-                test --workspace
-            } else {
-                test --features $features
-            }
-        }
-    } catch {
-        return (report --fail-test)
-    }
-
-    print $"running ('toolkit test stdlib' | pretty-format-command)"
-    try {
-        test stdlib
-    } catch {
-        return (report --fail-test-stdlib)
+  $env.NU_TEST_LOCALE_OVERRIDE = 'en_US.utf8'
+  $env.LANG = 'en_US.UTF-8'
+  $env.LANGUAGE = 'en'
+
+  try {
+    fmt --check --verbose
+  } catch {
+    return (report --fail-fmt)
+  }
+
+  try {
+    clippy --features $features --verbose
+  } catch {
+    return (report --fail-clippy)
+  }
+
+  print $"running ('toolkit test' | pretty-format-command)"
+  try {
+    if $fast {
+      if ($features | is-empty) {
+        test --workspace --fast
+      } else {
+        test --features $features --fast
+      }
+    } else {
+      if ($features | is-empty) {
+        test --workspace
+      } else {
+        test --features $features
+      }
     }
-
-    report --no-fail
+  } catch {
+    return (report --fail-test)
+  }
+
+  print $"running ('toolkit test stdlib' | pretty-format-command)"
+  try {
+    test stdlib
+  } catch {
+    return (report --fail-test-stdlib)
+  }
+
+  report --no-fail
 }
 
 # run Nushell from source with a right indicator
 export def run [] {
-    ^cargo run -- ...[
-        -e "$env.PROMPT_COMMAND_RIGHT = $'(ansi magenta_reverse)trying Nushell inside Cargo(ansi reset)'"
-    ]
+  ^cargo run -- ...[
+    -e
+    "$env.PROMPT_COMMAND_RIGHT = $'(ansi magenta_reverse)trying Nushell inside Cargo(ansi reset)'"
+  ]
 }
 
 # set up git hooks to run:
 # - `toolkit fmt --check --verbose` on `git commit`
 # - `toolkit fmt --check --verbose` and `toolkit clippy --verbose` on `git push`
 export def setup-git-hooks [] {
-    print "This command will change your local git configuration and hence modify your development workflow. Are you sure you want to continue? [y]"
-    if (input) == "y" {
-        print $"running ('toolkit setup-git-hooks' | pretty-format-command)"
-        git config --local core.hooksPath .githooks
-    } else {
-        print $"aborting ('toolkit setup-git-hooks' | pretty-format-command)"
-    }
+  print "This command will change your local git configuration and hence modify your development workflow. Are you sure you want to continue? [y]"
+  if (input) == "y" {
+    print $"running ('toolkit setup-git-hooks' | pretty-format-command)"
+    git config --local core.hooksPath .githooks
+  } else {
+    print $"aborting ('toolkit setup-git-hooks' | pretty-format-command)"
+  }
 }
 
 def build-nushell [features: string] {
-    print $'(char nl)Building nushell'
-    print '----------------------------'
+  print $'(char nl)Building nushell'
+  print '----------------------------'
 
-    ^cargo build --features $features --locked
+  ^cargo build --features $features --locked
 }
 
 def build-plugin [] {
-    let plugin = $in
+  let plugin = $in
 
-    print $'(char nl)Building ($plugin)'
-    print '----------------------------'
+  print $'(char nl)Building ($plugin)'
+  print '----------------------------'
 
-    cd $"crates/($plugin)"
-    ^cargo build
+  cd $"crates/($plugin)"
+  ^cargo build
 }
 
 # build Nushell and plugins with some features
 export def build [
-    ...features: string@"nu-complete list features"  # a space-separated list of feature to install with Nushell
-    --all # build all plugins with Nushell
+  ...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
+  --all # build all plugins with Nushell
 ] {
-    build-nushell ($features | str join ",")
-
-    if not $all {
-        return
-    }
-
-    let plugins = [
-        nu_plugin_inc,
-        nu_plugin_gstat,
-        nu_plugin_query,
-        nu_plugin_example,
-        nu_plugin_custom_values,
-        nu_plugin_formats,
-    ]
-
-    for plugin in $plugins {
-        $plugin | build-plugin
-    }
+  build-nushell ($features | str join ",")
+
+  if not $all {
+    return
+  }
+
+  let plugins = [
+    nu_plugin_inc
+    nu_plugin_gstat
+    nu_plugin_query
+    nu_plugin_example
+    nu_plugin_custom_values
+    nu_plugin_formats
+  ]
+
+  for plugin in $plugins {
+    $plugin | build-plugin
+  }
 }
 
 # build crates for wasm
 export def "build wasm" [] {
-    ^rustup target add wasm32-unknown-unknown
-
-    # these crates should compile for wasm
-    let compatible_crates = [
-        "nu-cmd-base",
-        "nu-cmd-extra",
-        "nu-cmd-lang",
-        "nu-color-config",
-        "nu-command",
-        "nu-derive-value",
-        "nu-engine",
-        "nu-glob",
-        "nu-json",
-        "nu-parser",
-        "nu-path",
-        "nu-pretty-hex",
-        "nu-protocol",
-        "nu-std",
-        "nu-system",
-        "nu-table",
-        "nu-term-grid",
-        "nu-utils",
-        "nuon"
-    ]
-
-    for crate in $compatible_crates {
-            print $'(char nl)Building ($crate) for wasm'
-            print '----------------------------'
-        ^cargo build -p $crate --target wasm32-unknown-unknown --no-default-features
-    }
+  ^rustup target add wasm32-unknown-unknown
+
+  # these crates should compile for wasm
+  let compatible_crates = [
+    "nu-cmd-base"
+    "nu-cmd-extra"
+    "nu-cmd-lang"
+    "nu-color-config"
+    "nu-command"
+    "nu-derive-value"
+    "nu-engine"
+    "nu-glob"
+    "nu-json"
+    "nu-parser"
+    "nu-path"
+    "nu-pretty-hex"
+    "nu-protocol"
+    "nu-std"
+    "nu-system"
+    "nu-table"
+    "nu-term-grid"
+    "nu-utils"
+    "nuon"
+  ]
+
+  for crate in $compatible_crates {
+    print $'(char nl)Building ($crate) for wasm'
+    print '----------------------------'
+    ^cargo build -p $crate --target wasm32-unknown-unknown --no-default-features
+  }
 }
 
 def "nu-complete list features" [] {
-    open Cargo.toml | get features | transpose feature dependencies | get feature
+  open Cargo.toml | get features | transpose feature dependencies | get feature
 }
 
 def install-plugin [] {
-    let plugin = $in
+  let plugin = $in
 
-    print $'(char nl)Installing ($plugin)'
-    print '----------------------------'
+  print $'(char nl)Installing ($plugin)'
+  print '----------------------------'
 
-    ^cargo install --path $"crates/($plugin)"
+  ^cargo install --path $"crates/($plugin)"
 }
 
 # install Nushell and features you want
 export def install [
-    ...features: string@"nu-complete list features"  # a space-separated list of feature to install with Nushell
-    --all # install all plugins with Nushell
+  ...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
+  --all # install all plugins with Nushell
 ] {
-    touch crates/nu-cmd-lang/build.rs # needed to make sure `version` has the correct `commit_hash`
-    ^cargo install --path . --features ($features | str join ",") --locked --force
-    if not $all {
-        return
-    }
-
-    let plugins = [
-        nu_plugin_inc,
-        nu_plugin_gstat,
-        nu_plugin_query,
-        nu_plugin_example,
-        nu_plugin_custom_values,
-        nu_plugin_formats,
-    ]
-
-    for plugin in $plugins {
-        $plugin | install-plugin
-    }
+  touch crates/nu-cmd-lang/build.rs # needed to make sure `version` has the correct `commit_hash`
+  ^cargo install --path . --features ($features | str join ",") --locked --force
+  if not $all {
+    return
+  }
+
+  let plugins = [
+    nu_plugin_inc
+    nu_plugin_gstat
+    nu_plugin_query
+    nu_plugin_example
+    nu_plugin_custom_values
+    nu_plugin_formats
+  ]
+
+  for plugin in $plugins {
+    $plugin | install-plugin
+  }
 }
 
 def windows? [] {
-    $nu.os-info.name == windows
+  $nu.os-info.name == windows
 }
 
 # filter out files that end in .d
 def keep-plugin-executables [] {
-    if (windows?) { where name ends-with '.exe' } else { where name !~ '\.d' }
+  if (windows?) { where name ends-with '.exe'} else { where name !~ '\.d'}
 }
 
 # add all installed plugins
 export def "add plugins" [] {
-    let plugin_path = (which nu | get path.0 | path dirname)
-    let plugins = (ls $plugin_path | where name =~ nu_plugin | keep-plugin-executables | get name)
+  let plugin_path = (which nu | get path.0 | path dirname)
+  let plugins = (ls $plugin_path | where name =~ nu_plugin | keep-plugin-executables | get name)
 
-    if ($plugins | is-empty) {
-        print $"no plugins found in ($plugin_path)..."
-        return
-    }
+  if ($plugins | is-empty) {
+    print $"no plugins found in ($plugin_path)..."
+    return
+  }
 
-    for plugin in $plugins {
-        try {
-            print $"> plugin add ($plugin)"
-            plugin add $plugin
-        } catch { |err|
-            print -e $"(ansi rb)Failed to add ($plugin):\n($err.msg)(ansi reset)"
-        }
+  for plugin in $plugins {
+    try {
+      print $"> plugin add ($plugin)"
+      plugin add $plugin
+    } catch {|err|
+      print -e $"(ansi rb)Failed to add ($plugin):\n($err.msg)(ansi reset)"
     }
+  }
 
-    print $"\n(ansi gb)plugins registered, please restart nushell(ansi reset)"
+  print $"\n(ansi gb)plugins registered, please restart nushell(ansi reset)"
 }
 
 def compute-coverage [] {
-    print "Setting up environment variables for coverage"
-    # Enable LLVM coverage tracking through environment variables
-    # show env outputs .ini/.toml style description of the variables
-    # In order to use from toml, we need to make sure our string literals are single quoted
-    # This is especially important when running on Windows since "C:\blah" is treated as an escape
-    ^cargo llvm-cov show-env | str replace (char dq) (char sq) -a | from toml | load-env
-
-    print "Cleaning up coverage data"
-    ^cargo llvm-cov clean --workspace
-
-    print "Building with workspace and profile=ci"
-    # Apparently we need to explicitly build the necessary parts
-    # using the `--profile=ci` is basically `debug` build with unnecessary symbols stripped
-    # leads to smaller binaries and potential savings when compiling and running
-    ^cargo build --workspace --profile=ci
-
-    print "Running tests with --workspace and profile=ci"
-    ^cargo test --workspace --profile=ci
-
-    # You need to provide the used profile to find the raw data
-    print "Generating coverage report as lcov.info"
-    ^cargo llvm-cov report --lcov --output-path lcov.info --profile=ci
+  print "Setting up environment variables for coverage"
+  # Enable LLVM coverage tracking through environment variables
+  # show env outputs .ini/.toml style description of the variables
+  # In order to use from toml, we need to make sure our string literals are single quoted
+  # This is especially important when running on Windows since "C:\blah" is treated as an escape
+  ^cargo llvm-cov show-env | str replace (char dq) (char sq) -a | from toml | load-env
+
+  print "Cleaning up coverage data"
+  ^cargo llvm-cov clean --workspace
+
+  print "Building with workspace and profile=ci"
+  # Apparently we need to explicitly build the necessary parts
+  # using the `--profile=ci` is basically `debug` build with unnecessary symbols stripped
+  # leads to smaller binaries and potential savings when compiling and running
+  ^cargo build --workspace --profile=ci
+
+  print "Running tests with --workspace and profile=ci"
+  ^cargo test --workspace --profile=ci
+
+  # You need to provide the used profile to find the raw data
+  print "Generating coverage report as lcov.info"
+  ^cargo llvm-cov report --lcov --output-path lcov.info --profile=ci
 }
 
 # Script to generate coverage locally
@@ -516,13 +512,13 @@ def compute-coverage [] {
 # - https://github.com/umaumax/vim-lcov
 # - https://github.com/andythigpen/nvim-coverage (probably needs some additional config)
 export def cov [] {
-    let start = (date now)
-    $env.NUSHELL_CARGO_PROFILE = "ci"
+  let start = (date now)
+  $env.NUSHELL_CARGO_PROFILE = "ci"
 
-    compute-coverage
+  compute-coverage
 
-    let end = (date now)
-    print $"Coverage generation took ($end - $start)."
+  let end = (date now)
+  print $"Coverage generation took ($end - $start)."
 }
 
 # Benchmark a target revision (default: current branch) against a reference revision (default: main branch)
@@ -530,37 +526,37 @@ export def cov [] {
 # Results are saved in a `./tango` directory
 # Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
 export def benchmark-compare [
-    target?: string     # which branch to compare (default: current branch)
-    reference?: string  # the reference to compare against (default: main branch)
+  target?: string # which branch to compare (default: current branch)
+  reference?: string # the reference to compare against (default: main branch)
 ] {
-    let reference = $reference | default "main"
-    let current = git branch --show-current
-    let target = $target | default $current
-
-    print $'-- Benchmarking ($target) against ($reference)'
-
-    let export_dir = $env.PWD | path join "tango"
-    let ref_bin_dir = $export_dir | path join bin $reference
-    let tgt_bin_dir = $export_dir | path join bin $target
-
-    # benchmark the target revision
-    print $'-- Running benchmarks for ($target)'
-    git checkout $target
-    ^cargo export $tgt_bin_dir -- bench
-
-    # benchmark the comparison reference revision
-    print $'-- Running benchmarks for ($reference)'
-    git checkout $reference
-    ^cargo export $ref_bin_dir -- bench
-
-    # return back to the whatever revision before benchmarking
-    print '-- Done'
-    git checkout $current
-
-    # report results
-    let reference_bin = $ref_bin_dir | path join benchmarks
-    let target_bin = $tgt_bin_dir | path join benchmarks
-    ^$target_bin compare $reference_bin -o -s 50 --dump ($export_dir | path join samples)
+  let reference = $reference | default "main"
+  let current = git branch --show-current
+  let target = $target | default $current
+
+  print $'-- Benchmarking ($target) against ($reference)'
+
+  let export_dir = $env.PWD | path join "tango"
+  let ref_bin_dir = $export_dir | path join bin $reference
+  let tgt_bin_dir = $export_dir | path join bin $target
+
+  # benchmark the target revision
+  print $'-- Running benchmarks for ($target)'
+  git checkout $target
+  ^cargo export $tgt_bin_dir -- bench
+
+  # benchmark the comparison reference revision
+  print $'-- Running benchmarks for ($reference)'
+  git checkout $reference
+  ^cargo export $ref_bin_dir -- bench
+
+  # return back to the whatever revision before benchmarking
+  print '-- Done'
+  git checkout $current
+
+  # report results
+  let reference_bin = $ref_bin_dir | path join benchmarks
+  let target_bin = $tgt_bin_dir | path join benchmarks
+  ^$target_bin compare $reference_bin -o -s 50 --dump ($export_dir | path join samples)
 }
 
 # Benchmark the current branch and logs the result in `./tango/samples`
@@ -568,30 +564,30 @@ export def benchmark-compare [
 # Results are saved in a `./tango` directory
 # Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
 export def benchmark-log [
-    target?: string     # which branch to compare (default: current branch)
+  target?: string # which branch to compare (default: current branch)
 ] {
-    let current = git branch --show-current
-    let target = $target | default $current
-    print $'-- Benchmarking ($target)'
+  let current = git branch --show-current
+  let target = $target | default $current
+  print $'-- Benchmarking ($target)'
 
-    let export_dir = $env.PWD | path join "tango"
-    let bin_dir = ($export_dir | path join bin $target)
+  let export_dir = $env.PWD | path join "tango"
+  let bin_dir = ($export_dir | path join bin $target)
 
-    # benchmark the target revision
-    if $target != $current {
-        git checkout $target
-    }
-    ^cargo export $bin_dir -- bench
+  # benchmark the target revision
+  if $target != $current {
+    git checkout $target
+  }
+  ^cargo export $bin_dir -- bench
 
-    # return back to the whatever revision before benchmarking
-    print '-- Done'
-    if $target != $current {
-        git checkout $current
-    }
+  # return back to the whatever revision before benchmarking
+  print '-- Done'
+  if $target != $current {
+    git checkout $current
+  }
 
-    # report results
-    let bench_bin = ($bin_dir | path join benchmarks)
-    ^$bench_bin compare -o -s 50 --dump ($export_dir | path join samples)
+  # report results
+  let bench_bin = ($bin_dir | path join benchmarks)
+  ^$bench_bin compare -o -s 50 --dump ($export_dir | path join samples)
 }
 
 # Build all Windows archives and MSIs for release manually
@@ -601,28 +597,28 @@ export def benchmark-log [
 # You need to have the cross-compilers for MSVC installed (see Visual Studio).
 # If compiling on x86_64, you need ARM64 compilers and libs too, and vice versa.
 export def 'release-pkg windows' [
-    --artifacts-dir="artifacts" # Where to copy the final msi and zip files to
+  --artifacts-dir= "artifacts" # Where to copy the final msi and zip files to
 ] {
-    $env.RUSTFLAGS = ""
-    $env.CARGO_TARGET_DIR = ""
-    hide-env RUSTFLAGS
-    hide-env CARGO_TARGET_DIR
-    $env.OS = "windows-latest"
-    $env.GITHUB_WORKSPACE = ("." | path expand)
-    $env.GITHUB_OUTPUT = ("./output/out.txt" | path expand)
-    let version = (open Cargo.toml | get package.version)
-    mkdir $artifacts_dir
-    for target in ["aarch64" "x86_64"] {
-        $env.TARGET = $target ++ "-pc-windows-msvc"
-
-        rm -rf output
-        _EXTRA_=bin nu .github/workflows/release-pkg.nu
-        cp $"output/nu-($version)-($target)-pc-windows-msvc.zip" $artifacts_dir
-
-        rm -rf output
-        _EXTRA_=msi nu .github/workflows/release-pkg.nu
-        cp $"target/wix/nu-($version)-($target)-pc-windows-msvc.msi" $artifacts_dir
-    }
+  $env.RUSTFLAGS = ""
+  $env.CARGO_TARGET_DIR = ""
+  hide-env RUSTFLAGS
+  hide-env CARGO_TARGET_DIR
+  $env.OS = "windows-latest"
+  $env.GITHUB_WORKSPACE = ("." | path expand)
+  $env.GITHUB_OUTPUT = ("./output/out.txt" | path expand)
+  let version = (open Cargo.toml | get package.version)
+  mkdir $artifacts_dir
+  for target in ["aarch64" "x86_64"] {
+    $env.TARGET = $target ++ "-pc-windows-msvc"
+
+    rm -rf output
+    _EXTRA_=bin nu .github/workflows/release-pkg.nu
+    cp $"output/nu-($version)-($target)-pc-windows-msvc.zip" $artifacts_dir
+
+    rm -rf output
+    _EXTRA_=msi nu .github/workflows/release-pkg.nu
+    cp $"target/wix/nu-($version)-($target)-pc-windows-msvc.msi" $artifacts_dir
+  }
 }
 
-export def main [] { help toolkit }
+export def main [] {help toolkit}

@fdncred
Copy link
Author

fdncred commented Dec 20, 2024

to be more clear, the funny part is that it formatted this

        if $no_fail               { [true     true     true     true] }
        else if $fail_fmt         { [false    null null null] }
        else if $fail_clippy      { [true     false    null null] }
        else if $fail_test        { [true     true     false    null] }
        else if $fail_test_stdlib { [true     true     true     false] }
        else                      { [null null null null] }

like this

    if $no_fail {[true true true true]} else if $fail_fmt {[false null null null]} else if $fail_clippy {[true false null null]} else if $fail_test {[true true false null]} else if $fail_test_stdlib {[true true true false]} else {[null null null null]}

i didn't expect it to align things, of course, but i also didn't expect it to put all that on one line. lol

@blindFS
Copy link
Owner

blindFS commented Dec 20, 2024

@fdncred, yes, it's definitely a style issue, I'm trying to fix it. Seems a lot rules about newlines in parentheses are still missing.

@blindFS
Copy link
Owner

blindFS commented Dec 28, 2024

@fdncred The style issue of else in parentheses has been fixed (and several other issues).
Since formatting through stdio works for you, maybe you can try it in neovim.
I've added an example setup with conform.nvim in README.

@fdncred
Copy link
Author

fdncred commented Dec 28, 2024

I guess I've done something else wrong.
image

This is on MacOS. I pulled the latest from topiary-nushell. I pulled the latest from tree-sitter-nu, did tree-sitter generate and tree-sitter build. Updated the languages.ncl file. Ran it from the command line and from nvim with the same result.
image

@blindFS
Copy link
Owner

blindFS commented Dec 28, 2024

@fdncred I think it's caused by my latest PR to tree-sitter-nu (the renaming). Since it is merged now, I'm going to update this repo.

@blindFS
Copy link
Owner

blindFS commented Dec 28, 2024

@fdncred Done.

@fdncred
Copy link
Author

fdncred commented Dec 28, 2024

Seems like it did something. Nice work! That's better than before.
image

@blindFS
Copy link
Owner

blindFS commented Dec 28, 2024

@fdncred I'm closing this issue for now, since it's getting a little bit too long to follow.
Feel free to report any other issue. PS. utils.nu can help to find some obvious ones in batch.

@blindFS blindFS closed this as completed Dec 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants