Skip to content

Commit

Permalink
Merge pull request #236 from jordilin/ampscmds
Browse files Browse the repository at this point in the history
Provide amps list/exec command
  • Loading branch information
jordilin committed Jun 15, 2024
2 parents 0828cd2 + edc13a8 commit 651c888
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "git-ar"
version = "0.1.70"
version = "0.1.71"
edition = "2021"

license = "MIT"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ You can download the latest release from the releases page
<https://github.com/jordilin/gitar/releases> and place the binary anywhere in
your path.

Or you can build from source.
Or you can build from source. Building from source requires the latest stable
release of Rust.

```bash
cargo build --release
Expand Down
1 change: 1 addition & 0 deletions doc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
- [Configuration](./configuration.md)
- [Gitar commands](./cmds/index.md)
- [Merge request](./cmds/merge_request.md)
- [Amps](./cmds/amps.md)
55 changes: 55 additions & 0 deletions doc/src/cmds/amps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# gr amps

`gr amps` lists and execute amps. Amps are wrappers around the `gr` command
itself. Amps normally execute gr subcommands and perform additional logic to get
to the desired result. They can also be seen as just `gr` scripts that can be
executed from `gr` itself. A curated list of amps is provided at
<https://github.com/jordilin/gitar-amps>.

## List available amps

```bash
gr amps
```

or

```bash
gr amps list
```

## Execute an amp in-line

To execute an amp in-line, you can use the following command:

```bash
gr amps exec "<amp-name> <arg_0> <arg_1> ... <arg_n>"
```

For example:

```bash
gr amps exec "list-last-assets github.com/jordilin/gitar"
```

will print out the URLs of the last stable release assets for the
`github.com/jordilin/gitar` repository.

**> Note:** Arguments for the amps are optional and the amp name and its
arguments should be enclosed in double quotes.

## Execute an amp by prompt

```bash
gr amps exec
```

This command will prompt you to select an amp from the list of available amps.
After selecting the amp name, it will prompt you to enter the arguments for the
amp. Upon pressing enter, the amp will be executed.

The prompt undertands the following prompt queries once an amp has been
selected:

- `h` or `help` - Show help message for the selected amp.
- `q` or `quit` - Quit the prompt and return back to the CLI.
1 change: 1 addition & 0 deletions doc/src/cmds/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## Commands available

- [Merge request](./merge_request.md)
- [Amps](./amps.md)

All gitar commands have a set of common options that can be used to control
their behavior.
Expand Down
3 changes: 3 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,8 @@ audit:
mkdir -p .cargo-audit-db/db
cargo audit -D warnings -d .cargo-audit-db/db

mdbook-serve:
mdbook serve doc --open

doc:
cargo doc --no-deps --open
9 changes: 6 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod amps;
pub mod browse;
pub mod cache;
pub mod cicd;
Expand All @@ -23,6 +24,8 @@ use self::project::{ProjectCommand, ProjectOptions};
use self::release::{ReleaseCommand, ReleaseOptions};
use self::trending::TrendingCommand;
use self::trending::TrendingOptions;
use amps::AmpsCommand;
use amps::AmpsOptions;
use cache::CacheCommand;
use cache::CacheOptions;
use merge_request::{MergeRequestCommand, MergeRequestOptions};
Expand Down Expand Up @@ -89,7 +92,7 @@ enum Command {
Trending(TrendingCommand),
/// Interactively execute gitar amplifier commands using gitar. gr-in-gr
#[clap(name = "amps")]
Amps,
Amps(AmpsCommand),
#[clap(name = "init", about = "Initialize the config file")]
Init(InitCommand),
#[clap(name = "cache", about = "Local cache operations")]
Expand Down Expand Up @@ -117,7 +120,7 @@ pub fn parse_cli() -> OptionArgs {
Command::Trending(sub_matches) => Some(CliOptions::Trending(sub_matches.into())),
Command::Cache(sub_matches) => Some(CliOptions::Cache(sub_matches.into())),
Command::Manual => Some(CliOptions::Manual),
Command::Amps => Some(CliOptions::Amps),
Command::Amps(sub_matches) => Some(CliOptions::Amps(sub_matches.into())),
};
OptionArgs::new(
options,
Expand All @@ -137,7 +140,7 @@ pub enum CliOptions {
Trending(TrendingOptions),
Cache(CacheOptions),
Manual,
Amps,
Amps(AmpsOptions),
}

#[derive(Clone)]
Expand Down
83 changes: 83 additions & 0 deletions src/cli/amps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use clap::Parser;

#[derive(Parser)]
pub struct AmpsCommand {
#[clap(subcommand)]
subcommand: Option<AmpsSubcommand>,
}

#[derive(Parser)]
enum AmpsSubcommand {
#[clap(about = "List available amps")]
List,
#[clap(
name = "exec",
about = "Execute an amp, either by name or through prompt",
alias = "ex"
)]
Exec(ExecCommand),
}

#[derive(Parser)]
struct ExecCommand {
/// The name of the amp to execute
#[clap()]
pub name: Option<String>,
}

pub enum AmpsOptions {
List,
Exec(String),
}

impl From<AmpsCommand> for AmpsOptions {
fn from(options: AmpsCommand) -> Self {
match options.subcommand {
Some(AmpsSubcommand::List) => AmpsOptions::List,
Some(AmpsSubcommand::Exec(options)) => options.into(),
// defaults to list available amps
None => AmpsOptions::List,
}
}
}

impl From<ExecCommand> for AmpsOptions {
fn from(options: ExecCommand) -> Self {
match options.name {
Some(name) => AmpsOptions::Exec(name),
// defaults to execute amp through prompt
None => AmpsOptions::Exec(String::new()),
}
}
}

#[cfg(test)]
mod tests {
use crate::cli::{Args, Command};

use super::*;

#[test]
fn test_amps_list_command() {
let args = Args::parse_from(vec!["gr", "amps", "list"]);
match args.command {
Command::Amps(AmpsCommand {
subcommand: Some(AmpsSubcommand::List),
}) => {}
_ => panic!("Expected Amp ListCommand"),
}
}

#[test]
fn test_amps_exec_command() {
let args = Args::parse_from(vec!["gr", "amps", "exec", "amp-name"]);
match args.command {
Command::Amps(AmpsCommand {
subcommand: Some(AmpsSubcommand::Exec(ExecCommand { name })),
}) => {
assert_eq!(name, Some("amp-name".to_string()));
}
_ => panic!("Expected Amp ExecCommand"),
}
}
}
44 changes: 34 additions & 10 deletions src/cmds/amps.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
use std::path::Path;

use crate::{
cli::amps::AmpsOptions::{self, Exec},
dialog,
error::GRError,
io::{Response, TaskRunner},
shell, Result,
};

pub fn execute(config_file: std::path::PathBuf) -> Result<()> {
let base_path = config_file.parent().unwrap();
let amps_scripts = base_path.join("amps");
let runner = shell::BlockingCommand;
let amps = list_amps(runner, amps_scripts.to_str().unwrap())?;
let amp_script = dialog::fuzzy_select(amps)?;
let stream_runner = shell::StreamingCommand;
let amp_runner = Amp::new(dialog::prompt_args, &stream_runner);
amp_runner.exec_amps(amp_script, base_path)?;
Ok(())
pub fn execute(options: AmpsOptions, config_file: std::path::PathBuf) -> Result<()> {
match options {
Exec(amp_name_args) => {
let base_path = config_file.parent().unwrap();
let amps_scripts = base_path.join("amps");
if amp_name_args.is_empty() {
let runner = shell::BlockingCommand;
let amps = list_amps(runner, amps_scripts.to_str().unwrap())?;
let amp_script = dialog::fuzzy_select(amps)?;
let stream_runner = shell::StreamingCommand;
let amp_runner = Amp::new(dialog::prompt_args, &stream_runner);
amp_runner.exec_amps(amp_script, base_path)?;
return Ok(());
}
let stream_runner = shell::StreamingCommand;
let amp_name_args: Vec<&str> = amp_name_args.split(' ').collect();
let amp_name = amp_name_args[0];
let amp_path = amps_scripts.join(amp_name);
let args = amp_name_args[1..].join(" ");
stream_runner.run(vec![&amp_path.to_str().unwrap(), &args.as_str()])?;
Ok(())
}
_ => {
let base_path = config_file.parent().unwrap();
let amps_scripts = base_path.join("amps");
let runner = shell::BlockingCommand;
let amps = list_amps(runner, amps_scripts.to_str().unwrap())?;
for amp in amps {
println!("{}", amp);
}
Ok(())
}
}
}

fn list_amps(runner: impl TaskRunner<Response = Response>, amps_path: &str) -> Result<Vec<String>> {
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,6 @@ fn handle_cli_options(
"".to_string(),
"".to_string(),
),
CliOptions::Amps => cmds::amps::execute(config_file),
CliOptions::Amps(options) => cmds::amps::execute(options, config_file),
}
}

0 comments on commit 651c888

Please sign in to comment.