mirror of
https://github.com/nushell/nushell.git
synced 2025-05-28 22:07:40 +02:00
Allow overlays to import prefixed definitions (#6301)
* WIP * Fix overlay prefix not preserving correctly * Work around failing REPL tests * Remove wrong code when removing with --keep-custom
This commit is contained in:
parent
d885258dc7
commit
c3efb12733
@ -24,12 +24,11 @@ impl Command for OverlayAdd {
|
|||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
"Module name to create overlay for",
|
"Module name to create overlay for",
|
||||||
)
|
)
|
||||||
// TODO:
|
.switch(
|
||||||
// .switch(
|
"prefix",
|
||||||
// "prefix",
|
"Prepend module name to the imported commands and aliases",
|
||||||
// "Prepend module name to the imported symbols",
|
Some('p'),
|
||||||
// Some('p'),
|
)
|
||||||
// )
|
|
||||||
.category(Category::Core)
|
.category(Category::Core)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,13 +121,22 @@ impl Command for OverlayAdd {
|
|||||||
Example {
|
Example {
|
||||||
description: "Create an overlay from a module",
|
description: "Create an overlay from a module",
|
||||||
example: r#"module spam { export def foo [] { "foo" } }
|
example: r#"module spam { export def foo [] { "foo" } }
|
||||||
overlay add spam"#,
|
overlay add spam
|
||||||
|
foo"#,
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
description: "Create an overlay with a prefix",
|
||||||
|
example: r#"echo 'export def foo { "foo" }'
|
||||||
|
overlay add --prefix spam
|
||||||
|
spam foo"#,
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "Create an overlay from a file",
|
description: "Create an overlay from a file",
|
||||||
example: r#"echo 'export env FOO { "foo" }' | save spam.nu
|
example: r#"echo 'export env FOO { "foo" }' | save spam.nu
|
||||||
overlay add spam.nu"#,
|
overlay add spam.nu
|
||||||
|
$env.FOO"#,
|
||||||
result: None,
|
result: None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -124,6 +124,18 @@ pub enum ParseError {
|
|||||||
#[diagnostic(code(nu::parser::active_overlay_not_found), url(docsrs))]
|
#[diagnostic(code(nu::parser::active_overlay_not_found), url(docsrs))]
|
||||||
ActiveOverlayNotFound(#[label = "not an active overlay"] Span),
|
ActiveOverlayNotFound(#[label = "not an active overlay"] Span),
|
||||||
|
|
||||||
|
#[error("Overlay prefix mismatch.")]
|
||||||
|
#[diagnostic(
|
||||||
|
code(nu::parser::overlay_prefix_mismatch),
|
||||||
|
url(docsrs),
|
||||||
|
help("Overlay {0} already exists {1} a prefix. To add it again, do it {1} the --prefix flag.")
|
||||||
|
)]
|
||||||
|
OverlayPrefixMismatch(
|
||||||
|
String,
|
||||||
|
String,
|
||||||
|
#[label = "already exists {1} a prefix"] Span,
|
||||||
|
),
|
||||||
|
|
||||||
#[error("Module or overlay not found.")]
|
#[error("Module or overlay not found.")]
|
||||||
#[diagnostic(
|
#[diagnostic(
|
||||||
code(nu::parser::module_or_overlay_not_found),
|
code(nu::parser::module_or_overlay_not_found),
|
||||||
@ -327,6 +339,7 @@ impl ParseError {
|
|||||||
ParseError::ModuleNotFound(s) => *s,
|
ParseError::ModuleNotFound(s) => *s,
|
||||||
ParseError::ModuleOrOverlayNotFound(s) => *s,
|
ParseError::ModuleOrOverlayNotFound(s) => *s,
|
||||||
ParseError::ActiveOverlayNotFound(s) => *s,
|
ParseError::ActiveOverlayNotFound(s) => *s,
|
||||||
|
ParseError::OverlayPrefixMismatch(_, _, s) => *s,
|
||||||
ParseError::CantRemoveLastOverlay(s) => *s,
|
ParseError::CantRemoveLastOverlay(s) => *s,
|
||||||
ParseError::CantRemoveDefaultOverlay(_, s) => *s,
|
ParseError::CantRemoveDefaultOverlay(_, s) => *s,
|
||||||
ParseError::NotFound(s) => *s,
|
ParseError::NotFound(s) => *s,
|
||||||
|
@ -702,21 +702,23 @@ pub fn parse_export(
|
|||||||
|
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
|
|
||||||
let decl_name = working_set.get_span_contents(spans[2]);
|
if let Some(decl_name_span) = spans.get(2) {
|
||||||
let decl_name = trim_quotes(decl_name);
|
let decl_name = working_set.get_span_contents(*decl_name_span);
|
||||||
|
let decl_name = trim_quotes(decl_name);
|
||||||
|
|
||||||
if let Some(decl_id) = working_set.find_decl(decl_name, &Type::Any) {
|
if let Some(decl_id) = working_set.find_decl(decl_name, &Type::Any) {
|
||||||
result.push(Exportable::Decl {
|
result.push(Exportable::Decl {
|
||||||
name: decl_name.to_vec(),
|
name: decl_name.to_vec(),
|
||||||
id: decl_id,
|
id: decl_id,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
error = error.or_else(|| {
|
error = error.or_else(|| {
|
||||||
Some(ParseError::InternalError(
|
Some(ParseError::InternalError(
|
||||||
"failed to find added declaration".into(),
|
"failed to find added declaration".into(),
|
||||||
span(&spans[1..]),
|
span(&spans[1..]),
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
@ -2032,7 +2034,13 @@ pub fn parse_overlay_new(
|
|||||||
|
|
||||||
let module_id = working_set.add_module(&overlay_name, Module::new());
|
let module_id = working_set.add_module(&overlay_name, Module::new());
|
||||||
|
|
||||||
working_set.add_overlay(overlay_name.as_bytes().to_vec(), module_id, vec![], vec![]);
|
working_set.add_overlay(
|
||||||
|
overlay_name.as_bytes().to_vec(),
|
||||||
|
module_id,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
(pipeline, None)
|
(pipeline, None)
|
||||||
}
|
}
|
||||||
@ -2118,6 +2126,8 @@ pub fn parse_overlay_add(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let has_prefix = call.has_flag("prefix");
|
||||||
|
|
||||||
let pipeline = Pipeline::from_vec(vec![Expression {
|
let pipeline = Pipeline::from_vec(vec![Expression {
|
||||||
expr: Expr::Call(call),
|
expr: Expr::Call(call),
|
||||||
span: span(spans),
|
span: span(spans),
|
||||||
@ -2125,15 +2135,36 @@ pub fn parse_overlay_add(
|
|||||||
custom_completion: None,
|
custom_completion: None,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
// TODO: Add support for it -- needs to play well with overlay remove
|
|
||||||
let has_prefix = false; //call.has_flag("prefix");
|
|
||||||
|
|
||||||
let cwd = working_set.get_cwd();
|
let cwd = working_set.get_cwd();
|
||||||
|
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
|
|
||||||
let result = if let Some(module_id) = working_set.find_overlay_origin(overlay_name.as_bytes()) {
|
let result = if let Some(overlay_frame) = working_set.find_overlay(overlay_name.as_bytes()) {
|
||||||
|
if has_prefix && !overlay_frame.prefixed {
|
||||||
|
return (
|
||||||
|
pipeline,
|
||||||
|
Some(ParseError::OverlayPrefixMismatch(
|
||||||
|
overlay_name,
|
||||||
|
"without".to_string(),
|
||||||
|
overlay_name_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !has_prefix && overlay_frame.prefixed {
|
||||||
|
return (
|
||||||
|
pipeline,
|
||||||
|
Some(ParseError::OverlayPrefixMismatch(
|
||||||
|
overlay_name,
|
||||||
|
"with".to_string(),
|
||||||
|
overlay_name_span,
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Activate existing overlay
|
// Activate existing overlay
|
||||||
|
let module_id = overlay_frame.origin;
|
||||||
|
|
||||||
if let Some(new_module_id) = working_set.find_module(overlay_name.as_bytes()) {
|
if let Some(new_module_id) = working_set.find_module(overlay_name.as_bytes()) {
|
||||||
if module_id == new_module_id {
|
if module_id == new_module_id {
|
||||||
Some((overlay_name, Module::new(), module_id))
|
Some((overlay_name, Module::new(), module_id))
|
||||||
@ -2237,6 +2268,7 @@ pub fn parse_overlay_add(
|
|||||||
module_id,
|
module_id,
|
||||||
decls_to_lay,
|
decls_to_lay,
|
||||||
aliases_to_lay,
|
aliases_to_lay,
|
||||||
|
has_prefix,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,11 @@ impl EngineState {
|
|||||||
blocks: vec![],
|
blocks: vec![],
|
||||||
modules: vec![Module::new()],
|
modules: vec![Module::new()],
|
||||||
// make sure we have some default overlay:
|
// make sure we have some default overlay:
|
||||||
scope: ScopeFrame::with_empty_overlay(DEFAULT_OVERLAY_NAME.as_bytes().to_vec(), 0),
|
scope: ScopeFrame::with_empty_overlay(
|
||||||
|
DEFAULT_OVERLAY_NAME.as_bytes().to_vec(),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
),
|
||||||
ctrlc: None,
|
ctrlc: None,
|
||||||
env_vars: EnvVars::from([(DEFAULT_OVERLAY_NAME.to_string(), HashMap::new())]),
|
env_vars: EnvVars::from([(DEFAULT_OVERLAY_NAME.to_string(), HashMap::new())]),
|
||||||
previous_env_vars: HashMap::new(),
|
previous_env_vars: HashMap::new(),
|
||||||
@ -832,9 +836,11 @@ pub struct StateDelta {
|
|||||||
|
|
||||||
impl StateDelta {
|
impl StateDelta {
|
||||||
pub fn new(engine_state: &EngineState) -> Self {
|
pub fn new(engine_state: &EngineState) -> Self {
|
||||||
|
let last_overlay = engine_state.last_overlay(&[]);
|
||||||
let scope_frame = ScopeFrame::with_empty_overlay(
|
let scope_frame = ScopeFrame::with_empty_overlay(
|
||||||
engine_state.last_overlay_name(&[]).to_owned(),
|
engine_state.last_overlay_name(&[]).to_owned(),
|
||||||
engine_state.last_overlay(&[]).origin,
|
last_overlay.origin,
|
||||||
|
last_overlay.prefixed,
|
||||||
);
|
);
|
||||||
|
|
||||||
StateDelta {
|
StateDelta {
|
||||||
@ -1726,16 +1732,16 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
self.permanent_state.has_overlay(name)
|
self.permanent_state.has_overlay(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_overlay_origin(&self, name: &[u8]) -> Option<ModuleId> {
|
pub fn find_overlay(&self, name: &[u8]) -> Option<&OverlayFrame> {
|
||||||
for scope_frame in self.delta.scope.iter().rev() {
|
for scope_frame in self.delta.scope.iter().rev() {
|
||||||
if let Some(overlay_id) = scope_frame.find_overlay(name) {
|
if let Some(overlay_id) = scope_frame.find_overlay(name) {
|
||||||
return Some(scope_frame.get_overlay(overlay_id).origin);
|
return Some(scope_frame.get_overlay(overlay_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.permanent_state
|
self.permanent_state
|
||||||
.find_overlay(name)
|
.find_overlay(name)
|
||||||
.map(|id| self.permanent_state.get_overlay(id).origin)
|
.map(|id| self.permanent_state.get_overlay(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_overlay_name(&self) -> &Vec<u8> {
|
pub fn last_overlay_name(&self) -> &Vec<u8> {
|
||||||
@ -1775,9 +1781,11 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
pub fn last_overlay_mut(&mut self) -> &mut OverlayFrame {
|
pub fn last_overlay_mut(&mut self) -> &mut OverlayFrame {
|
||||||
if self.delta.last_overlay_mut().is_none() {
|
if self.delta.last_overlay_mut().is_none() {
|
||||||
// If there is no overlay, automatically activate the last one
|
// If there is no overlay, automatically activate the last one
|
||||||
|
let overlay_frame = self.last_overlay();
|
||||||
let name = self.last_overlay_name().to_vec();
|
let name = self.last_overlay_name().to_vec();
|
||||||
let origin = self.last_overlay().origin;
|
let origin = overlay_frame.origin;
|
||||||
self.add_overlay(name, origin, vec![], vec![]);
|
let prefixed = overlay_frame.prefixed;
|
||||||
|
self.add_overlay(name, origin, vec![], vec![], prefixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.delta
|
self.delta
|
||||||
@ -1841,6 +1849,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
origin: ModuleId,
|
origin: ModuleId,
|
||||||
decls: Vec<(Vec<u8>, DeclId)>,
|
decls: Vec<(Vec<u8>, DeclId)>,
|
||||||
aliases: Vec<(Vec<u8>, AliasId)>,
|
aliases: Vec<(Vec<u8>, AliasId)>,
|
||||||
|
prefixed: bool,
|
||||||
) {
|
) {
|
||||||
let last_scope_frame = self.delta.last_scope_frame_mut();
|
let last_scope_frame = self.delta.last_scope_frame_mut();
|
||||||
|
|
||||||
@ -1855,7 +1864,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
} else {
|
} else {
|
||||||
last_scope_frame
|
last_scope_frame
|
||||||
.overlays
|
.overlays
|
||||||
.push((name, OverlayFrame::from_origin(origin)));
|
.push((name, OverlayFrame::from_origin(origin, prefixed)));
|
||||||
last_scope_frame.overlays.len() - 1
|
last_scope_frame.overlays.len() - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1873,7 +1882,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
pub fn remove_overlay(&mut self, name: &[u8], keep_custom: bool) {
|
pub fn remove_overlay(&mut self, name: &[u8], keep_custom: bool) {
|
||||||
let last_scope_frame = self.delta.last_scope_frame_mut();
|
let last_scope_frame = self.delta.last_scope_frame_mut();
|
||||||
|
|
||||||
let removed_overlay_origin = if let Some(overlay_id) = last_scope_frame.find_overlay(name) {
|
let maybe_module_id = if let Some(overlay_id) = last_scope_frame.find_overlay(name) {
|
||||||
last_scope_frame
|
last_scope_frame
|
||||||
.active_overlays
|
.active_overlays
|
||||||
.retain(|id| id != &overlay_id);
|
.retain(|id| id != &overlay_id);
|
||||||
@ -1885,7 +1894,7 @@ impl<'a> StateWorkingSet<'a> {
|
|||||||
.map(|id| self.permanent_state.get_overlay(id).origin)
|
.map(|id| self.permanent_state.get_overlay(id).origin)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(module_id) = removed_overlay_origin {
|
if let Some(module_id) = maybe_module_id {
|
||||||
last_scope_frame.removed_overlays.push(name.to_owned());
|
last_scope_frame.removed_overlays.push(name.to_owned());
|
||||||
|
|
||||||
if keep_custom {
|
if keep_custom {
|
||||||
|
@ -100,9 +100,9 @@ impl ScopeFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_empty_overlay(name: Vec<u8>, origin: ModuleId) -> Self {
|
pub fn with_empty_overlay(name: Vec<u8>, origin: ModuleId, prefixed: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
overlays: vec![(name, OverlayFrame::from_origin(origin))],
|
overlays: vec![(name, OverlayFrame::from_origin(origin, prefixed))],
|
||||||
active_overlays: vec![0],
|
active_overlays: vec![0],
|
||||||
removed_overlays: vec![],
|
removed_overlays: vec![],
|
||||||
predecls: HashMap::new(),
|
predecls: HashMap::new(),
|
||||||
@ -205,10 +205,11 @@ pub struct OverlayFrame {
|
|||||||
pub modules: HashMap<Vec<u8>, ModuleId>,
|
pub modules: HashMap<Vec<u8>, ModuleId>,
|
||||||
pub visibility: Visibility,
|
pub visibility: Visibility,
|
||||||
pub origin: ModuleId, // The original module the overlay was created from
|
pub origin: ModuleId, // The original module the overlay was created from
|
||||||
|
pub prefixed: bool, // Whether the overlay has definitions prefixed with its name
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayFrame {
|
impl OverlayFrame {
|
||||||
pub fn from_origin(origin: ModuleId) -> Self {
|
pub fn from_origin(origin: ModuleId, prefixed: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
predecls: HashMap::new(),
|
predecls: HashMap::new(),
|
||||||
@ -217,6 +218,7 @@ impl OverlayFrame {
|
|||||||
modules: HashMap::new(),
|
modules: HashMap::new(),
|
||||||
visibility: Visibility::new(),
|
visibility: Visibility::new(),
|
||||||
origin,
|
origin,
|
||||||
|
prefixed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,102 @@ fn add_overlay() {
|
|||||||
assert_eq!(actual_repl.out, "foo");
|
assert_eq!(actual_repl.out, "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_overlay_twice() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add spam"#,
|
||||||
|
r#"overlay add spam"#,
|
||||||
|
r#"foo"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "foo");
|
||||||
|
assert_eq!(actual_repl.out, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_prefixed_overlay() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"spam foo"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "foo");
|
||||||
|
assert_eq!(actual_repl.out, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_prefixed_overlay_twice() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"spam foo"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "foo");
|
||||||
|
assert_eq!(actual_repl.out, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_prefixed_overlay_mismatch_1() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"overlay add spam"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert!(actual.err.contains("exists with a prefix"));
|
||||||
|
// Why doesn't the REPL test work with the previous expected output
|
||||||
|
assert!(actual_repl.err.contains("overlay_prefix_mismatch"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_prefixed_overlay_mismatch_2() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add spam"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert!(actual.err.contains("exists without a prefix"));
|
||||||
|
// Why doesn't the REPL test work with the previous expected output
|
||||||
|
assert!(actual_repl.err.contains("overlay_prefix_mismatch"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prefixed_overlay_keeps_custom_decl() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export def foo [] { "foo" } }"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"def bar [] { "bar" }"#,
|
||||||
|
r#"overlay remove --keep-custom spam"#,
|
||||||
|
r#"bar"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "bar");
|
||||||
|
assert_eq!(actual_repl.out, "bar");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_overlay_env() {
|
fn add_overlay_env() {
|
||||||
let inp = &[
|
let inp = &[
|
||||||
@ -30,6 +126,21 @@ fn add_overlay_env() {
|
|||||||
assert_eq!(actual_repl.out, "foo");
|
assert_eq!(actual_repl.out, "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_prefixed_overlay_env_no_prefix() {
|
||||||
|
let inp = &[
|
||||||
|
r#"module spam { export env FOO { "foo" } }"#,
|
||||||
|
r#"overlay add --prefix spam"#,
|
||||||
|
r#"$env.FOO"#,
|
||||||
|
];
|
||||||
|
|
||||||
|
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||||
|
let actual_repl = nu!(cwd: "tests/overlays", nu_repl_code(inp));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "foo");
|
||||||
|
assert_eq!(actual_repl.out, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_overlay_from_file_decl() {
|
fn add_overlay_from_file_decl() {
|
||||||
let inp = &[r#"overlay add samples/spam.nu"#, r#"foo"#];
|
let inp = &[r#"overlay add samples/spam.nu"#, r#"foo"#];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user