Skip to content

Commit

Permalink
[#57] Adds install command to install known tools (#89)
Browse files Browse the repository at this point in the history
Resolves #57 

This pr adds an `isntall` subcommand that lets the user install any of
the hardcoded tools. As a bonus it also implements the `From` trait to
convert from `ToolInfo` To `ConfigAsset`.

### Additional tasks

- [x] Documentation for changes provided/changed
- [x] Tests added
  • Loading branch information
MitchellBerend authored Sep 15, 2022
1 parent b79eeb9 commit 2bb99cf
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
}
18 changes: 18 additions & 0 deletions src/config/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -39,6 +40,23 @@ pub struct ConfigAsset {
pub asset_name: AssetName,
}

impl From<ToolInfo> 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
Expand Down
47 changes: 43 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ mod infra;
mod model;
mod sync;

use clap::Parser;
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::{Config, ConfigAsset};
use crate::config::template;
use crate::config::toml;
use crate::sync::db::{build_db, lookup_tool};
use crate::sync::sync;

const DEFAULT_CONFIG_PATH: &str = ".tool.toml";
Expand All @@ -19,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!(
Expand All @@ -27,11 +33,44 @@ pub fn run() {
e.display()
));
}
Ok(tool) => {
sync(tool);
Ok(config) => {
sync(config);
}
},
Command::DefaultConfig => generate_config(),
Command::Install { name } => {
with_parsed_file(&config_path, |mut config| {
if let Some(tool_info) = lookup_tool(&name) {
let tool_btree: BTreeMap<String, ConfigAsset> =
BTreeMap::from([(name, tool_info.into())]);
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::<Vec<String>>() {
if let Err(e) = writeln!(exit_message, "\t* {}", tool) {
err::abort_suggest_issue(&format!("{}", e));
};
}
err::abort_with(&exit_message);
};
});
}
}
}

fn with_parsed_file<F: FnOnce(Config)>(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()
));
}
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/install-ripgrep.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
store_directory = "install-ripgrep"

0 comments on commit 2bb99cf

Please sign in to comment.