From 3db7adeb358458fad9bff8bfbc41dc5fc6a89719 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Thu, 15 Sep 2022 16:08:41 +0200 Subject: [PATCH 1/5] added install command --- src/config/cli.rs | 3 +++ src/config/schema.rs | 18 ++++++++++++++++++ src/lib.rs | 16 +++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/config/cli.rs b/src/config/cli.rs index 85333e2..a5acde7 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -20,4 +20,7 @@ pub enum Command { /// Generate a default .tools.toml file and prints it to std out DefaultConfig, + + /// Install a tool if it is hardcoded into internal database + Install { name: String }, } diff --git a/src/config/schema.rs b/src/config/schema.rs index 6293b34..2bb5b2b 100644 --- a/src/config/schema.rs +++ b/src/config/schema.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use crate::err; use crate::model::asset_name::AssetName; +use crate::model::tool::{ToolInfo, ToolInfoTag}; /// Stores global information about the tool installation process and detailed /// info about installing each particular tool. @@ -39,6 +40,23 @@ pub struct ConfigAsset { pub asset_name: AssetName, } +impl From for ConfigAsset { + fn from(tool_info: ToolInfo) -> Self { + let tag = match tool_info.tag { + ToolInfoTag::Specific(version) => Some(version), + ToolInfoTag::Latest => None, + }; + + Self { + owner: Some(tool_info.owner), + repo: Some(tool_info.repo), + exe_name: Some(tool_info.exe_name), + tag, + asset_name: tool_info.asset_name, + } + } +} + impl Config { /// Shellexpands store directory, check whether it exists and exits with /// error if 'store_directory' doesn't exist diff --git a/src/lib.rs b/src/lib.rs index e0a1134..91b7b62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,16 @@ mod infra; mod model; mod sync; -use clap::Parser; +use std::collections::BTreeMap; use std::path::PathBuf; +use clap::Parser; + use crate::config::cli::{Cli, Command}; +use crate::config::schema::ConfigAsset; use crate::config::template; use crate::config::toml; +use crate::sync::db::lookup_tool; use crate::sync::sync; const DEFAULT_CONFIG_PATH: &str = ".tool.toml"; @@ -32,6 +36,16 @@ pub fn run() { } }, Command::DefaultConfig => generate_config(), + Command::Install { name } => { + if let Some(tool_info) = lookup_tool(&name) { + if let Ok(mut tool) = toml::parse_file(&config_path) { + let tool_btree: BTreeMap = + BTreeMap::from([(name, tool_info.into())]); + tool.tools = tool_btree; + sync(tool); + } + } + } } } From feb037b8e0512faf7fa4f89a1c519ceb4fe43fa0 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Thu, 15 Sep 2022 16:46:00 +0200 Subject: [PATCH 2/5] added some documentation about the install command --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index de441fd..1517f9d 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,12 @@ Install all the tools from config in a different location: tool --config=path/to/my/config.toml sync ``` +Install a tool that is hardcoded in the known tools list: + +```shell +tool install ripgrep +``` + Run `tool --help` for more details. > :octocat: If you hit the limit for downloading assets or want to download From 3bb4240f0fefb0e11282e64361c4631d11a46382 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Thu, 15 Sep 2022 19:10:56 +0200 Subject: [PATCH 3/5] incorporated feedback and reordered main cli match --- src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 91b7b62..11f33e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,15 +5,16 @@ mod model; mod sync; use std::collections::BTreeMap; +use std::fmt::Write; use std::path::PathBuf; use clap::Parser; use crate::config::cli::{Cli, Command}; -use crate::config::schema::ConfigAsset; +use crate::config::schema::{Config, ConfigAsset}; use crate::config::template; use crate::config::toml; -use crate::sync::db::lookup_tool; +use crate::sync::db::{build_db, lookup_tool}; use crate::sync::sync; const DEFAULT_CONFIG_PATH: &str = ".tool.toml"; @@ -23,6 +24,7 @@ pub fn run() { let config_path = resolve_config_path(cli.config.clone()); match cli.command { + Command::DefaultConfig => generate_config(), Command::Sync => match toml::parse_file(&config_path) { Err(e) => { err::abort_with(&format!( @@ -31,20 +33,43 @@ pub fn run() { e.display() )); } - Ok(tool) => { - sync(tool); + Ok(config) => { + sync(config); } }, - Command::DefaultConfig => generate_config(), Command::Install { name } => { - if let Some(tool_info) = lookup_tool(&name) { - if let Ok(mut tool) = toml::parse_file(&config_path) { + with_parsed_file(&config_path, |mut config| { + if let Some(tool_info) = lookup_tool(&name) { let tool_btree: BTreeMap = BTreeMap::from([(name, tool_info.into())]); - tool.tools = tool_btree; - sync(tool); - } - } + config.tools = tool_btree; + sync(config); + } else { + let mut exit_message: String = + format!("Unknown tool: {}\nSupported tools:\n", name); + for tool in build_db().keys().cloned().collect::>() { + if let Err(e) = writeln!(exit_message, "\t* {}", tool) { + err::abort_suggest_issue(&format!("{}", e)); + }; + } + err::abort_with(&exit_message); + }; + }); + } + } +} + +fn with_parsed_file(config_path: &PathBuf, on_success: F) { + match toml::parse_file(config_path) { + Ok(config) => { + on_success(config); + } + Err(e) => { + err::abort_with(&format!( + "Error parsing configuration at path {}: {}", + config_path.display(), + e.display() + )); } } } From d123280d12005864743116264fc81a243f82f305 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Thu, 15 Sep 2022 19:34:14 +0200 Subject: [PATCH 4/5] added a shameless copy as an integration test for tool install ripgrep --- .github/workflows/ci.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dadbf9..60ffdb8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,19 @@ jobs: - name: Unit tests run: cargo test --verbose + - if: matrix.os != 'windows-latest' + name: "Integration test: [unix] [install ripgrep]" + env: + SYNC_DIR: "install-ripgrep" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + mkdir $SYNC_DIR + cargo run -- --config=tests/$SYNC_DIR.toml install ripgrep + + ls -l $SYNC_DIR + + if [[ ! -x $SYNC_DIR/rg ]]; then echo "error on: rg"; false; fi + - if: matrix.os != 'windows-latest' name: "Integration test: [unix] [only-ripgrep]" env: From 0382ad18e6c4532882f6543aa65ea2e6417d6fb3 Mon Sep 17 00:00:00 2001 From: Mitchell Berendhuysen Date: Thu, 15 Sep 2022 19:35:02 +0200 Subject: [PATCH 5/5] added tests file for integration test --- tests/install-ripgrep.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/install-ripgrep.toml diff --git a/tests/install-ripgrep.toml b/tests/install-ripgrep.toml new file mode 100644 index 0000000..7b3f26a --- /dev/null +++ b/tests/install-ripgrep.toml @@ -0,0 +1 @@ +store_directory = "install-ripgrep"