Run exitscripts in original dir (#2352)

* Modify testcase

* Run exitscript in the folder it was specified

* Update documentation

* Add comment

* Borrow instead of clone

* Does this just... work on windows?

* fmt

* as_str

* Collapse if by order of clippy

* Support windows

* fmt

* refactor tests

* fmt

* This time it will work on windows FOR SURE

* Remove debug prints

* Comment

* Refactor tests

* fmt

* fix spelling

* update comment
This commit is contained in:
Sam Hedin 2020-08-18 07:36:09 +02:00 committed by GitHub
parent f6ff6ab6e4
commit 57101d5022
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 50 deletions

View File

@ -55,7 +55,7 @@ impl WholeStreamCommand for Autoenv {
The file can contain several optional sections: 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. 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. 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. Note that exitscripts are not run in the directory they are declared in."# scripts: scripts to run when entering the directory or leaving it."#
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {

View File

@ -112,7 +112,7 @@ impl DirectorySpecificEnvironment {
if let Some(es) = nu_env_doc.entryscripts { if let Some(es) = nu_env_doc.entryscripts {
for s in es { for s in es {
run(s.as_str())?; run(s.as_str(), None)?;
} }
} }
@ -147,7 +147,7 @@ impl DirectorySpecificEnvironment {
new_exitscripts.insert(dir, scripts); new_exitscripts.insert(dir, scripts);
} else { } else {
for s in scripts { for s in scripts {
run(s.as_str())?; run(s.as_str(), Some(&dir))?;
} }
} }
} }
@ -215,9 +215,23 @@ impl DirectorySpecificEnvironment {
} }
} }
fn run(cmd: &str) -> Result<(), ShellError> { fn run(cmd: &str, dir: Option<&PathBuf>) -> Result<(), ShellError> {
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", cmd]).output()? if let Some(dir) = dir {
let command = format!("cd {} & {}", dir.to_string_lossy(), cmd);
Command::new("cmd")
.args(&["/C", command.as_str()])
.output()?
} else {
Command::new("cmd").args(&["/C", cmd]).output()?
}
} else if let Some(dir) = dir {
// FIXME: When nu scripting is added, cding like might not be a good idea. If nu decides to execute entryscripts when entering the dir this way, it will cause troubles.
// For now only standard shell scripts are used, so this is an issue for the future.
Command::new("sh")
.arg("-c")
.arg(format!("cd {:?}; {}", dir, cmd))
.output()?
} else { } else {
Command::new("sh").arg("-c").arg(&cmd).output()? Command::new("sh").arg("-c").arg(&cmd).output()?
}; };

View File

@ -48,36 +48,31 @@ fn autoenv() {
sandbox.mkdir("bizz/buzz"); sandbox.mkdir("bizz/buzz");
sandbox.mkdir("foob"); sandbox.mkdir("foob");
let scriptfile = if cfg!(target_os = "windows") { // Windows uses a different command to create an empty file so we need to have different content on windows.
FileWithContent( let full_nu_env = if cfg!(target_os = "windows") {
".nu-env", r#"[env]
r#"[env] testkey = "testvalue"
testkey = "testvalue"
[scriptvars] [scriptvars]
myscript = "echo myval" myscript = "echo myval"
[scripts] [scripts]
entryscripts = ["echo nul > hello.txt"] entryscripts = ["echo nul > hello.txt"]
exitscripts = ["echo nul > bye.txt"]"#, exitscripts = ["echo nul > bye.txt"]"#
)
} else { } else {
FileWithContent( r#"[env]
".nu-env", testkey = "testvalue"
r#"[env]
testkey = "testvalue"
[scriptvars] [scriptvars]
myscript = "echo myval" myscript = "echo myval"
[scripts] [scripts]
entryscripts = ["touch hello.txt"] entryscripts = ["touch hello.txt"]
exitscripts = ["touch bye.txt"]"#, exitscripts = ["touch bye.txt"]"#
)
}; };
sandbox.with_files(vec![ sandbox.with_files(vec![
scriptfile, FileWithContent(".nu-env", full_nu_env),
FileWithContent( FileWithContent(
"foo/.nu-env", "foo/.nu-env",
r#"[env] r#"[env]
@ -89,14 +84,28 @@ fn autoenv() {
r#"[env] r#"[env]
overwrite_me = "set_in_bar""#, overwrite_me = "set_in_bar""#,
), ),
FileWithContent( FileWithContent("bizz/.nu-env", full_nu_env),
"bizz/.nu-env",
r#"[scripts]
entryscripts = ["touch hello.txt"]
exitscripts = ["touch bye.txt"]"#,
),
]); ]);
//Make sure basic keys are set
let actual = nu!(
cwd: dirs.test(),
r#"autoenv trust
echo $nu.env.testkey"#
);
assert!(actual.out.ends_with("testvalue"));
// Make sure exitscripts are run in the directory they were specified.
let actual = nu!(
cwd: dirs.test(),
r#"autoenv trust
cd ..
cd autoenv_test
ls
ls | where name == "bye.txt" | get name"#
);
assert!(actual.out.contains("bye.txt"));
// Make sure entry scripts are run // Make sure entry scripts are run
let actual = nu!( let actual = nu!(
cwd: dirs.test(), cwd: dirs.test(),
@ -116,7 +125,7 @@ fn autoenv() {
); );
assert!(!actual.out.contains("bye.txt")); assert!(!actual.out.contains("bye.txt"));
// Make sure entry scripts are run when re-visiting a directory // Make sure entryscripts are run when re-visiting a directory
let actual = nu!( let actual = nu!(
cwd: dirs.test(), cwd: dirs.test(),
r#"autoenv trust bizz r#"autoenv trust bizz
@ -138,14 +147,6 @@ fn autoenv() {
); );
assert!(!actual.out.ends_with("hello.txt")); assert!(!actual.out.ends_with("hello.txt"));
//Make sure basic keys are set
let actual = nu!(
cwd: dirs.test(),
r#"autoenv trust
echo $nu.env.testkey"#
);
assert!(actual.out.ends_with("testvalue"));
//Backing out of the directory should unset the keys //Backing out of the directory should unset the keys
let actual = nu!( let actual = nu!(
cwd: dirs.test(), cwd: dirs.test(),
@ -189,14 +190,6 @@ fn autoenv() {
); );
assert!(actual.out.contains("hello.txt")); assert!(actual.out.contains("hello.txt"));
// Make sure exit scripts are run
let actual = nu!(
cwd: dirs.test(),
r#"cd ..
ls | where name == "bye.txt" | get name"#
);
assert!(actual.out.contains("bye.txt"));
//Variables set in parent directories should be set even if you directly cd to a subdir //Variables set in parent directories should be set even if you directly cd to a subdir
let actual = nu!( let actual = nu!(
cwd: dirs.test(), cwd: dirs.test(),