From e1403da326d5691a6636cb80d99d001196162235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Palom=C3=A4ki?= Date: Tue, 10 Aug 2021 00:55:26 +0300 Subject: [PATCH] New which implementation (#27) --- Cargo.lock | 58 +++++++++++++++++++++++++-------------------------- Cargo.toml | 4 ++-- README.md | 26 ++++++++++++++--------- src/shared.rs | 53 ++++++++++++++++------------------------------ src/utils.rs | 27 +----------------------- tests/main.rs | 10 ++++----- 6 files changed, 71 insertions(+), 107 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce739d2..4b04b55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest", @@ -676,9 +676,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" +checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" dependencies = [ "bytes", "http", @@ -784,18 +784,18 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "jobserver" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd" +checksum = "f5ca711fd837261e14ec9e674f092cbb931d3fa1482b017ae59328ddc6f3212b" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" +checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" dependencies = [ "wasm-bindgen", ] @@ -1209,9 +1209,9 @@ checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" [[package]] name = "predicates-tree" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2" +checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d" dependencies = [ "predicates-core", "treeline", @@ -1318,9 +1318,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ "bitflags", ] @@ -1580,9 +1580,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" [[package]] name = "smallvec" @@ -1667,7 +1667,7 @@ dependencies = [ [[package]] name = "terve" -version = "0.6.0-beta.1" +version = "0.6.0-beta.2" dependencies = [ "assert_cmd", "bytes", @@ -1922,9 +1922,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" dependencies = [ "cfg-if 1.0.0", "serde", @@ -1934,9 +1934,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" dependencies = [ "bumpalo", "lazy_static", @@ -1949,9 +1949,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" +checksum = "16646b21c3add8e13fdb8f20172f8a28c3dbf62f45406bcff0233188226cfe0c" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1961,9 +1961,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1971,9 +1971,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" dependencies = [ "proc-macro2", "quote", @@ -1984,15 +1984,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.74" +version = "0.2.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" +checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" [[package]] name = "web-sys" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" +checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 9a4e2b7..1e93be7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "terve" -version = "0.6.0-beta.1" +version = "0.6.0-beta.2" edition = "2018" [dependencies] @@ -14,7 +14,6 @@ sha2 = "~0.9" hex = "~0.4" pgp = "~0.7" bytes = "~1.0" -same-file = "~1.0" [dependencies.reqwest] version = "~0.11" @@ -28,6 +27,7 @@ features = ["https"] [dev-dependencies] assert_cmd = "~1.0" predicates = "~2.0" +same-file = "~1.0" [profile.release] codegen-units = 1 diff --git a/README.md b/README.md index a85e522..b89735f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Release](https://img.shields.io/github/v/release/superblk/terve) ![License](https://img.shields.io/github/license/superblk/terve) -![OS](https://img.shields.io/badge/os-Linux%20%7C%20MacOS%20%7C%20Windows-ff69b4) +![OS](https://img.shields.io/badge/os-Linux%20%7C%20macOS%20%7C%20Windows-ff69b4) Unified, minimal [terraform](https://www.terraform.io/downloads.html) and [terragrunt](https://github.com/gruntwork-io/terragrunt/releases) version manager. @@ -47,14 +47,20 @@ All files are kept in directory `~/.terve` like so (example directory tree for L │   └── terragrunt ├── etc │   └── terraform.asc -└── opt +├── opt +│   ├── terraform +│   │   ├── 0.1.0 +│   │   ├── 1.0.2 +│   │   └── 1.0.3 +│   └── terragrunt +│   ├── 0.0.4 +│   ├── 0.1.0 +│   └── 0.31.2 +└── var ├── terraform - │   ├── 0.14.11 - │   └── 0.15.4 + │   └── version └── terragrunt - ├── 0.28.10 - ├── 0.28.39 - └── 0.29.4 + └── version ``` ## Usage @@ -92,7 +98,7 @@ WARNING: terragrunt releases < `0.18.1` do not ship `SHA256SUMS` files, so their ### Select -Selects a specific version for use. That version must be installed first. +Selects an installed version for use. Syntax: `terve s[elect] ` @@ -101,7 +107,7 @@ Syntax: `terve s[elect] ` ### Remove -Removes a specific version. If that version is currently selected, the selection will be reset. +Removes an installed version. NOTE: does not reset selection Syntax: `terve r[emove] ` @@ -110,7 +116,7 @@ Syntax: `terve r[emove] ` ### Which -Tells which version is selected. +Tells which version is currently selected. Syntax: `terve w[hich] ` diff --git a/src/shared.rs b/src/shared.rs index f91d286..d87681c 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -1,14 +1,15 @@ use std::{ error::Error, fmt::Display, - fs::{create_dir_all, hard_link, read_dir, remove_file}, + fs::{create_dir_all, hard_link, read_dir, read_to_string, remove_file, write}, path::{Path, PathBuf}, str::FromStr, }; -use crate::utils::{self, is_same_file}; use semver::{Prerelease, Version}; +use crate::utils::{git_list_remote_tags, to_sorted_multiline_string}; + pub enum Action { List, Install, @@ -88,6 +89,7 @@ pub struct DotDir { pub bin: PathBuf, pub etc: PathBuf, pub opt: PathBuf, + pub var: PathBuf, } impl DotDir { @@ -96,27 +98,31 @@ impl DotDir { let bin = root.join("bin"); let etc = root.join("etc"); let opt = root.join("opt"); + let var = root.join("var"); create_dir_all(&bin)?; create_dir_all(&etc)?; create_dir_all(opt.join(Binary::Terraform))?; create_dir_all(opt.join(Binary::Terragrunt))?; + create_dir_all(var.join(Binary::Terraform))?; + create_dir_all(var.join(Binary::Terragrunt))?; Ok(DotDir { root, bin, etc, opt, + var, }) } } pub fn list_available_versions(git_repo_url: &str) -> Result> { - let mut versions: Vec = utils::git_list_remote_tags(git_repo_url)? + let mut versions: Vec = git_list_remote_tags(git_repo_url)? .iter() .map(|t| t.trim_start_matches('v')) .filter_map(|s| Version::parse(s).ok()) .filter(|v| v.pre == Prerelease::EMPTY) .collect(); - let result = utils::to_sorted_multiline_string(&mut versions); + let result = to_sorted_multiline_string(&mut versions); Ok(result) } @@ -127,7 +133,7 @@ pub fn list_installed_versions(binary: Binary, dot_dir: DotDir) -> Result Result> { let opt_file_path = dot_dir.opt.join(&binary).join(&version); if opt_file_path.exists() { - let bin_file_path = dot_dir.bin.join(&binary); - if bin_file_path.exists() && is_same_file(&opt_file_path, &bin_file_path)? { - remove_file(bin_file_path)?; - } remove_file(&opt_file_path)?; } Ok(format!("Removed {} {}", binary, version)) } -// We use hard links, so we need to compare the executable ~/.terve/bin/ -// to all ~/.terve/opt// files (version is encoded in file name) pub fn get_selected_version(binary: Binary, dot_dir: DotDir) -> Result> { let bin_file_path = dot_dir.bin.join(&binary); - let result = if bin_file_path.exists() { - let opt_dir_path = dot_dir.opt.join(&binary); - find_selected_binary_version(bin_file_path, opt_dir_path)? + let version_file_path = dot_dir.var.join(&binary).join("version"); + let result = if bin_file_path.exists() && version_file_path.exists() { + read_to_string(version_file_path)? } else { "".to_string() }; Ok(result) } - -fn find_selected_binary_version( - bin_file_path: PathBuf, - opt_dir_path: PathBuf, -) -> Result> { - let path: Option = read_dir(&opt_dir_path)? - .filter_map(|r| Some(r.ok()?.path())) - .find(|p| is_same_file(&bin_file_path, p).unwrap_or(false)); - if let Some(p) = path { - if let Some(s) = p.file_name() { - return Ok(s.to_string_lossy().to_string()); - } - } - Ok("".to_string()) -} diff --git a/src/utils.rs b/src/utils.rs index ea08bf2..c698c7f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -7,7 +7,6 @@ use std::{ error::Error, fs::File, io::{copy, stderr, stdout, Seek, SeekFrom, Write}, - path::Path, }; pub fn check_sha256_sum(mut file: &File, expected_sha256: &str) -> Result<(), Box> { @@ -112,16 +111,10 @@ const NEWLINE: &str = "\n"; #[cfg(windows)] const NEWLINE: &str = "\r\n"; -pub fn is_same_file(lhs: &Path, rhs: &Path) -> Result> { - // Compare file size first, see https://github.com/BurntSushi/same-file/issues/52 - let file_size_matches = lhs.metadata()?.len() == rhs.metadata()?.len(); - Ok(file_size_matches && same_file::is_same_file(lhs, rhs)?) -} - #[cfg(test)] mod tests { - use std::{fs::read_to_string, path::Path}; + use std::fs::read_to_string; use pgp::Deserializable; @@ -206,22 +199,4 @@ mod tests { let tags = git_list_remote_tags("https://github.com/gruntwork-io/terragrunt").unwrap(); assert!(tags.contains(&"v0.29.7".to_string())); } - - #[test] - fn test_is_same_file_equal() { - assert!(is_same_file( - Path::new("tests/special.txt"), - Path::new("tests/special.txt") - ) - .unwrap()); - } - - #[test] - fn test_is_same_file_not_equal() { - assert!(!is_same_file( - Path::new("tests/special.txt"), - Path::new("tests/hashicorp-72D7468F.asc") - ) - .unwrap()); - } } diff --git a/tests/main.rs b/tests/main.rs index 9ab3a0b..233b98e 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -41,7 +41,7 @@ fn test_terraform_workflow() { .code(1) .stderr(starts_with("ERROR: HTTP status client error")); - // Install a version + // Install some version terve(&home_dir) .arg("i") .arg("tf") @@ -139,14 +139,14 @@ fn test_terraform_workflow() { .stdout(contains("Removed terraform 0.14.11")); } - // Assert no version is now selected + // Assert same version is still selected terve(&home_dir) .arg("w") .arg("tf") .assert() .success() .code(0) - .stdout(is_empty()); + .stdout(contains("0.14.11")); // Remove the other version terve(&home_dir) @@ -312,14 +312,14 @@ fn test_terragrunt_workflow() { .stdout(contains("Removed terragrunt 0.29.2")); } - // Assert no version is now selected + // Assert same version is still selected terve(&home_dir) .arg("w") .arg("tg") .assert() .success() .code(0) - .stdout(is_empty()); + .stdout(contains("0.29.2")); // Remove the other version terve(&home_dir)