mirror of
https://github.com/nushell/nushell
synced 2025-01-13 21:55:07 +00:00
flag to pass config file in nu (#4552)
* flag to pass config file in nu * return when no folder is created * simple syntax for function
This commit is contained in:
parent
efd62f917f
commit
965cea3af5
4 changed files with 88 additions and 59 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3312,7 +3312,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "reedline"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/nushell/reedline?branch=main#42ec23f08399519e79077921a08901420e27b05c"
|
||||
source = "git+https://github.com/nushell/reedline?branch=main#e87e9d1fd3d392308975fb6f89c1a67cc43bc8b9"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossterm",
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use crate::is_perf_true;
|
||||
use crate::utils::{eval_source, report_error};
|
||||
use log::info;
|
||||
use nu_parser::ParseError;
|
||||
use nu_path::canonicalize_with;
|
||||
use nu_protocol::engine::{EngineState, Stack, StateDelta, StateWorkingSet};
|
||||
use nu_protocol::{PipelineData, Span};
|
||||
use nu_protocol::{PipelineData, Span, Spanned};
|
||||
use std::path::PathBuf;
|
||||
|
||||
const NUSHELL_FOLDER: &str = "nushell";
|
||||
|
@ -38,54 +40,73 @@ pub(crate) fn read_plugin_file(engine_state: &mut EngineState, stack: &mut Stack
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_config_file(engine_state: &mut EngineState, stack: &mut Stack) {
|
||||
pub(crate) fn read_config_file(
|
||||
engine_state: &mut EngineState,
|
||||
stack: &mut Stack,
|
||||
config_file: Option<Spanned<String>>,
|
||||
) {
|
||||
// Load config startup file
|
||||
if let Some(mut config_path) = nu_path::config_dir() {
|
||||
if let Some(file) = config_file {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
let cwd = working_set.get_cwd();
|
||||
|
||||
match canonicalize_with(&file.item, cwd) {
|
||||
Ok(path) => {
|
||||
eval_config_contents(path, engine_state, stack);
|
||||
}
|
||||
Err(_) => {
|
||||
let e = ParseError::FileNotFound(file.item, file.span);
|
||||
report_error(&working_set, &e);
|
||||
}
|
||||
}
|
||||
} else if let Some(mut config_path) = nu_path::config_dir() {
|
||||
config_path.push(NUSHELL_FOLDER);
|
||||
|
||||
// Create config directory if it does not exist
|
||||
if !config_path.exists() {
|
||||
if let Err(err) = std::fs::create_dir_all(&config_path) {
|
||||
eprintln!("Failed to create config directory: {}", err);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
config_path.push(CONFIG_FILE);
|
||||
}
|
||||
|
||||
if config_path.exists() {
|
||||
// FIXME: remove this message when we're ready
|
||||
//println!("Loading config from: {:?}", config_path);
|
||||
let config_filename = config_path.to_string_lossy().to_owned();
|
||||
config_path.push(CONFIG_FILE);
|
||||
eval_config_contents(config_path, engine_state, stack);
|
||||
}
|
||||
|
||||
if let Ok(contents) = std::fs::read(&config_path) {
|
||||
eval_source(
|
||||
engine_state,
|
||||
stack,
|
||||
&contents,
|
||||
&config_filename,
|
||||
PipelineData::new(Span::new(0, 0)),
|
||||
);
|
||||
// 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(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);
|
||||
}
|
||||
if is_perf_true() {
|
||||
info!("read_config_file {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_config_contents(config_path: PathBuf, engine_state: &mut EngineState, stack: &mut Stack) {
|
||||
if config_path.exists() & config_path.is_file() {
|
||||
let config_filename = config_path.to_string_lossy().to_owned();
|
||||
|
||||
if let Ok(contents) = std::fs::read(&config_path) {
|
||||
eval_source(
|
||||
engine_state,
|
||||
stack,
|
||||
&contents,
|
||||
&config_filename,
|
||||
PipelineData::new(Span::new(0, 0)),
|
||||
);
|
||||
|
||||
// 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(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if is_perf_true() {
|
||||
info!("read_config_file {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn create_history_path() -> Option<PathBuf> {
|
||||
|
|
47
src/main.rs
47
src/main.rs
|
@ -78,7 +78,6 @@ fn main() -> Result<()> {
|
|||
// Would be nice if we had a way to parse this. The first flags we see will be going to nushell
|
||||
// then it'll be the script name
|
||||
// then the args to the script
|
||||
|
||||
let mut collect_arg_nushell = false;
|
||||
for arg in std::env::args().skip(1) {
|
||||
if !script_name.is_empty() {
|
||||
|
@ -102,13 +101,14 @@ fn main() -> Result<()> {
|
|||
|| arg == "--develop"
|
||||
|| arg == "--debug"
|
||||
|| arg == "--loglevel"
|
||||
|| arg == "--config-file"
|
||||
|| arg == "--config"
|
||||
|| arg == "--perf"
|
||||
|| arg == "--threads"
|
||||
|| arg == "--version"
|
||||
{
|
||||
collect_arg_nushell = true;
|
||||
}
|
||||
|
||||
args_to_nushell.push(arg);
|
||||
} else {
|
||||
// Our script file
|
||||
|
@ -198,7 +198,7 @@ fn main() -> Result<()> {
|
|||
|
||||
ret_val
|
||||
} else {
|
||||
let ret_val = repl::evaluate(&mut engine_state);
|
||||
let ret_val = repl::evaluate(&mut engine_state, binary_args.config_file);
|
||||
if is_perf_true() {
|
||||
info!("repl eval {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
|
@ -255,29 +255,26 @@ fn parse_commandline_args(
|
|||
let commands: Option<Expression> = call.get_flag_expr("commands");
|
||||
let testbin: Option<Expression> = call.get_flag_expr("testbin");
|
||||
let perf = call.has_flag("perf");
|
||||
let config_file: Option<Expression> = call.get_flag_expr("config");
|
||||
let threads: Option<Value> = call.get_flag(engine_state, &mut stack, "threads")?;
|
||||
|
||||
let commands = if let Some(expression) = commands {
|
||||
let contents = engine_state.get_span_contents(&expression.span);
|
||||
fn extract_contents(
|
||||
expression: Option<Expression>,
|
||||
engine_state: &mut EngineState,
|
||||
) -> Option<Spanned<String>> {
|
||||
expression.map(|expr| {
|
||||
let contents = engine_state.get_span_contents(&expr.span);
|
||||
|
||||
Some(Spanned {
|
||||
item: String::from_utf8_lossy(contents).to_string(),
|
||||
span: expression.span,
|
||||
Spanned {
|
||||
item: String::from_utf8_lossy(contents).to_string(),
|
||||
span: expr.span,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
let testbin = if let Some(expression) = testbin {
|
||||
let contents = engine_state.get_span_contents(&expression.span);
|
||||
|
||||
Some(Spanned {
|
||||
item: String::from_utf8_lossy(contents).to_string(),
|
||||
span: expression.span,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let commands = extract_contents(commands, engine_state);
|
||||
let testbin = extract_contents(testbin, engine_state);
|
||||
let config_file = extract_contents(config_file, engine_state);
|
||||
|
||||
let help = call.has_flag("help");
|
||||
|
||||
|
@ -311,6 +308,7 @@ fn parse_commandline_args(
|
|||
interactive_shell,
|
||||
commands,
|
||||
testbin,
|
||||
config_file,
|
||||
perf,
|
||||
threads,
|
||||
});
|
||||
|
@ -330,6 +328,7 @@ struct NushellCliArgs {
|
|||
interactive_shell: Option<Spanned<String>>,
|
||||
commands: Option<Spanned<String>>,
|
||||
testbin: Option<Spanned<String>>,
|
||||
config_file: Option<Spanned<String>>,
|
||||
perf: bool,
|
||||
threads: Option<Value>,
|
||||
}
|
||||
|
@ -371,6 +370,12 @@ impl Command for Nu {
|
|||
SyntaxShape::Filepath,
|
||||
"name of the optional script file to run",
|
||||
)
|
||||
.named(
|
||||
"config",
|
||||
SyntaxShape::String,
|
||||
"run internal test binary",
|
||||
None,
|
||||
)
|
||||
.named(
|
||||
"threads",
|
||||
SyntaxShape::Int,
|
||||
|
|
|
@ -12,15 +12,18 @@ use nu_cli::{NuCompleter, NuHighlighter, NuValidator, NushellPrompt};
|
|||
use nu_color_config::get_color_config;
|
||||
use nu_engine::convert_env_values;
|
||||
use nu_parser::lex;
|
||||
use nu_protocol::PipelineData;
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, StateWorkingSet},
|
||||
Config, ShellError, Span, Value, CONFIG_VARIABLE_ID,
|
||||
};
|
||||
use nu_protocol::{PipelineData, Spanned};
|
||||
use reedline::{DefaultHinter, Emacs, Vi};
|
||||
use std::{sync::atomic::Ordering, time::Instant};
|
||||
|
||||
pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> {
|
||||
pub(crate) fn evaluate(
|
||||
engine_state: &mut EngineState,
|
||||
config_file: Option<Spanned<String>>,
|
||||
) -> Result<()> {
|
||||
// use crate::logger::{configure, logger};
|
||||
use reedline::{FileBackedHistory, Reedline, Signal};
|
||||
|
||||
|
@ -53,7 +56,7 @@ pub(crate) fn evaluate(engine_state: &mut EngineState) -> Result<()> {
|
|||
info!("read_config_file {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
|
||||
config_files::read_config_file(engine_state, &mut stack);
|
||||
config_files::read_config_file(engine_state, &mut stack, config_file);
|
||||
let history_path = config_files::create_history_path();
|
||||
|
||||
// Load config struct form config variable
|
||||
|
|
Loading…
Reference in a new issue