nushell/src/eval_file.rs

157 lines
5.0 KiB
Rust
Raw Normal View History

2022-01-18 09:48:28 +01:00
use log::trace;
use miette::{IntoDiagnostic, Result};
use nu_engine::{convert_env_values, eval_block};
use nu_parser::parse;
use nu_protocol::{
engine::{EngineState, StateDelta, StateWorkingSet},
Config, PipelineData, Span, Value, CONFIG_VARIABLE_ID,
};
use std::path::PathBuf;
use crate::utils::{gather_parent_env_vars, report_error};
/// Main function used when a file path is found as argument for nu
pub(crate) fn evaluate(
path: String,
args: &[String],
2022-01-18 09:48:28 +01:00
init_cwd: PathBuf,
engine_state: &mut EngineState,
input: PipelineData,
2022-01-18 09:48:28 +01:00
) -> Result<()> {
// First, set up env vars as strings only
gather_parent_env_vars(engine_state);
let file = std::fs::read(&path).into_diagnostic()?;
let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state);
trace!("parsing file: {}", path);
let (output, err) = parse(&mut working_set, Some(&path), &file, false);
if let Some(err) = err {
report_error(&working_set, &err);
std::process::exit(1);
}
(output, working_set.render())
};
if let Err(err) = engine_state.merge_delta(delta, None, &init_cwd) {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &err);
}
let mut stack = nu_protocol::engine::Stack::new();
// Set up our initial config to start from
stack.vars.insert(
CONFIG_VARIABLE_ID,
Value::Record {
cols: vec![],
vals: vec![],
span: Span { start: 0, end: 0 },
},
);
let config = match stack.get_config() {
Ok(config) => config,
Err(e) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
Config::default()
}
};
// Merge the delta in case env vars changed in the config
match nu_engine::env::current_dir(engine_state, &stack) {
Ok(cwd) => {
if let Err(e) = engine_state.merge_delta(StateDelta::new(), Some(&mut stack), cwd) {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
}
}
Err(e) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
}
}
// Translate environment variables from Strings to Values
if let Some(e) = convert_env_values(engine_state, &stack, &config) {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e);
std::process::exit(1);
}
// Next, let's check if there are any flags we want to pass to the main function
if args.is_empty() && engine_state.find_decl(b"main").is_none() {
// We don't have a main, so evaluate the whole file
match eval_block(engine_state, &mut stack, &block, input) {
Ok(pipeline_data) => {
for item in pipeline_data {
if let Value::Error { error } = item {
let working_set = StateWorkingSet::new(engine_state);
2022-01-18 09:48:28 +01:00
report_error(&working_set, &error);
2022-01-18 09:48:28 +01:00
std::process::exit(1);
}
println!("{}", item.into_string("\n", &config));
2022-01-18 09:48:28 +01:00
}
}
Err(err) => {
let working_set = StateWorkingSet::new(engine_state);
2022-01-18 09:48:28 +01:00
report_error(&working_set, &err);
2022-01-18 09:48:28 +01:00
std::process::exit(1);
2022-01-18 09:48:28 +01:00
}
}
} else {
let args = format!("main {}", args.join(" ")).as_bytes().to_vec();
2022-01-18 09:48:28 +01:00
let (block, delta) = {
let mut working_set = StateWorkingSet::new(engine_state);
let (output, err) = parse(&mut working_set, Some("<cmdline>"), &args, false);
if let Some(err) = err {
report_error(&working_set, &err);
2022-01-18 09:48:28 +01:00
std::process::exit(1);
}
(output, working_set.render())
};
2022-01-18 09:48:28 +01:00
let cwd = nu_engine::env::current_dir_str(engine_state, &stack)?;
2022-01-18 09:48:28 +01:00
if let Err(err) = engine_state.merge_delta(delta, Some(&mut stack), &cwd) {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &err);
}
2022-01-18 09:48:28 +01:00
match eval_block(engine_state, &mut stack, &block, input) {
Ok(pipeline_data) => {
for item in pipeline_data {
if let Value::Error { error } = item {
let working_set = StateWorkingSet::new(engine_state);
2022-01-18 09:48:28 +01:00
report_error(&working_set, &error);
2022-01-18 09:48:28 +01:00
std::process::exit(1);
}
println!("{}", item.into_string("\n", &config));
2022-01-18 09:48:28 +01:00
}
}
Err(err) => {
let working_set = StateWorkingSet::new(engine_state);
2022-01-18 09:48:28 +01:00
report_error(&working_set, &err);
2022-01-18 09:48:28 +01:00
std::process::exit(1);
}
2022-01-18 09:48:28 +01:00
}
}
Ok(())
}