mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 06:55:36 +02:00
Refactor nu-cli/env* (#3041)
* Revert "History, more test coverage improvements, and refactorings. (#3217)"
This reverts commit 8fc8fc89aa
.
* Add tests
* Refactor .nu-env
* Change logic of Config write to logic of read()
* Fix reload always appends to old vars
* Fix reload always takes last_modified of global config
* Add reload_config in evaluation context
* Reload config after writing to it in cfg set / cfg set_into
* Add --no-history to cli options
* Use --no-history in tests
* Add comment about maybe_print_errors
* Get ctrl_exit var from context.global_config
* Use context.global_config in command "config"
* Add Readme in engine how env vars are now handled
* Update docs from autoenv command
* Move history_path from engine to nu_data
* Move load history out of if
* No let before return
* Add import for indexmap
This commit is contained in:
@ -2,49 +2,8 @@ use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
pub struct Autoenv;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||
pub struct Trusted {
|
||||
pub files: IndexMap<String, Vec<u8>>,
|
||||
}
|
||||
impl Trusted {
|
||||
pub fn new() -> Self {
|
||||
Trusted {
|
||||
files: IndexMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn file_is_trusted(nu_env_file: &Path, content: &[u8]) -> Result<bool, ShellError> {
|
||||
let contentdigest = Sha256::digest(&content).as_slice().to_vec();
|
||||
let nufile = std::fs::canonicalize(nu_env_file)?;
|
||||
|
||||
let trusted = read_trusted()?;
|
||||
|
||||
Ok(trusted.files.get(&nufile.to_string_lossy().to_string()) == Some(&contentdigest))
|
||||
}
|
||||
|
||||
pub fn read_trusted() -> Result<Trusted, ShellError> {
|
||||
let config_path = config::default_path_for(&Some(PathBuf::from("nu-env.toml")))?;
|
||||
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(config_path)
|
||||
.map_err(|_| ShellError::untagged_runtime_error("Couldn't open nu-env.toml"))?;
|
||||
let mut doc = String::new();
|
||||
file.read_to_string(&mut doc)?;
|
||||
|
||||
let allowed = toml::de::from_str(doc.as_str()).unwrap_or_else(|_| Trusted::new());
|
||||
Ok(allowed)
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for Autoenv {
|
||||
fn name(&self) -> &str {
|
||||
@ -56,11 +15,12 @@ impl WholeStreamCommand for Autoenv {
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
// "Mark a .nu-env file in a directory as trusted. Needs to be re-run after each change to the file or its filepath."
|
||||
r#"Create a file called .nu-env in any directory and run 'autoenv trust' to let nushell read it when entering the directory.
|
||||
The file can contain several optional sections:
|
||||
env: environment variables to set when visiting the directory. The variables are unset after leaving the directory and any overwritten values are restored.
|
||||
scriptvars: environment variables that should be set to the return value of a script. After they have been set, they behave in the same way as variables set in the env section.
|
||||
scripts: scripts to run when entering the directory or leaving it."#
|
||||
r#"Create a file called .nu-env in any directory and run 'autoenv trust' to let nushell load it when entering the directory.
|
||||
The .nu-env file has the same format as your $HOME/nu/config.toml file. By loading a .nu-env file the following applies:
|
||||
- environment variables (section \"[env]\") are loaded from the .nu-env file. Those env variables are only existend in this directory (and children directories)
|
||||
- the \"startup\" commands are run when entering the directory
|
||||
- the \"on_exit\" commands are run when leaving the directory
|
||||
"#
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
@ -76,15 +36,12 @@ The file can contain several optional sections:
|
||||
vec![Example {
|
||||
description: "Example .nu-env file",
|
||||
example: r#"cat .nu-env
|
||||
startup = ["echo ...entering the directory", "echo 1 2 3"]
|
||||
on_exit = ["echo ...leaving the directory"]
|
||||
|
||||
[env]
|
||||
mykey = "myvalue"
|
||||
|
||||
[scriptvars]
|
||||
myscript = "echo myval"
|
||||
|
||||
[scripts]
|
||||
entryscripts = ["touch hello.txt", "touch hello2.txt"]
|
||||
exitscripts = ["touch bye.txt"]"#,
|
||||
"#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::autoenv::read_trusted;
|
||||
use crate::prelude::*;
|
||||
use nu_data::config::read_trusted;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::SyntaxShape;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::autoenv::Trusted;
|
||||
use crate::prelude::*;
|
||||
use nu_data::config::Trusted;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::SyntaxShape;
|
||||
|
@ -2,7 +2,7 @@ use crate::commands::autoview::options::{ConfigExtensions, NuConfig as AutoViewC
|
||||
use crate::prelude::*;
|
||||
use crate::primitive::get_color_config;
|
||||
use nu_data::value::format_leaf;
|
||||
use nu_engine::{UnevaluatedCallInfo, WholeStreamCommand};
|
||||
use nu_engine::{ConfigHolder, RunnableContext, UnevaluatedCallInfo, WholeStreamCommand};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::hir::{self, Expression, ExternalRedirection, Literal, SpannedExpression};
|
||||
use nu_protocol::{Primitive, Signature, UntaggedValue, Value};
|
||||
@ -27,16 +27,7 @@ impl WholeStreamCommand for Command {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
autoview(RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
})
|
||||
.await
|
||||
autoview(RunnableContext::from_command_args(args)).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -60,6 +51,7 @@ pub struct RunnableContextWithoutInput {
|
||||
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
|
||||
pub current_errors: Arc<Mutex<Vec<ShellError>>>,
|
||||
pub ctrl_c: Arc<AtomicBool>,
|
||||
pub configs: Arc<Mutex<ConfigHolder>>,
|
||||
pub scope: Scope,
|
||||
pub name: Tag,
|
||||
}
|
||||
@ -70,6 +62,7 @@ impl RunnableContextWithoutInput {
|
||||
shell_manager: context.shell_manager,
|
||||
host: context.host,
|
||||
ctrl_c: context.ctrl_c,
|
||||
configs: context.configs,
|
||||
current_errors: context.current_errors,
|
||||
scope: context.scope,
|
||||
name: context.name,
|
||||
@ -288,6 +281,7 @@ fn create_default_command_args(context: &RunnableContextWithoutInput) -> RawComm
|
||||
RawCommandArgs {
|
||||
host: context.host.clone(),
|
||||
ctrl_c: context.ctrl_c.clone(),
|
||||
configs: context.configs.clone(),
|
||||
current_errors: context.current_errors.clone(),
|
||||
shell_manager: context.shell_manager.clone(),
|
||||
call_info: UnevaluatedCallInfo {
|
||||
|
@ -509,7 +509,7 @@ mod tests {
|
||||
#[cfg(feature = "which")]
|
||||
use futures::executor::block_on;
|
||||
#[cfg(feature = "which")]
|
||||
use nu_engine::EvaluationContext;
|
||||
use nu_engine::basic_evaluation_context;
|
||||
#[cfg(feature = "which")]
|
||||
use nu_errors::ShellError;
|
||||
#[cfg(feature = "which")]
|
||||
@ -534,7 +534,7 @@ mod tests {
|
||||
|
||||
let input = InputStream::empty();
|
||||
let mut ctx =
|
||||
EvaluationContext::basic().expect("There was a problem creating a basic context.");
|
||||
basic_evaluation_context().expect("There was a problem creating a basic context.");
|
||||
|
||||
assert!(
|
||||
run_external_command(cmd, &mut ctx, input, ExternalRedirection::Stdout)
|
||||
@ -548,7 +548,7 @@ mod tests {
|
||||
// async fn failure_run() -> Result<(), ShellError> {
|
||||
// let cmd = ExternalBuilder::for_name("fail").build();
|
||||
|
||||
// let mut ctx = crate::cli::EvaluationContext::basic().expect("There was a problem creating a basic context.");
|
||||
// let mut ctx = crate::cli::basic_evaluation_context().expect("There was a problem creating a basic context.");
|
||||
// let stream = run_external_command(cmd, &mut ctx, None, false)
|
||||
// .await?
|
||||
// .expect("There was a problem running the external command.");
|
||||
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::CommandArgs;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
use nu_stream::OutputStream;
|
||||
|
||||
pub struct Command;
|
||||
@ -22,20 +22,21 @@ impl WholeStreamCommand for Command {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let name = args.call_info.name_tag;
|
||||
|
||||
let path = match args.scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
};
|
||||
let result = nu_data::config::read(&name, &path)?;
|
||||
|
||||
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
)])
|
||||
.to_output_stream())
|
||||
if let Some(global_cfg) = &args.configs.lock().global_config {
|
||||
let result = global_cfg.vars.clone();
|
||||
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
)])
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Ok(
|
||||
futures::stream::iter(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error("No global config found!"),
|
||||
))])
|
||||
.to_output_stream(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
ColumnPath, ConfigPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
|
||||
pub struct SubCommand;
|
||||
@ -61,6 +61,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let scope = args.scope.clone();
|
||||
let (
|
||||
Arguments {
|
||||
@ -93,6 +94,10 @@ pub async fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
..
|
||||
}) => {
|
||||
config::write(&changes.entries, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(changes).into_value(name),
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
ConfigPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct SubCommand;
|
||||
@ -44,6 +46,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let scope = args.scope.clone();
|
||||
let (Arguments { set_into: v }, input) = args.process().await?;
|
||||
|
||||
@ -73,6 +76,10 @@ pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
result.insert(key, value.clone());
|
||||
|
||||
config::write(&result, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))
|
||||
.await?;
|
||||
|
||||
OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
@ -84,6 +91,10 @@ pub async fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
result.insert(key, value);
|
||||
|
||||
config::write(&result, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))
|
||||
.await?;
|
||||
|
||||
OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_engine::whole_stream_command;
|
||||
use nu_engine::EvaluationContext;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Box<dyn Error>> {
|
||||
let context = EvaluationContext::basic()?;
|
||||
let context = basic_evaluation_context()?;
|
||||
|
||||
{
|
||||
use crate::commands::*;
|
||||
|
@ -81,6 +81,7 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let shell_manager = raw_args.shell_manager.clone();
|
||||
let head = raw_args.call_info.args.head.clone();
|
||||
let ctrl_c = raw_args.ctrl_c.clone();
|
||||
let configs = raw_args.configs.clone();
|
||||
let current_errors = raw_args.current_errors.clone();
|
||||
let host = raw_args.host.clone();
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
@ -132,6 +133,7 @@ async fn enter(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let new_args = RawCommandArgs {
|
||||
host,
|
||||
ctrl_c,
|
||||
configs,
|
||||
current_errors,
|
||||
shell_manager,
|
||||
call_info: UnevaluatedCallInfo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::prelude::*;
|
||||
use nu_data::config::{path::history as history_path, NuConfig};
|
||||
use nu_data::config::{Conf, NuConfig};
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
@ -33,11 +33,11 @@ impl WholeStreamCommand for History {
|
||||
}
|
||||
|
||||
async fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let config = NuConfig::new();
|
||||
let config: Box<dyn Conf> = Box::new(NuConfig::new());
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (Arguments { clear }, _) = args.process().await?;
|
||||
|
||||
let path = history_path(&config);
|
||||
let path = nu_data::config::path::history_path(&config);
|
||||
|
||||
match clear {
|
||||
Some(_) => {
|
||||
|
@ -29,19 +29,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
average,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), average).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -23,15 +23,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_numerical_functions_on_stream(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
RunnableContext::from_command_args(args),
|
||||
ceil_big_int,
|
||||
ceil_big_decimal,
|
||||
ceil_default,
|
||||
|
@ -23,15 +23,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_numerical_functions_on_stream(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
RunnableContext::from_command_args(args),
|
||||
floor_big_int,
|
||||
floor_big_decimal,
|
||||
floor_default,
|
||||
|
@ -22,19 +22,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
maximum,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), maximum).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -26,19 +26,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
median,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), median).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -22,19 +22,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
minimum,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), minimum).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -22,19 +22,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
mode,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), mode).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -22,19 +22,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
product,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), product).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -23,19 +23,7 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
async fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
scope: args.scope.clone(),
|
||||
shell_manager: args.shell_manager,
|
||||
host: args.host,
|
||||
ctrl_c: args.ctrl_c,
|
||||
current_errors: args.current_errors,
|
||||
name: args.call_info.name_tag,
|
||||
},
|
||||
summation,
|
||||
)
|
||||
.await
|
||||
run_with_function(RunnableContext::from_command_args(args), summation).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -83,9 +83,9 @@ impl WholeStreamCommand for RunExternalCommand {
|
||||
EvaluationContext {
|
||||
scope: args.scope.clone(),
|
||||
host: args.host.clone(),
|
||||
user_recently_used_autoenv_untrust: Arc::new(AtomicBool::new(false)),
|
||||
shell_manager: args.shell_manager.clone(),
|
||||
ctrl_c: args.ctrl_c.clone(),
|
||||
configs: args.configs.clone(),
|
||||
current_errors: Arc::new(Mutex::new(vec![])),
|
||||
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
|
||||
}
|
||||
|
@ -168,6 +168,7 @@ async fn save(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let scope = raw_args.scope.clone();
|
||||
let host = raw_args.host.clone();
|
||||
let ctrl_c = raw_args.ctrl_c.clone();
|
||||
let configs = raw_args.configs.clone();
|
||||
let current_errors = raw_args.current_errors.clone();
|
||||
let shell_manager = raw_args.shell_manager.clone();
|
||||
|
||||
@ -215,6 +216,7 @@ async fn save(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let new_args = RawCommandArgs {
|
||||
host,
|
||||
ctrl_c,
|
||||
configs,
|
||||
current_errors,
|
||||
shell_manager: shell_manager.clone(),
|
||||
call_info: UnevaluatedCallInfo {
|
||||
|
@ -6,12 +6,14 @@ mod stub_generate;
|
||||
|
||||
use double_echo::Command as DoubleEcho;
|
||||
use double_ls::Command as DoubleLs;
|
||||
use stub_generate::{mock_path, Command as StubOpen};
|
||||
|
||||
use nu_engine::basic_evaluation_context;
|
||||
use nu_errors::ShellError;
|
||||
use nu_parser::ParserScope;
|
||||
use nu_protocol::hir::ClassifiedBlock;
|
||||
use nu_protocol::{ShellTypeName, Value};
|
||||
use nu_source::AnchorLocation;
|
||||
use stub_generate::{mock_path, Command as StubOpen};
|
||||
|
||||
use crate::commands::{
|
||||
Append, BuildString, Each, Echo, First, Get, Keep, Last, Let, Nth, Select, StrCollect, Wrap,
|
||||
@ -24,7 +26,7 @@ use futures::executor::block_on;
|
||||
pub fn test_examples(cmd: Command) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = EvaluationContext::basic()?;
|
||||
let base_context = basic_evaluation_context()?;
|
||||
|
||||
base_context.add_commands(vec![
|
||||
// Command Doubles
|
||||
@ -90,7 +92,7 @@ pub fn test_examples(cmd: Command) -> Result<(), ShellError> {
|
||||
pub fn test(cmd: impl WholeStreamCommand + 'static) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = EvaluationContext::basic()?;
|
||||
let base_context = basic_evaluation_context()?;
|
||||
|
||||
base_context.add_commands(vec![
|
||||
whole_stream_command(Echo {}),
|
||||
@ -147,7 +149,7 @@ pub fn test(cmd: impl WholeStreamCommand + 'static) -> Result<(), ShellError> {
|
||||
pub fn test_anchors(cmd: Command) -> Result<(), ShellError> {
|
||||
let examples = cmd.examples();
|
||||
|
||||
let base_context = EvaluationContext::basic()?;
|
||||
let base_context = basic_evaluation_context()?;
|
||||
|
||||
base_context.add_commands(vec![
|
||||
// Minimal restricted commands to aid in testing
|
||||
@ -228,10 +230,8 @@ async fn evaluate_block(
|
||||
ctx: &mut EvaluationContext,
|
||||
) -> Result<Vec<Value>, ShellError> {
|
||||
let input_stream = InputStream::empty();
|
||||
let env = ctx.get_env();
|
||||
|
||||
ctx.scope.enter_scope();
|
||||
ctx.scope.add_env(env);
|
||||
|
||||
let result = run_block(&block.block, ctx, input_stream).await;
|
||||
|
||||
|
@ -1,5 +1,17 @@
|
||||
use std::io::{self, BufRead, Write};
|
||||
|
||||
/// Echo's value of env keys from args
|
||||
/// Example: nu --testbin env_echo FOO BAR
|
||||
/// If it it's not present echo's nothing
|
||||
pub fn echo_env() {
|
||||
let args = args();
|
||||
for arg in args {
|
||||
if let Ok(v) = std::env::var(arg) {
|
||||
println!("{}", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cococo() {
|
||||
let args: Vec<String> = args();
|
||||
|
||||
|
Reference in New Issue
Block a user