nushell: Can't use standard library module within the standard library (?)
Describe the bug
Trying to add a call to std log info in crates/nu-std/lib/dirs.nu for, e.g, std dirs next, another module in the standard library.
It would be a grave restriction indeed if some commands in the standard library could not be used within other commands of the standard library.
How to reproduce
- in crates/nu-std/lib/dirs.nu (for example), add
use std log infoin either of the locations indicated below (or both). - `〉cargo run – -c ‘use std *; dirs next’
- or do a build and run the binary:
> cargo build; target/debug/nu -c 'use std *; dirs next'
Expected behavior
Info log output from invoked dirs next command
Screenshots
10 repetitions of the ‘module not found’ error, all from the same source line.
~/src/rust/nushell〉cargo run -- -c 'use std *; dirs next'
Finished dev [unoptimized + debuginfo] target(s) in 0.25s
Running `target/debug/nu -c 'use std *; dirs next'`
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
Error: nu::parser::module_not_found
× Module not found.
╭─[dirs:33:1]
33 │ ] {
34 │ use std "log info"
· ─┬─
· ╰── module not found
35 │
╰────
help: module files and their paths must be available before your script is run as parsing occurs before anything
is evaluated
thread 'main' panicked at 'Internal error: can't run a predeclaration without a body', crates/nu-protocol/src/signature.rs:686:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: nu::shell::column_not_found
Configuration
| key | value |
|---|---|
| version | 0.78.1 |
| branch | stdlib_contributing |
| commit_hash | f2b977b9c59931ad2b5e55174e63ebbec50b8cbe |
| build_os | linux-x86_64 |
| build_target | x86_64-unknown-linux-gnu |
| rust_version | rustc 1.66.1 (90743e729 2023-01-10) |
| rust_channel | 1.66.1-x86_64-unknown-linux-gnu |
| cargo_version | cargo 1.66.1 (ad779e08b 2023-01-10) |
| build_time | 2023-04-07 21:17:57 -04:00 |
| build_rust_channel | debug |
| features | default, zip |
| installed_plugins |
Additional context
Here’s the relevant chunk of dirs.nu:
# Maintain a list of working directories and navigates them
use std "log info"
# the directory stack
export-env {
let-env DIRS_POSITION = 0
let-env DIRS_LIST = [($env.PWD | path expand)]
}
# Add one or more directories to the list.
# PWD becomes first of the newly added directories.
export def-env "dirs add" [
...paths: string # directory or directories to add to working list
] {
mut abspaths = []
for p in $paths {
let exp = ($p | path expand)
if ($exp | path type) != 'dir' {
let span = (metadata $p).span
error make {msg: "not a directory", label: {text: "not a directory", start: $span.start, end: $span.end } }
}
$abspaths = ($abspaths | append $exp)
}
let-env DIRS_LIST = ($env.DIRS_LIST | insert ($env.DIRS_POSITION + 1) $abspaths | flatten)
let-env DIRS_POSITION = $env.DIRS_POSITION + 1
_fetch 0
}
# Advance to the next directory in the list or wrap to beginning.
export def-env "dirs next" [
N:int = 1 # number of positions to move.
] {
use std "log info"
_fetch $N
log info $"advancing to position ($env.DIRS_POSITION)"
}
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15 (14 by maintainers)
Commits related to this issue
- stdlib: make helper modules available in std (#8841) > **Note** > waiting for the following to land > - https://github.com/nushell/nushell/pull/8824 to avoid conflicts, i'll add this to `CONTRIBUT... — committed to nushell/nushell by amtoine a year ago
- Squashed commit of the following: commit 8ee52b6ee1cebfbb265d68efcffed97254a7c252 Author: JT <547158+jntrnr@users.noreply.github.com> Date: Wed Apr 12 05:21:52 2023 +1200 Relax the closure syn... — committed to MariaSolOs/nushell by MariaSolOs a year ago
@bobhy The file cache would allow you to use
use log.nufrom insidestd.nuloaded inside Nushell without the files being on the disk. It would need to be marked as a “virtual file” or something like that which would bypass the otherwise mandatory check whether the file contents have changed (they cannot change because it’s read-only). At least that’s my idea how to solve this problem that doesn’t require redesigning the current module system.@amtoine, as a quick fix, it seems reasonable to me to load helpers first so they can be used by all, like log and assert.
Ah, I see. Seems like we should finally create the long-awaited file cache and make
useetc. aware of it. Then, when callinguse log.nu, the parser would look into the cache first, see thatlog.nuwas already parsed before and give the parsed module without reparsing. That way you don’t need the file to be on disk. Since the file is not in the file system, there is no chance it could change, so it should be safe to do so. We could` also write out the stdlib into real files but that brings issues with versioning etc.If possible, I’d prefer not having submodules aware of being a part of some top module because it adds a lot of complexity and hinders code reuse. So far, we used a simple file-based module system that I think works quite well and is very straightforward. The stdlib is special because it doesn’t have real files at runtime, but I think that’s the only case where you’d have a Nushell module without a corresponding .nu file. The only other one I can think of are plugins in the future. If we make the file cache aware of this, we should be able to get around it.