coliru

A minimal, flexible, dotfile installer
git clone https://git.ashermorgan.net/coliru/
Log | Files | Refs | README

commit 5f07237d80cfb5b7a4b50f25511fbfc44d55a05e
parent 797d920cd235019fd113add16c0c39d74f928cd9
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Tue,  2 Jul 2024 11:48:36 -0700

Implement remote copying and update tests

The copy_manifest function now performs string replacements in manifest.yml for
Windows and SSH e2e tests. Also, ssh::send_staged_files now deletes staging
directories after use.

Diffstat:
MCargo.lock | 48++++++++++++++++++++++++++++++++++++++++++++++++
MCargo.toml | 1+
Dexamples/manifest-windows-test.yml | 27---------------------------
Msrc/core.rs | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/ssh.rs | 47+++++++++++++++++++++++------------------------
Mtests/basic.rs | 2+-
Mtests/common/mod.rs | 12+++++++++---
Mtests/local.rs | 61++++++++++++++++++++++++++++++-------------------------------
Mtests/ssh.rs | 241++++++++++++++++++++++++++++++++++---------------------------------------------
9 files changed, 276 insertions(+), 251 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -111,6 +111,7 @@ dependencies = [ "serde", "serde_yaml", "shellexpand", + "tempfile", ] [[package]] @@ -147,6 +148,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] name = "getrandom" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -208,6 +225,12 @@ dependencies = [ ] [[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -243,6 +266,19 @@ dependencies = [ ] [[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -308,6 +344,18 @@ dependencies = [ ] [[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] name = "thiserror" version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -8,3 +8,4 @@ clap = { version = "4.5.7", features = ["derive"] } shellexpand = "3.0" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" +tempfile = "3" diff --git a/examples/manifest-windows-test.yml b/examples/manifest-windows-test.yml @@ -1,27 +0,0 @@ -# Identical to manifest.yml, but uses relative paths instead of paths with -# tildes becuase $HOME is difficult to mock on windows. - -steps: - - copy: - - src: gitconfig - dst: .gitconfig.coliru - tags: [ windows, linux, macos ] - - - link: - - src: bashrc - dst: .bashrc.coliru - - src: vimrc - dst: .vimrc.coliru # Will create symbolic links on Linux & MacOS - run: - - src: script.sh - prefix: sh # unecessary on Unix if script.sh is executable - postfix: arg1 $COLIRU_RULES - tags: [ linux, macos ] - - - link: - - src: vimrc - dst: _vimrc.coliru # Will create hard link on Windows - run: - - src: script.bat - postfix: arg1 $COLIRU_RULES - tags: [ windows ] diff --git a/src/core.rs b/src/core.rs @@ -1,23 +1,29 @@ use std::env::set_current_dir; use std::path::Path; -use super::manifest::{CopyLinkOptions, RunOptions, Manifest, parse_manifest_file -}; +use super::manifest::{CopyLinkOptions, RunOptions, parse_manifest_file}; use super::tags::tags_match; use super::local::{copy_file, link_file, run_script}; +use super::ssh::{send_staged_files, stage_file}; +use tempfile::tempdir; /// Execute the steps in a coliru manifest file according to a set of tag rules pub fn execute_manifest_file(path: &Path, tag_rules: Vec<String>, host: &str, dry_run: bool, copy: bool) { - match parse_manifest_file(path) { - Ok(manifest) => execute_manifest(manifest, tag_rules, host, dry_run, - copy), - Err(why) => eprintln!("Error: {}", why), - }; -} -/// Execute the steps in a coliru manifest according to a set of tag rules -fn execute_manifest(manifest: Manifest, tag_rules: Vec<String>, host: &str, - dry_run: bool, copy: bool) { + let _manifest = parse_manifest_file(path); + if let Err(why) = _manifest { + eprintln!("Error: {}", why); + return; + } + let manifest = _manifest.unwrap(); + + let _temp_dir = tempdir(); + if let Err(why) = _temp_dir { + eprintln!("Error: {}", why); + return; + } + let temp_dir = _temp_dir.unwrap(); + if let Err(why) = set_current_dir(manifest.base_dir) { eprintln!("Error: {}", why); return; @@ -28,25 +34,47 @@ fn execute_manifest(manifest: Manifest, tag_rules: Vec<String>, host: &str, let step_str = format!("[{}/{}]", i+1, manifest.steps.len()); - execute_copies(&step.copy, host, dry_run, &step_str); - if copy || host != "" { - execute_copies(&step.link, host, dry_run, &step_str); + if host == "" { + execute_copies(&step.copy, dry_run, &step_str); } else { + execute_copies_remote(&step.copy, host, temp_dir.path(), dry_run, + &step_str); + } + if !copy && host == "" { execute_links(&step.link, dry_run, &step_str); + } else if host != "" { + execute_copies_remote(&step.link, host, temp_dir.path(), dry_run, + &step_str); + } else { + execute_copies(&step.link, dry_run, &step_str); } execute_runs(&step.run, &tag_rules, host, dry_run, &step_str); } } -/// Execute the copy commands specified in a coliru manifest step -fn execute_copies(copies: &[CopyLinkOptions], host: &str, dry_run: bool, - step_str: &str) { +/// Execute a set of copy commands on the local machine +fn execute_copies(copies: &[CopyLinkOptions], dry_run: bool, step_str: &str) { for copy in copies { - if host == "" { - print!("{} Copy {} to {}", step_str, copy.src, copy.dst); - } else { - print!("{} Send {} to {}:{}", step_str, copy.src, host, copy.dst); + print!("{} Copy {} to {}", step_str, copy.src, copy.dst); + + if dry_run { + println!(" (DRY RUN)"); + continue; } + println!(""); + + if let Err(why) = copy_file(&copy.src, &copy.dst) { + eprintln!(" Error: {}", why); + } + } +} + +/// Execute a set of copy commands on a remote machine +fn execute_copies_remote(copies: &[CopyLinkOptions], host: &str, + staging_dir: &Path, dry_run: bool, step_str: &str) { + + for copy in copies { + print!("{} Copy {} to {}:{}", step_str, copy.src, host, copy.dst); if dry_run { println!(" (DRY RUN)"); @@ -54,17 +82,19 @@ fn execute_copies(copies: &[CopyLinkOptions], host: &str, dry_run: bool, } println!(""); - if host == "" { - if let Err(why) = copy_file(&copy.src, &copy.dst) { - eprintln!(" Error: {}", why); - } - } else { - eprintln!(" Error: not implemented"); + if let Err(why) = stage_file(&copy.src, &copy.dst, staging_dir) { + eprintln!(" Error: {}", why); + } + } + + if !dry_run { + if let Err(why) = send_staged_files(staging_dir, host) { + eprintln!(" Error: {}", why); } } } -/// Execute the link commands specified in a coliru manifest step +/// Execute a set of link commands on the local machine fn execute_links(links: &[CopyLinkOptions], dry_run: bool, step_str: &str) { for link in links { print!("{} Link {} to {}", step_str, link.src, link.dst); @@ -81,7 +111,7 @@ fn execute_links(links: &[CopyLinkOptions], dry_run: bool, step_str: &str) { } } -/// Execute the run commands specified in a coliru manifest step +/// Execute a set of run commands on the local machine fn execute_runs(runs: &[RunOptions], tag_rules: &[String], host: &str, dry_run: bool, step_str: &str) { diff --git a/src/ssh.rs b/src/ssh.rs @@ -1,6 +1,6 @@ use shellexpand::tilde_with_context; -use std::fs::read_dir; -use std::path::{MAIN_SEPARATOR_STR, PathBuf}; +use std::fs::{read_dir, remove_dir_all}; +use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf}; use std::process::Command; use super::local::copy_file; @@ -8,13 +8,11 @@ use super::local::copy_file; /// /// The destination directory structure will be recreated in the staging /// directory under either the home or root subdirectories. This staging system -/// allows for many files to transferred at once and for missing directories to -/// be created automatically on the remote machine. -#[allow(dead_code)] -fn stage_file(src: &str, dst: &str, staging_dir: &str) -> Result<(), String> { - let _staging_dir = PathBuf::from(staging_dir); - let home_dir = _staging_dir.join("home"); - let root_dir = _staging_dir.join("root"); +/// allows missing directories to be created automatically on the remote +/// machine. +pub fn stage_file(src: &str, dst: &str, staging_dir: &Path) -> Result<(), String> { + let home_dir = staging_dir.join("home"); + let root_dir = staging_dir.join("root"); let get_home_dir = || { Some::<String>(home_dir.to_string_lossy().into()) }; @@ -44,16 +42,16 @@ fn stage_file(src: &str, dst: &str, staging_dir: &str) -> Result<(), String> { } /// Transfer the files in an SCP staging directory to a remote machine -#[allow(dead_code)] -fn send_staged_files(staging_dir: &str, host: &str) -> Result<(), String> { - let _staging_dir = PathBuf::from(staging_dir); - let home_dir = _staging_dir.join("home"); +pub fn send_staged_files(staging_dir: &Path, host: &str) -> Result<(), String> { + let home_dir = staging_dir.join("home"); if home_dir.exists() { send_dir(home_dir.to_string_lossy().to_mut(), "~", host)?; + remove_dir_all(home_dir).map_err(|why| why.to_string())?; } - let root_dir = _staging_dir.join("root"); + let root_dir = staging_dir.join("root"); if root_dir.exists() { send_dir(root_dir.to_string_lossy().to_mut(), "/", host)?; + remove_dir_all(root_dir).map_err(|why| why.to_string())?; } Ok(()) } @@ -68,7 +66,7 @@ fn send_dir(src: &str, dst: &str, host: &str) -> Result<(), String> { let _src = item.map_err(|why| why.to_string())?.path(); let mut cmd = Command::new("scp"); - if cfg!(test) { + if host == "test@localhost" { // SSH options and port for test server hard coded for now cmd.args(["-o", "StrictHostKeyChecking=no", "-P", "2222"]); } @@ -101,8 +99,7 @@ mod tests { let staging = &tmp.local; write_file(&src, "contents of foo"); - let result = stage_file(src.to_str().unwrap(), dst, - staging.to_str().unwrap()); + let result = stage_file(src.to_str().unwrap(), dst, staging); assert_eq!(result, Ok(())); assert_eq!(dst_real.exists(), true); @@ -119,8 +116,7 @@ mod tests { let staging = &tmp.local; write_file(&src, "contents of foo"); - let result = stage_file(src.to_str().unwrap(), dst, - staging.to_str().unwrap()); + let result = stage_file(src.to_str().unwrap(), dst, staging); assert_eq!(result, Ok(())); assert_eq!(dst_real.exists(), true); @@ -137,8 +133,7 @@ mod tests { let staging = &tmp.local; write_file(&src, "contents of foo"); - let result = stage_file(src.to_str().unwrap(), dst, - staging.to_str().unwrap()); + let result = stage_file(src.to_str().unwrap(), dst, staging); assert_eq!(result, Ok(())); assert_eq!(dst_real.exists(), true); @@ -150,7 +145,7 @@ mod tests { fn test_send_staged_files_no_files() { let tmp = setup_integration("test_send_staged_files_no_files"); - let result = send_staged_files(tmp.local.to_str().unwrap(), SSH_HOST); + let result = send_staged_files(&tmp.local, SSH_HOST); assert_eq!(result, Ok(())); } @@ -167,7 +162,7 @@ mod tests { write_file(&src_foo, "contents of foo"); write_file(&src_bar, "contents of bar"); - let result = send_staged_files(tmp.local.to_str().unwrap(), SSH_HOST); + let result = send_staged_files(&tmp.local, SSH_HOST); let dst_foo = tmp.ssh.join("foo"); let dst_bar = tmp.ssh.join("dir").join("bar"); @@ -176,6 +171,8 @@ mod tests { assert_eq!(read_file(&dst_foo), "contents of foo"); assert_eq!(dst_bar.exists(), true); assert_eq!(read_file(&dst_bar), "contents of bar"); + assert_eq!(tmp.local.join("home").exists(), false); + assert_eq!(tmp.local.join("root").exists(), false); } #[test] @@ -191,7 +188,7 @@ mod tests { write_file(&src_foo, "contents of foo"); write_file(&src_bar, "contents of bar"); - let result = send_staged_files(tmp.local.to_str().unwrap(), SSH_HOST); + let result = send_staged_files(&tmp.local, SSH_HOST); let dst_foo = tmp.ssh.join("foo"); let dst_bar = tmp.ssh.join("dir").join("bar"); @@ -200,6 +197,8 @@ mod tests { assert_eq!(read_file(&dst_foo), "contents of foo"); assert_eq!(dst_bar.exists(), true); assert_eq!(read_file(&dst_bar), "contents of bar"); + assert_eq!(tmp.local.join("home").exists(), false); + assert_eq!(tmp.local.join("root").exists(), false); } #[test] diff --git a/tests/basic.rs b/tests/basic.rs @@ -69,7 +69,7 @@ fn test_basic_absolute_manifest() { let (dirs, mut cmd) = setup_e2e("test_basic_absolute_manifest"); let manifest_path = dirs.local.join("manifest.yml"); cmd.args([&manifest_path.to_str().unwrap(), "--dry-run", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [1/3] Copy gitconfig to ~/.gitconfig.coliru (DRY RUN) diff --git a/tests/common/mod.rs b/tests/common/mod.rs @@ -89,7 +89,10 @@ pub fn setup_e2e_ssh(name: &str) -> (TempDir, Command) { } /// Create a basic manifest file and its associated dotfiles in a directory -pub fn copy_manifest(dir: &Path) { +/// +/// All occurances of the string "~/" in examples/manifest.yml will be replaced +/// with the value of home_dir. +pub fn copy_manifest(dir: &Path, home_dir: &str) { // Copy files from examples let examples = env::current_exe().unwrap().parent().unwrap().to_path_buf() .join("../../../examples"); @@ -98,8 +101,11 @@ pub fn copy_manifest(dir: &Path) { }; copy_file("script.bat"); copy_file("script.sh"); - copy_file("manifest.yml"); - copy_file("manifest-windows-test.yml"); + + // Create manifest file with "~/" replaced for home_dir + let mut manifest = read_file(&examples.join("manifest.yml")); + manifest = manifest.replace("~/", home_dir); + write_file(&dir.join("manifest.yml"), &manifest); // Create simplified config files write_file(&dir.join("bashrc"), "bash #1"); diff --git a/tests/local.rs b/tests/local.rs @@ -11,7 +11,7 @@ use std::fs::remove_file; fn test_local_standard() { let (dirs, mut cmd) = setup_e2e("test_local_standard"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [1/3] Copy gitconfig to ~/.gitconfig.coliru @@ -20,8 +20,8 @@ fn test_local_standard() { [2/3] Run sh script.sh arg1 linux script.sh called with arg1 linux "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -43,8 +43,8 @@ script.sh called with arg1 linux #[cfg(target_family = "windows")] fn test_local_standard() { let (dirs, mut cmd) = setup_e2e("test_local_standard"); - cmd.args(["manifest-windows-test.yml", "-t", "windows"]); - copy_manifest(&dirs.local); + cmd.args(["manifest.yml", "-t", "windows"]); + copy_manifest(&dirs.local, ""); let expected = "\ [1/3] Copy gitconfig to .gitconfig.coliru @@ -52,8 +52,8 @@ fn test_local_standard() { [3/3] Run script.bat arg1 windows script.bat called with arg1 windows\r "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("gitconfig"), "git #2"); @@ -75,7 +75,7 @@ script.bat called with arg1 windows\r fn test_local_run_alternate_tag_rules_1() { let (dirs, mut cmd) = setup_e2e("test_local_run_alternate_tag_rules_1"); cmd.args(["manifest.yml", "-t", "linux", "^windows"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [2/3] Link bashrc to ~/.bashrc.coliru @@ -83,8 +83,8 @@ fn test_local_run_alternate_tag_rules_1() { [2/3] Run sh script.sh arg1 linux ^windows script.sh called with arg1 linux ^windows "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -106,7 +106,7 @@ script.sh called with arg1 linux ^windows fn test_local_run_alternate_tag_rules_2() { let (dirs, mut cmd) = setup_e2e("test_local_run_alternate_tag_rules_2"); cmd.args(["manifest.yml", "-t", "macos"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [1/3] Copy gitconfig to ~/.gitconfig.coliru @@ -115,8 +115,8 @@ fn test_local_run_alternate_tag_rules_2() { [2/3] Run sh script.sh arg1 macos script.sh called with arg1 macos "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -139,7 +139,7 @@ script.sh called with arg1 macos fn test_local_dry_run() { let (dirs, mut cmd) = setup_e2e("test_local_dry_run"); cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [1/3] Copy gitconfig to ~/.gitconfig.coliru (DRY RUN) @@ -147,8 +147,8 @@ fn test_local_dry_run() { [2/3] Link vimrc to ~/.vimrc.coliru (DRY RUN) [2/3] Run sh script.sh arg1 linux (DRY RUN) "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run let bash_exists = dirs.home.join(".bashrc.coliru").exists(); @@ -167,16 +167,16 @@ fn test_local_dry_run() { #[cfg(target_family = "windows")] fn test_local_dry_run() { let (dirs, mut cmd) = setup_e2e("test_local_dry_run"); - cmd.args(["manifest-windows-test.yml", "--dry-run", "-t", "windows"]); - copy_manifest(&dirs.local); + cmd.args(["manifest.yml", "--dry-run", "-t", "windows"]); + copy_manifest(&dirs.local, ""); let expected = "\ [1/3] Copy gitconfig to .gitconfig.coliru (DRY RUN) [3/3] Link vimrc to _vimrc.coliru (DRY RUN) [3/3] Run script.bat arg1 windows (DRY RUN) "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run let bash_exists = dirs.local.join(".bashrc.coliru").exists(); @@ -196,7 +196,7 @@ fn test_local_dry_run() { fn test_local_copy() { let (dirs, mut cmd) = setup_e2e("test_local_copy"); cmd.args(["manifest.yml", "--copy", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); let expected = "\ [1/3] Copy gitconfig to ~/.gitconfig.coliru @@ -205,8 +205,8 @@ fn test_local_copy() { [2/3] Run sh script.sh arg1 linux script.sh called with arg1 linux "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -228,8 +228,8 @@ script.sh called with arg1 linux #[cfg(target_family = "windows")] fn test_local_copy() { let (dirs, mut cmd) = setup_e2e("test_local_copy"); - cmd.args(["manifest-windows-test.yml", "--copy", "-t", "windows"]); - copy_manifest(&dirs.local); + cmd.args(["manifest.yml", "--copy", "-t", "windows"]); + copy_manifest(&dirs.local, ""); let expected = "\ [1/3] Copy gitconfig to .gitconfig.coliru @@ -237,8 +237,8 @@ fn test_local_copy() { [3/3] Run script.bat arg1 windows script.bat called with arg1 windows\r "; - assert_eq!(&stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(&stdout_to_string(&mut cmd), expected); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("gitconfig"), "git #2"); @@ -260,7 +260,7 @@ script.bat called with arg1 windows\r fn test_local_run_failure() { let (dirs, mut cmd) = setup_e2e("test_local_run_failure"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); write_file(&dirs.local.join("script.sh"), "exit 1"); let expected_stdout = "\ @@ -270,8 +270,8 @@ fn test_local_run_failure() { [2/3] Run sh script.sh arg1 linux "; let expected_stderr = " Error: Process exited with exit status: 1\n"; - assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -291,8 +291,8 @@ fn test_local_run_failure() { #[cfg(target_family = "windows")] fn test_local_run_failure() { let (dirs, mut cmd) = setup_e2e("test_local_run_failure"); - cmd.args(["manifest-windows-test.yml", "-t", "windows"]); - copy_manifest(&dirs.local); + cmd.args(["manifest.yml", "-t", "windows"]); + copy_manifest(&dirs.local, ""); write_file(&dirs.local.join("script.bat"), "@echo off\r\nexit 1"); let expected_stdout = "\ @@ -301,8 +301,8 @@ fn test_local_run_failure() { [3/3] Run script.bat arg1 windows "; let expected_stderr = " Error: Process exited with exit code: 1\n"; - assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("gitconfig"), "git #2"); @@ -322,7 +322,7 @@ fn test_local_run_failure() { fn test_local_missing_file() { let (dirs, mut cmd) = setup_e2e("test_local_missing_file"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/"); remove_file(&dirs.local.join("vimrc")).unwrap(); let expected_stdout = "\ @@ -332,10 +332,9 @@ fn test_local_missing_file() { [2/3] Run sh script.sh arg1 linux script.sh called with arg1 linux "; - let expected_stderr = " Error: No such file or directory \ - (os error 2)\n"; - assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: No such file or directory (os error 2)\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("bashrc"), "bash #2"); @@ -352,8 +351,8 @@ script.sh called with arg1 linux #[cfg(target_family = "windows")] fn test_local_missing_file() { let (dirs, mut cmd) = setup_e2e("test_local_missing_file"); - cmd.args(["manifest-windows-test.yml", "-t", "windows"]); - copy_manifest(&dirs.local); + cmd.args(["manifest.yml", "-t", "windows"]); + copy_manifest(&dirs.local, ""); remove_file(&dirs.local.join("vimrc")).unwrap(); let expected_stdout = "\ @@ -364,8 +363,8 @@ script.bat called with arg1 windows\r "; let expected_stderr = " Error: The system cannot find the file specified. \ (os error 2)\n"; - assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(&stdout_to_string(&mut cmd), expected_stdout); // Assert files are correctly copied/linked/run write_file(&dirs.local.join("gitconfig"), "git #2"); diff --git a/tests/ssh.rs b/tests/ssh.rs @@ -7,107 +7,91 @@ use common::*; use std::fs::remove_file; #[test] +#[cfg(target_family = "unix")] fn test_ssh_standard() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_standard"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_standard/"); let expected_stdout = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_standard/.gitconfig.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_standard/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_standard/.vimrc.coliru [2/3] Run sh script.sh arg1 linux on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented - Error: not implemented -"; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: not implemented\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("gitconfig"), "git #2"); - // write_file(&dirs.local.join("vimrc"), "vim #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); - // let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); + let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); // let log_contents = read_file(&dirs.local.join("log.txt")); - // assert_eq!(bash_contents, "bash #2"); - // assert_eq!(git_contents, "git #1"); - // assert_eq!(vim1_contents, "vim #2"); - // assert_eq!(vim2_exists, false); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_contents, "git #1"); + assert_eq!(vim1_contents, "vim #1"); + assert_eq!(vim2_exists, false); // assert_eq!(log_contents, "script.sh called with arg1 linux\n"); } #[test] +#[cfg(target_family = "unix")] fn test_ssh_run_alternate_tag_rules_1() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_1"); cmd.args(["manifest.yml", "-t", "linux", "^windows"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_run_alternate_tag_rules_1/"); let expected_stdout = format!("\ -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_1/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_1/.vimrc.coliru [2/3] Run sh script.sh arg1 linux ^windows on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented -"; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: not implemented\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("vimrc"), "vim #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_exists = dirs.ssh.join(".gitconfig.coliru").exists(); - // let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_exists = dirs.ssh.join(".gitconfig.coliru").exists(); + let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); // let log_contents = read_file(&dirs.local.join("log.txt")); - // assert_eq!(bash_contents, "bash #2"); - // assert_eq!(git_exists, false); - // assert_eq!(vim1_contents, "vim #2"); - // assert_eq!(vim2_exists, false); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_exists, false); + assert_eq!(vim1_contents, "vim #1"); + assert_eq!(vim2_exists, false); // assert_eq!(log_contents, "script.sh called with arg1 linux ^windows\n"); } #[test] +#[cfg(target_family = "unix")] fn test_ssh_run_alternate_tag_rules_2() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_2"); cmd.args(["manifest.yml", "-t", "macos"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_run_alternate_tag_rules_2/"); let expected_stdout = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.gitconfig.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.vimrc.coliru [2/3] Run sh script.sh arg1 macos on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented - Error: not implemented -"; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: not implemented\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("gitconfig"), "git #2"); - // write_file(&dirs.local.join("vimrc"), "vim #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); - // let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); + let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); // let log_contents = read_file(&dirs.local.join("log.txt")); - // assert_eq!(bash_contents, "bash #2"); - // assert_eq!(git_contents, "git #1"); - // assert_eq!(vim1_contents, "vim #2"); - // assert_eq!(vim2_exists, false); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_contents, "git #1"); + assert_eq!(vim1_contents, "vim #1"); + assert_eq!(vim2_exists, false); // assert_eq!(log_contents, "script.sh called with arg1 macos\n"); } @@ -115,129 +99,114 @@ fn test_ssh_run_alternate_tag_rules_2() { fn test_ssh_dry_run() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_dry_run"); cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_dry_run/"); let expected = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru (DRY RUN) -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru (DRY RUN) -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru (DRY RUN) +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_dry_run/.gitconfig.coliru (DRY RUN) +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_dry_run/.bashrc.coliru (DRY RUN) +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_dry_run/.vimrc.coliru (DRY RUN) [2/3] Run sh script.sh arg1 linux on {SSH_HOST} (DRY RUN) "); - assert_eq!(stdout_to_string(&mut cmd), expected); assert_eq!(&stderr_to_string(&mut cmd), ""); + assert_eq!(stdout_to_string(&mut cmd), expected); - // Assert files are correctly copied/linked/run - // let bash_exists = dirs.ssh.join(".bashrc.coliru").exists(); - // let git_exists = dirs.ssh.join(".gitconfig.coliru").exists(); - // let vim1_exists = dirs.ssh.join(".vimrc.coliru").exists(); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + // Assert files are correctly copied/run + let bash_exists = dirs.ssh.join(".bashrc.coliru").exists(); + let git_exists = dirs.ssh.join(".gitconfig.coliru").exists(); + let vim1_exists = dirs.ssh.join(".vimrc.coliru").exists(); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); // let log_exists = dirs.local.join("log.txt").exists(); - // assert_eq!(bash_exists, false); - // assert_eq!(git_exists, false); - // assert_eq!(vim1_exists, false); - // assert_eq!(vim2_exists, false); + assert_eq!(bash_exists, false); + assert_eq!(git_exists, false); + assert_eq!(vim1_exists, false); + assert_eq!(vim2_exists, false); // assert_eq!(log_exists, false); } #[test] +#[cfg(target_family = "unix")] fn test_ssh_copy() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_copy"); cmd.args(["manifest.yml", "--copy", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_copy/"); let expected_stdout = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_copy/.gitconfig.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_copy/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_copy/.vimrc.coliru [2/3] Run sh script.sh arg1 linux on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented - Error: not implemented -"; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: not implemented\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("gitconfig"), "git #2"); - // write_file(&dirs.local.join("vimrc"), "vim #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); - // let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); + let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); // let log_contents = read_file(&dirs.local.join("log.txt")); - // assert_eq!(bash_contents, "bash #1"); - // assert_eq!(git_contents, "git #1"); - // assert_eq!(vim1_contents, "vim #1"); - // assert_eq!(vim2_exists, false); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_contents, "git #1"); + assert_eq!(vim1_contents, "vim #1"); + assert_eq!(vim2_exists, false); // assert_eq!(log_contents, "script.sh called with arg1 linux\n"); } #[test] +#[cfg(target_family = "unix")] fn test_ssh_run_failure() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_failure"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_run_failure/"); write_file(&dirs.local.join("script.sh"), "exit 1"); let expected_stdout = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_run_failure/.gitconfig.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_run_failure/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_run_failure/.vimrc.coliru [2/3] Run sh script.sh arg1 linux on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented - Error: not implemented -"; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); + let expected_stderr = " Error: not implemented\n"; assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("gitconfig"), "git #2"); - // write_file(&dirs.local.join("vimrc"), "vim #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); - // let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); - // let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); - // assert_eq!(bash_contents, "bash #2"); - // assert_eq!(git_contents, "git #1"); - // assert_eq!(vim1_contents, "vim #2"); - // assert_eq!(vim2_exists, false); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); + let vim1_contents = read_file(&dirs.ssh.join(".vimrc.coliru")); + let vim2_exists = dirs.ssh.join("_vimrc.coliru").exists(); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_contents, "git #1"); + assert_eq!(vim1_contents, "vim #1"); + assert_eq!(vim2_exists, false); } #[test] +#[cfg(target_family = "unix")] fn test_ssh_missing_file() { let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_missing_file"); cmd.args(["manifest.yml", "-t", "linux"]); - copy_manifest(&dirs.local); + copy_manifest(&dirs.local, "~/test_ssh_missing_file/"); remove_file(&dirs.local.join("vimrc")).unwrap(); let expected_stdout = format!("\ -[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru -[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru -[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru +[1/3] Copy gitconfig to {SSH_HOST}:~/test_ssh_missing_file/.gitconfig.coliru +[2/3] Copy bashrc to {SSH_HOST}:~/test_ssh_missing_file/.bashrc.coliru +[2/3] Copy vimrc to {SSH_HOST}:~/test_ssh_missing_file/.vimrc.coliru [2/3] Run sh script.sh arg1 linux on {SSH_HOST} "); - let expected_stderr = " Error: not implemented - Error: not implemented - Error: not implemented + let expected_stderr = " Error: No such file or directory (os error 2) Error: not implemented "; - assert_eq!(stdout_to_string(&mut cmd), expected_stdout); assert_eq!(&stderr_to_string(&mut cmd), expected_stderr); + assert_eq!(stdout_to_string(&mut cmd), expected_stdout); - // Assert files are correctly copied/linked/run - // write_file(&dirs.local.join("bashrc"), "bash #2"); - // write_file(&dirs.local.join("gitconfig"), "git #2"); - // let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); - // let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); + // Assert files are correctly copied/run + let bash_contents = read_file(&dirs.ssh.join(".bashrc.coliru")); + let git_contents = read_file(&dirs.ssh.join(".gitconfig.coliru")); // let log_contents = read_file(&dirs.ssh.join("log.txt")); - // assert_eq!(bash_contents, "bash #2"); - // assert_eq!(git_contents, "git #1"); + assert_eq!(bash_contents, "bash #1"); + assert_eq!(git_contents, "git #1"); // assert_eq!(log_contents, "script.sh called with arg1 linux\n"); }