mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 07:46:01 +02:00
History, more test coverage improvements, and refactorings. (#3217)
Improvements overall to Nu. Also among the changes here, we can also be more confident towards incorporating `3041`. End to end tests for checking envs properly exported to externals is not added here (since it's in the other PR) A few things added in this PR (probably forgetting some too) * no writes happen to history during test runs. * environment syncing end to end coverage added. * clean up / refactorings few areas. * testing API for finer control (can write tests passing more than one pipeline) * can pass environment variables in tests that nu will inherit when running. * No longer needed. * no longer under a module. No need to use super.
This commit is contained in:
committed by
GitHub
parent
b243b3ee1d
commit
8fc8fc89aa
@ -1,5 +1,6 @@
|
||||
mod conf;
|
||||
mod nuconfig;
|
||||
pub mod path;
|
||||
|
||||
pub mod tests;
|
||||
|
||||
@ -185,7 +186,7 @@ pub fn default_path_for(file: &Option<PathBuf>) -> Result<PathBuf, ShellError> {
|
||||
let file: &Path = file
|
||||
.as_ref()
|
||||
.map(AsRef::as_ref)
|
||||
.unwrap_or_else(|| "config.toml".as_ref());
|
||||
.unwrap_or_else(|| self::path::DEFAULT_CONFIG_LOCATION.as_ref());
|
||||
filename.push(file);
|
||||
|
||||
Ok(filename)
|
||||
|
@ -1,7 +1,9 @@
|
||||
use nu_protocol::Value;
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait Conf: Debug + Send {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn is_modified(&self) -> Result<bool, Box<dyn std::error::Error>>;
|
||||
fn var(&self, key: &str) -> Option<Value>;
|
||||
fn env(&self) -> Option<Value>;
|
||||
@ -11,6 +13,10 @@ pub trait Conf: Debug + Send {
|
||||
}
|
||||
|
||||
impl Conf for Box<dyn Conf> {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn is_modified(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
(**self).is_modified()
|
||||
}
|
||||
|
@ -2,15 +2,22 @@ use crate::config::{last_modified, read, Conf, Status};
|
||||
use indexmap::IndexMap;
|
||||
use nu_protocol::Value;
|
||||
use nu_source::Tag;
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct NuConfig {
|
||||
pub source_file: Option<std::path::PathBuf>,
|
||||
pub vars: IndexMap<String, Value>,
|
||||
pub modified_at: Status,
|
||||
}
|
||||
|
||||
impl Conf for NuConfig {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn is_modified(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
self.is_modified()
|
||||
}
|
||||
@ -30,7 +37,7 @@ impl Conf for NuConfig {
|
||||
fn reload(&mut self) {
|
||||
let vars = &mut self.vars;
|
||||
|
||||
if let Ok(variables) = read(Tag::unknown(), &None) {
|
||||
if let Ok(variables) = read(Tag::unknown(), &self.source_file) {
|
||||
vars.extend(variables);
|
||||
|
||||
self.modified_at = if let Ok(status) = last_modified(&None) {
|
||||
@ -60,6 +67,7 @@ impl NuConfig {
|
||||
};
|
||||
|
||||
NuConfig {
|
||||
source_file: source_file.clone(),
|
||||
vars,
|
||||
modified_at: NuConfig::get_last_modified(&source_file),
|
||||
}
|
||||
@ -75,11 +83,16 @@ impl NuConfig {
|
||||
};
|
||||
|
||||
NuConfig {
|
||||
source_file: None,
|
||||
vars,
|
||||
modified_at: NuConfig::get_last_modified(&None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn history_path(&self) -> PathBuf {
|
||||
super::path::history(self)
|
||||
}
|
||||
|
||||
pub fn get_last_modified(config_file: &Option<std::path::PathBuf>) -> Status {
|
||||
if let Ok(status) = last_modified(config_file) {
|
||||
status
|
||||
@ -91,15 +104,17 @@ impl NuConfig {
|
||||
pub fn is_modified(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let modified_at = &self.modified_at;
|
||||
|
||||
Ok(match (NuConfig::get_last_modified(&None), modified_at) {
|
||||
(Status::LastModified(left), Status::LastModified(right)) => {
|
||||
let left = left.duration_since(std::time::UNIX_EPOCH)?;
|
||||
let right = (*right).duration_since(std::time::UNIX_EPOCH)?;
|
||||
Ok(
|
||||
match (NuConfig::get_last_modified(&self.source_file), modified_at) {
|
||||
(Status::LastModified(left), Status::LastModified(right)) => {
|
||||
let left = left.duration_since(std::time::UNIX_EPOCH)?;
|
||||
let right = (*right).duration_since(std::time::UNIX_EPOCH)?;
|
||||
|
||||
left != right
|
||||
}
|
||||
(_, _) => false,
|
||||
})
|
||||
left != right
|
||||
}
|
||||
(_, _) => false,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn var(&self, key: &str) -> Option<Value> {
|
||||
|
32
crates/nu-data/src/config/path.rs
Normal file
32
crates/nu-data/src/config/path.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use crate::config::NuConfig;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub const DEFAULT_CONFIG_LOCATION: &str = "config.toml";
|
||||
const DEFAULT_HISTORY_LOCATION: &str = "history.txt";
|
||||
|
||||
pub fn history(config: &NuConfig) -> PathBuf {
|
||||
let default_path = crate::config::user_data()
|
||||
.map(|mut p| {
|
||||
p.push(DEFAULT_HISTORY_LOCATION);
|
||||
p
|
||||
})
|
||||
.unwrap_or_else(|_| PathBuf::from(DEFAULT_HISTORY_LOCATION));
|
||||
|
||||
let path = &config.var("history-path");
|
||||
|
||||
path.as_ref().map_or(default_path.clone(), |custom_path| {
|
||||
match custom_path.as_string() {
|
||||
Ok(path) => PathBuf::from(path),
|
||||
Err(_) => default_path,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn source_file(config: &NuConfig) -> PathBuf {
|
||||
match &config.source_file {
|
||||
Some(path) => PathBuf::from(path),
|
||||
None => {
|
||||
crate::config::default_path().unwrap_or_else(|_| PathBuf::from(DEFAULT_CONFIG_LOCATION))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
use crate::config::{Conf, NuConfig, Status};
|
||||
use nu_protocol::Value;
|
||||
use std::any::Any;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -9,6 +10,10 @@ pub struct FakeConfig {
|
||||
}
|
||||
|
||||
impl Conf for FakeConfig {
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn is_modified(&self) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
self.is_modified()
|
||||
}
|
||||
|
Reference in New Issue
Block a user