1
Fork 0
mirror of https://github.com/RGBCube/nu_scripts synced 2025-07-29 21:27:47 +00:00
nu_scripts/toolkit.nu
Douglas c17dcc3855
Fix failing lints on source files (#1049)
This PR updates the toolkit testing to:

* Determine whether to lint as a module or source file based on the
presence of any `export ` line in the file.
* Run `nu-check` on files before linting with `use <file>` or `source
<file>`
* Updates the environment variable to `TEST_METHOD` with options for
`ide-check` or `import-or-source`.
* Updates the default to `import-or-source` (was `ide-check`) to match
CI
* Removes environment variable from CI since this test method is now the
default.

With this in place we should have far fewer (false positive) failing CI
runs.
2025-02-17 09:14:30 -05:00

127 lines
3.8 KiB
Text

# 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.
# Check that all the tests pass.
#
# Input:
# Optional file paths to check or infer them from Git
export def test [
--full # Check all files instead of input
--and-exit # Exit with error count
]: [list<path> -> int, nothing -> int] {
with files --full=$full --and-exit=$and_exit { |files|
print "test: not implemented!"
[0] # success code
}
}
# Run all the necessary checks and tests to submit a perfect PR.
#
# Input:
# Optional file paths to check or infer them from Git
export def "check pr" [
--full # Check all files instead of input
--and-exit # Exit with error count
]: [list<path> -> int, nothing -> int] {
with files --full=$full --and-exit=$and_exit { |files|
[
{ lint }
{ test }
] | par-each { |task| $files | do $task } # TODO: buffer output
}
}
# View subcommands.
export def main []: nothing -> string {
help toolkit
}
# Wrap file lookup and exit codes.
def "with files" [
task: closure
--full
--and-exit
]: [list<path> -> int, nothing -> int] {
let files = match [$in, $full] {
[_ true] => (glob **/*.nu --exclude [before_v0.60/**])
[null _] => (git diff --name-only origin/main | lines)
[$files _] => $files
} | where $it ends-with .nu and ($it | path exists)
let error_count = if ($files | length) == 0 {
print 'warning: no .nu files found!'
0
} else {
$files
| each { path expand }
| do $task $files # run the closure with both input and param
| math sum # it MUST return a non-empty list of ints
}
if $and_exit {
exit $error_count
} else {
$error_count
}
}
export def "lint check" []: path -> int {
let file = $in
let test_methodology = $env.TEST_METHOD? | default "import-or-source"
const current_path = (path self)
let diagnostics = match $test_methodology {
ide-check => {
nu --ide-check 10 $file
| $"[($in)]"
| from nuon
| where type == diagnostic
| select severity message
}
import-or-source => {
# If any line in the file starts with `export`, then
# we assume it is a module. Otherwise, treat it as source
let has_exports = (open $file | $in like '(?m)^export\s')
if $has_exports {
# treat as module
if not (nu-check --as-module $file) {
do { nu --no-config-file --commands $"use '($file)'" }
| complete
| [[severity message]; [$in.exit_code $in.stderr]]
| where severity != 0
}
} else {
if not (nu-check $file) {
do { nu --no-config-file --commands $"source '($file)'" }
| complete
| [[severity message]; [$in.exit_code $in.stderr]]
| where severity != 0
}
}
}
_ => { error make { msg: "Invalid TEST_METHOD"}}
}
let error_count = $diagnostics | length
if $error_count == 0 {
print $"lint: ✔ ($file) is ok"
} else {
print $"lint: ❌ ($file) has errors:\n($diagnostics | table)"
}
$error_count
}
# Check that all the files parse.
#
# Input:
# Optional file paths to check or infer them from Git
export def lint [
--full # Check all files instead of input
--and-exit # Exit with error count
]: [list<path> -> int, nothing -> int] {
with files --full=$full --and-exit=$and_exit {
par-each { lint check }
}
}