Enable conditional source and use patterns by allowing null as a no-op module (#14773)

Related:
- #14329
- #13872
- #8214

# Description & User-Facing Changes

This PR allows enables the following uses, which are all no-op.
```nushell
source null
source-env null
use null
overlay use null
```

The motivation for this change is conditional sourcing of files. For
example, with this change `login.nu` may be deprecated and replaced with
the following code in `config.nu`
```nushell
const login_module = if $nu.is-login { "login.nu" } else { null }
source $login_module
```

# Tests + Formatting
I'm hoping for CI to pass 😄

# After Submitting
Add a part about the conditional sourcing pattern to the website.
This commit is contained in:
Bahex
2025-01-09 15:37:27 +03:00
committed by GitHub
parent 5cf6dea997
commit 79f19f2fc7
7 changed files with 160 additions and 25 deletions

View File

@ -24,8 +24,8 @@ impl Command for OverlayUse {
.allow_variants_without_examples(true)
.required(
"name",
SyntaxShape::String,
"Module name to use overlay for.",
SyntaxShape::OneOf(vec![SyntaxShape::String, SyntaxShape::Nothing]),
"Module name to use overlay for (`null` for no-op).",
)
.optional(
"as",
@ -61,6 +61,11 @@ impl Command for OverlayUse {
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let noop = call.get_parser_info(caller_stack, "noop");
if noop.is_some() {
return Ok(PipelineData::empty());
}
let mut name_arg: Spanned<String> = call.req(engine_state, caller_stack, 0)?;
name_arg.item = trim_quotes_str(&name_arg.item).to_string();

View File

@ -22,7 +22,11 @@ impl Command for Use {
Signature::build("use")
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.allow_variants_without_examples(true)
.required("module", SyntaxShape::String, "Module or module file.")
.required(
"module",
SyntaxShape::OneOf(vec![SyntaxShape::String, SyntaxShape::Nothing]),
"Module or module file (`null` for no-op).",
)
.rest(
"members",
SyntaxShape::Any,
@ -54,6 +58,9 @@ This command is a parser keyword. For details, check:
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
if call.get_parser_info(caller_stack, "noop").is_some() {
return Ok(PipelineData::empty());
}
let Some(Expression {
expr: Expr::ImportPattern(import_pattern),
..