mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
Add unlet_env
command (#3629)
* Add ability to remove env variables Signed-off-by: nathom <nathanthomas707@gmail.com> * Implement unlet_env command Signed-off-by: nathom <nathanthomas707@gmail.com> * Update parameter description Signed-off-by: nathom <nathanthomas707@gmail.com> * Migrate to new filestructure Signed-off-by: nathom <nathanthomas707@gmail.com> * Added tests for unlet-env Signed-off-by: nathom <nathanthomas707@gmail.com> * Formatting Signed-off-by: nathom <nathanthomas707@gmail.com>
This commit is contained in:
parent
26899bc0f0
commit
9e39284de9
5 changed files with 96 additions and 0 deletions
2
crates/nu-command/src/commands/env/mod.rs
vendored
2
crates/nu-command/src/commands/env/mod.rs
vendored
|
@ -3,6 +3,7 @@ mod autoenv_trust;
|
||||||
mod autoenv_untrust;
|
mod autoenv_untrust;
|
||||||
mod let_env;
|
mod let_env;
|
||||||
mod load_env;
|
mod load_env;
|
||||||
|
mod unlet_env;
|
||||||
mod with_env;
|
mod with_env;
|
||||||
|
|
||||||
pub use autoenv::Autoenv;
|
pub use autoenv::Autoenv;
|
||||||
|
@ -10,4 +11,5 @@ pub use autoenv_trust::AutoenvTrust;
|
||||||
pub use autoenv_untrust::AutoenvUntrust;
|
pub use autoenv_untrust::AutoenvUntrust;
|
||||||
pub use let_env::LetEnv;
|
pub use let_env::LetEnv;
|
||||||
pub use load_env::LoadEnv;
|
pub use load_env::LoadEnv;
|
||||||
|
pub use unlet_env::UnletEnv;
|
||||||
pub use with_env::WithEnv;
|
pub use with_env::WithEnv;
|
||||||
|
|
59
crates/nu-command/src/commands/env/unlet_env.rs
vendored
Normal file
59
crates/nu-command/src/commands/env/unlet_env.rs
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
use nu_engine::WholeStreamCommand;
|
||||||
|
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_protocol::{Signature, SyntaxShape};
|
||||||
|
use nu_source::Tagged;
|
||||||
|
|
||||||
|
pub struct UnletEnv;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct UnletEnvArgs {
|
||||||
|
pub name: Tagged<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WholeStreamCommand for UnletEnv {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"unlet-env"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("unlet-env").required(
|
||||||
|
"name",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"the name of the environment variable",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Delete an environment variable."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||||
|
unlet_env(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![Example {
|
||||||
|
description: "Remove the environment variable named FOO.",
|
||||||
|
example: "unlet-env FOO",
|
||||||
|
result: None,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unlet_env(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||||
|
let ctx = &args.context;
|
||||||
|
|
||||||
|
let name: Tagged<String> = args.req(0)?;
|
||||||
|
|
||||||
|
if ctx.scope.remove_env_var(&name.item) == None {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Not an environment variable. Run `echo $nu.env` to view the available variables.",
|
||||||
|
"not an environment variable",
|
||||||
|
name.span(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ActionStream::empty())
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
||||||
whole_stream_command(NuPlugin),
|
whole_stream_command(NuPlugin),
|
||||||
whole_stream_command(Let),
|
whole_stream_command(Let),
|
||||||
whole_stream_command(LetEnv),
|
whole_stream_command(LetEnv),
|
||||||
|
whole_stream_command(UnletEnv),
|
||||||
whole_stream_command(LoadEnv),
|
whole_stream_command(LoadEnv),
|
||||||
whole_stream_command(Def),
|
whole_stream_command(Def),
|
||||||
whole_stream_command(Source),
|
whole_stream_command(Source),
|
||||||
|
|
|
@ -239,6 +239,15 @@ impl Scope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_env_var(&self, name: impl Into<String>) -> Option<String> {
|
||||||
|
if let Some(frame) = self.frames.lock().last_mut() {
|
||||||
|
if let Some(val) = frame.env.remove_entry(&name.into()) {
|
||||||
|
return Some(val.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_env(&self, env_vars: IndexMap<String, String>) {
|
pub fn add_env(&self, env_vars: IndexMap<String, String>) {
|
||||||
if let Some(frame) = self.frames.lock().last_mut() {
|
if let Some(frame) = self.frames.lock().last_mut() {
|
||||||
frame.env.extend(env_vars)
|
frame.env.extend(env_vars)
|
||||||
|
|
|
@ -411,6 +411,31 @@ fn let_env_variable() {
|
||||||
assert_eq!(actual.out, "hello world");
|
assert_eq!(actual.out, "hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unlet_env_variable() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
let-env TEST_VAR = "hello world"
|
||||||
|
unlet-env TEST_VAR
|
||||||
|
echo $nu.env.TEST_VAR
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
assert!(actual.err.contains("did you mean"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unlet_nonexistent_variable() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: ".",
|
||||||
|
r#"
|
||||||
|
unlet-env NONEXISTENT_VARIABLE
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(actual.err.contains("did you mean"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn let_env_doesnt_leak() {
|
fn let_env_doesnt_leak() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
|
Loading…
Reference in a new issue