Skip to content

Commit

Permalink
add initial version of 'lean-cli' feature toggle, but…
Browse files Browse the repository at this point in the history
…nested subcommands are not allowed.

Maybe this tells me that I want two binaries, one for plumbing, one for
everything else.
  • Loading branch information
Byron committed Jun 30, 2020
1 parent f558ce5 commit f01c298
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 51 deletions.
30 changes: 30 additions & 0 deletions Cargo.lock

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

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ doctest = false
default = ["fast", "pretty-cli"]
fast = ["git-features/parallel", "git-features/fast-sha1"]
pretty-cli = ["structopt"]
lean-cli = ["argh"]

[dependencies]
anyhow = "1.0.31"

gitoxide-core = { version = "0.1.0", path = "gitoxide-core" }
git-features = { version = "0.1.0", path = "git-features" }

structopt = { version = "0.3.14", optional = true }
anyhow = "1.0.31"
argh = { version = "0.1.3", optional = true }

[profile.release]
overflow-checks = false
Expand Down
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interactive-developer-environment-in-docker: ## Use docker for all dependencies
##@ Development

target/debug/gio: always
cargo build
cargo build --no-default-features --features pretty-cli

target/release/gio: always
cargo build --release
Expand All @@ -29,7 +29,7 @@ profile: target/release/gio ## run callgrind and annotate its output - linux onl
benchmark: target/release/gio ## see how fast things are, powered by hyperfine
hyperfine '$<'

tests: check unit-tests journey-tests ## run all tests, including journey tests
tests: check unit-tests journey-tests journey-tests-lean-cli ## run all tests, including journey tests

check: ## Build all code in suitable configurations
cargo check --all
Expand All @@ -43,9 +43,13 @@ unit-tests: ## run all unit tests
continuous-unit-tests: ## run all unit tests whenever something changes
watchexec -w src $(MAKE) unit-tests

journey-tests: target/debug/gio ## run stateless journey tests
journey-tests: target/debug/gio ## run stateless journey tests (pretty-cli)
./tests/stateless-journey.sh $<

journey-tests-lean-cli: always ## run stateless journey tests (lean-cli)
cargo build --no-default-features --features lean-cli
./tests/stateless-journey.sh target/debug/gio

continuous-journey-tests: ## run stateless journey tests whenever something changes
watchexec $(MAKE) journey-tests

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ The top-level command-line interface.
* If disabled, the binary will be visibly smaller.
* **pretty-cli** _(default)_
* Use `clap` + `structopt` to build the prettiest, best documented and most user-friendly CLI at the expense of file size.
* **small-cli** _(mutually exclusive to pretty-cli)_
* **lean-cli** _(mutually exclusive to pretty-cli)_
* Use `argh` to produce a usable binary with decent documentation that is smallest in size.
* If `pretty-cli` is enabled as well, `small-cli` will take precedence, and you pay for building unnecessary dependencies.

Expand Down
155 changes: 109 additions & 46 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,124 @@
#![forbid(unsafe_code)]

use anyhow::Result;
use gitoxide_core as core;
use std::io::{stderr, stdout};
use structopt::StructOpt;

mod options {
use std::path::PathBuf;
use structopt::clap::AppSettings;
#[cfg(feature = "pretty-cli")]
mod pretty {
use anyhow::Result;
use gitoxide_core as core;
use std::io::{stderr, stdout};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "The git, simply swift")]
#[structopt(settings = &[AppSettings::SubcommandRequired,
mod options {
use std::path::PathBuf;
use structopt::clap::AppSettings;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
#[structopt(about = "The git, simply swift")]
#[structopt(settings = &[AppSettings::SubcommandRequired,
AppSettings::ColoredHelp])]
pub struct Args {
#[structopt(subcommand)]
pub cmd: Subcommands,
pub struct Args {
#[structopt(subcommand)]
pub cmd: Subcommands,
}

/// Low-level commands that are not used every day
#[derive(Debug, StructOpt)]
pub enum Plumbing {
/// Verify the integrity of a pack or index file
#[structopt(setting = AppSettings::ColoredHelp)]
VerifyPack {
/// The '.pack' or '.idx' file whose checksum to validate.
#[structopt(parse(from_os_str))]
path: PathBuf,
},
}

#[derive(Debug, StructOpt)]
pub enum Subcommands {
/// Initialize the repository in the current directory.
#[structopt(alias = "initialize")]
#[structopt(setting = AppSettings::ColoredHelp)]
Init,

#[structopt(alias = "p")]
#[structopt(setting = AppSettings::ColoredHelp)]
Plumbing(Plumbing),
}
}

/// Low-level commands that are not used every day
#[derive(Debug, StructOpt)]
pub enum Plumbing {
/// Verify the integrity of a pack or index file
#[structopt(setting = AppSettings::ColoredHelp)]
VerifyPack {
/// The '.pack' file whose checksum to validate.
///
/// '.pack' files have a 20 byte trailer representing the Sha1 over all the bytes that
/// preceded it.
#[structopt(parse(from_os_str))]
path: PathBuf,
},
pub fn main() -> Result<()> {
use options::*;
let args = Args::from_args();
match args.cmd {
Subcommands::Init => core::init(),
Subcommands::Plumbing(cmd) => match cmd {
Plumbing::VerifyPack { path } => {
core::verify_pack_or_pack_index(path, stdout(), stderr())
}
},
}?;
Ok(())
}
}

#[derive(Debug, StructOpt)]
pub enum Subcommands {
/// Initialize the repository in the current directory.
#[structopt(alias = "initialize")]
#[structopt(setting = AppSettings::ColoredHelp)]
Init,
#[cfg(all(feature = "lean-cli", not(feature = "pretty-cli")))]
mod lean {
use argh::FromArgs;

#[structopt(alias = "p")]
#[structopt(setting = AppSettings::ColoredHelp)]
Plumbing(Plumbing),
#[derive(FromArgs)]
/// A simple calculation tool
struct Args {
#[argh(subcommand)]
subcommand: SubCommands,
}
}

fn main() -> Result<()> {
let args = options::Args::from_args();
match args.cmd {
options::Subcommands::Init => core::init(),
options::Subcommands::Plumbing(cmd) => match cmd {
options::Plumbing::VerifyPack { path } => {
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommands {
Init(Init),
VerifyPack(VerifyPack),
}

/// Initialize the repository in the current directory.
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "init")]
struct Init {}

/// Initialize the repository in the current directory.
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "verify-pack")]
struct VerifyPack {
/// the '.pack' or '.idx' file whose checksum to validate.
#[argh(option)]
path: PathBuf,
}

use anyhow::Result;
use gitoxide_core as core;
use std::{
io::{stderr, stdout},
path::PathBuf,
};

pub fn main() -> Result<()> {
let cli: Args = argh::from_env();
match cli.subcommand {
SubCommands::Init(_) => core::init(),
SubCommands::VerifyPack(VerifyPack { path }) => {
core::verify_pack_or_pack_index(path, stdout(), stderr())
}
},
}?;
Ok(())
}
}
}

use anyhow::Result;

#[cfg(feature = "pretty-cli")]
fn main() -> Result<()> {
pretty::main()
}

#[cfg(all(feature = "lean-cli", not(feature = "pretty-cli")))]
fn main() -> Result<()> {
lean::main()
}

0 comments on commit f01c298

Please sign in to comment.