Skip to content

Commit

Permalink
Provide arguments through struct which can also be parsed through `Cl…
Browse files Browse the repository at this point in the history
…ap` (#15)

* Remove Cargo.lock

* Use clap instead of hacky arg parsing.

* Update args.

* Make it build again.

* Update src/subcommand.rs

Co-authored-by: Marijn Suijten <[email protected]>

Co-authored-by: Marijn Suijten <[email protected]>
  • Loading branch information
dvc94ch and MarijnS95 authored Mar 25, 2022
1 parent 038722c commit 6c77c51
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 210 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/target
**/*.rs.bk
Cargo.lock
89 changes: 0 additions & 89 deletions Cargo.lock

This file was deleted.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ description = "Library for creating cargo subcommands."
repository = "https://github.com/dvc94ch/cargo-subcommand"
license = "ISC"

[features]
default = ["clap"]

[dependencies]
clap = { version = "3.1.6", optional = true, features = ["derive"] }
dunce = "1.0.1"
glob = "0.3.0"
serde = { version = "1.0.123", features = ["derive"] }
Expand Down
133 changes: 133 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use crate::profile::Profile;
#[cfg(feature = "clap")]
use clap::Parser;
use std::path::PathBuf;
use std::process::Command;

#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "clap", derive(Parser))]
pub struct Args {
/// No output printed to stdout
#[cfg_attr(feature = "clap", clap(long, short))]
pub quiet: bool,

/// Package to build
#[cfg_attr(feature = "clap", clap(long, short))]
pub package: Vec<String>,
/// Build all packages in the workspace
#[cfg_attr(feature = "clap", clap(long))]
pub workspace: bool,
/// Exclude packages from the build
#[cfg_attr(feature = "clap", clap(long))]
pub exclude: Vec<String>,

/// Build only this package's library
#[cfg_attr(feature = "clap", clap(long))]
pub lib: bool,
/// Build only the specified binary
#[cfg_attr(feature = "clap", clap(long))]
pub bin: Vec<String>,
/// Build all binaries
#[cfg_attr(feature = "clap", clap(long, conflicts_with = "bin"))]
pub bins: bool,
/// Build only the specified example
#[cfg_attr(feature = "clap", clap(long))]
pub example: Vec<String>,
/// Build all examples
#[cfg_attr(feature = "clap", clap(long, conflicts_with = "example"))]
pub examples: bool,

/// Build artifacts in release mode, with optimizations
#[cfg_attr(feature = "clap", clap(long))]
pub release: bool,
/// Build artifacts with the specified profile
#[cfg_attr(feature = "clap", clap(long, conflicts_with = "release"))]
pub profile: Option<Profile>,
/// Space or comma separated list of features to activate
#[cfg_attr(feature = "clap", clap(long))]
pub features: Vec<String>,
/// Activate all available features
#[cfg_attr(feature = "clap", clap(long))]
pub all_features: bool,
/// Do not activate the `default` feature
#[cfg_attr(feature = "clap", clap(long))]
pub no_default_features: bool,
/// Build for the target triple
#[cfg_attr(feature = "clap", clap(long))]
pub target: Option<String>,
/// Directory for all generated artifacts
#[cfg_attr(feature = "clap", clap(long))]
pub target_dir: Option<PathBuf>,
/// Path to Cargo.toml
#[cfg_attr(feature = "clap", clap(long))]
pub manifest_path: Option<PathBuf>,
}

impl Args {
pub fn apply(&self, cmd: &mut Command) {
if self.quiet {
cmd.arg("--quiet");
}

for package in &self.package {
cmd.arg("--package").arg(package);
}
if self.workspace {
cmd.arg("--workspace");
}
for exclude in &self.exclude {
cmd.arg("--exclude").arg(exclude);
}

if self.lib {
cmd.arg("--lib");
}
for bin in &self.bin {
cmd.arg("--bin").arg(bin);
}
if self.bins {
cmd.arg("--bins");
}
for example in &self.example {
cmd.arg("--example").arg(example);
}
if self.examples {
cmd.arg("--examples");
}

if self.release {
cmd.arg("--release");
}
if let Some(profile) = self.profile.as_ref() {
cmd.arg("--profile").arg(profile.to_string());
}
for features in &self.features {
cmd.arg("--features").arg(features);
}
if self.all_features {
cmd.arg("--all-features");
}
if self.no_default_features {
cmd.arg("--no-default-features");
}
if let Some(target) = self.target.as_ref() {
cmd.arg("--target").arg(target);
}
if let Some(target_dir) = self.target_dir.as_ref() {
cmd.arg("--target-dir").arg(target_dir);
}
if let Some(manifest_path) = self.manifest_path.as_ref() {
cmd.arg("--manifest-path").arg(manifest_path);
}
}

pub fn profile(&self) -> Profile {
if let Some(profile) = self.profile.as_ref() {
profile.clone()
} else if self.release {
Profile::Release
} else {
Profile::Dev
}
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod args;
mod artifact;
mod config;
mod error;
Expand All @@ -6,6 +7,7 @@ mod profile;
mod subcommand;
mod utils;

pub use args::Args;
pub use artifact::{Artifact, CrateType};
pub use config::{EnvError, EnvOption, LocalizedConfig};
pub use error::Error;
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use cargo_subcommand::Subcommand;
use cargo_subcommand::{Args, Subcommand};
use clap::Parser;

fn main() {
let cmd = Subcommand::new(std::env::args(), "subcommand", |_, _| Ok(false)).unwrap();
let args = Args::parse();
let cmd = Subcommand::new(args).unwrap();
println!("{:#?}", cmd);
}
23 changes: 23 additions & 0 deletions src/profile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::error::Error;
use std::path::Path;

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
Expand All @@ -7,6 +8,28 @@ pub enum Profile {
Custom(String),
}

impl std::fmt::Display for Profile {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str(match self {
Self::Dev => "dev",
Self::Release => "release",
Self::Custom(custom) => custom,
})
}
}

impl std::str::FromStr for Profile {
type Err = Error;

fn from_str(profile: &str) -> Result<Self, Self::Err> {
Ok(match profile {
"dev" => Profile::Dev,
"release" => Profile::Release,
custom => Profile::Custom(custom.into()),
})
}
}

impl AsRef<Path> for Profile {
fn as_ref(&self) -> &Path {
Path::new(match self {
Expand Down
Loading

0 comments on commit 6c77c51

Please sign in to comment.