Skip to content

Commit

Permalink
Support autobins and target renaming [lib] and [[bin]]
Browse files Browse the repository at this point in the history
  • Loading branch information
MarijnS95 committed Jun 27, 2023
1 parent 9d83a34 commit c20ac24
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cargo-subcommand"
version = "0.11.0"
authors = ["David Craven <[email protected]>", "Marijn Suijten <[email protected]>"]
edition = "2018"
edition = "2021"
description = "Library for creating cargo subcommands."
repository = "https://github.com/dvc94ch/cargo-subcommand"
license = "ISC"
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# cargo-subcommand library for building subcommands
Is used by `cargo-apk` and `cargo-flutter`.
# `cargo-subcommand` library for building subcommands

Is used by [`cargo-apk`](https://crates.io/crates/cargo-apk) and `cargo-flutter`.

# License

Copyright 2020 David Craven <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of
Expand Down
9 changes: 9 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,13 @@ impl Args {
Profile::Dev
}
}

/// Returns [`true`] when one or more target selection options are active.
/// This is generally used to deduce whether to default to binary and
/// library targets, in accordance with [`cargo build`].
///
/// [`cargo build`]: https://doc.rust-lang.org/cargo/commands/cargo-build.html#target-selection
pub fn specific_target_selected(&self) -> bool {
self.lib || self.bins || self.examples || !self.bin.is_empty() || !self.example.is_empty()
}
}
70 changes: 37 additions & 33 deletions src/artifact.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,54 @@
use std::path::Path;
use std::path::{Path, PathBuf};

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Artifact {
Root(String),
Example(String),
use crate::manifest::CrateType;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum ArtifactType {
Lib,
Bin,
Example,
// Bench,
// Test,
}

impl AsRef<Path> for Artifact {
fn as_ref(&self) -> &Path {
Path::new(match self {
Self::Root(_) => "",
Self::Example(_) => "examples",
})
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Artifact {
pub name: String,
pub path: PathBuf,
pub r#type: ArtifactType,
}

impl Artifact {
pub fn name(&self) -> &str {
match self {
Self::Root(name) => name,
Self::Example(name) => name,
}
pub fn build_dir(&self) -> &'static Path {
Path::new(match self.r#type {
ArtifactType::Lib | ArtifactType::Bin => "",
ArtifactType::Example => "examples",
})
}

// TODO: CrateType should be read from the manifest' crate-type array,
// and validated that the requested format is in that array
pub fn file_name(&self, ty: CrateType, target: &str) -> String {
match ty {
CrateType::Bin => {
match (self.r#type, ty) {
(ArtifactType::Bin | ArtifactType::Example, CrateType::Bin) => {
if target.contains("windows") {
format!("{}.exe", self.name())
format!("{}.exe", self.name)
} else if target.contains("wasm") {
format!("{}.wasm", self.name())
format!("{}.wasm", self.name)
} else {
self.name().to_string()
self.name.to_string()
}
}
CrateType::Lib => format!("lib{}.rlib", self.name().replace('-', "_")),
CrateType::Staticlib => format!("lib{}.a", self.name().replace('-', "_")),
CrateType::Cdylib => format!("lib{}.so", self.name().replace('-', "_")),
(ArtifactType::Lib | ArtifactType::Example, CrateType::Lib) => {
format!("lib{}.rlib", self.name.replace('-', "_"))
}
(ArtifactType::Lib | ArtifactType::Example, CrateType::Staticlib) => {
format!("lib{}.a", self.name.replace('-', "_"))
}
(ArtifactType::Lib | ArtifactType::Example, CrateType::Cdylib) => {
format!("lib{}.so", self.name.replace('-', "_"))
}
(a, c) => panic!("{a:?} is not compatible with {c:?}"),
}
}
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum CrateType {
Bin,
Lib,
Staticlib,
Cdylib,
}
6 changes: 6 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub enum Error {
},
Io(PathBuf, IoError),
Toml(PathBuf, TomlError),
BinNotFound(String),
DuplicateBin(String),
DuplicateExample(String),
}

pub type Result<T, E = Error> = std::result::Result<T, E>;
Expand Down Expand Up @@ -74,6 +77,9 @@ Alternatively, to keep it out of the workspace, add an empty `[workspace]` table
},
Self::Io(path, error) => return write!(f, "{}: {}", path.display(), error),
Self::Toml(file, error) => return write!(f, "{}: {}", file.display(), error),
Self::BinNotFound(name) => return write!(f, "Can't find `{name}` bin at `src/bin/{name}.rs` or `src/bin/{name}/main.rs`. Please specify bin.path if you want to use a non-default path.", name = name),
Self::DuplicateBin(name) => return write!(f, "found duplicate binary name {name}, but all binary targets must have a unique name"),
Self::DuplicateExample(name) => return write!(f, "found duplicate example name {name}, but all example targets must have a unique name"),
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ mod subcommand;
mod utils;

pub use args::Args;
pub use artifact::{Artifact, CrateType};
pub use artifact::{Artifact, ArtifactType};
pub use config::{EnvError, EnvOption, LocalizedConfig};
pub use error::Error;
pub use manifest::CrateType;
pub use profile::Profile;
pub use subcommand::Subcommand;
48 changes: 48 additions & 0 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ use crate::utils;
pub struct Manifest {
pub workspace: Option<Workspace>,
pub package: Option<Package>,
pub lib: Option<Lib>,
#[serde(default, rename = "bin")]
pub bins: Vec<Bin>,
#[serde(default, rename = "example")]
pub examples: Vec<Example>,
}

impl Manifest {
Expand Down Expand Up @@ -90,7 +95,50 @@ pub struct Workspace {
pub members: Vec<String>,
}

const fn default_true() -> bool {
true
}

#[derive(Clone, Debug, Deserialize)]
pub struct Package {
pub name: String,

// https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery
#[serde(default = "default_true")]
pub autobins: bool,
#[serde(default = "default_true")]
pub autoexamples: bool,
// #[serde(default = "default_true")]
// pub autotests: bool,
// #[serde(default = "default_true")]
// pub autobenches: bool,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize)]
pub enum CrateType {
Bin,
Lib,
Staticlib,
Cdylib,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Lib {
pub name: Option<String>,
pub path: Option<PathBuf>,
// pub crate_type: Vec<CrateType>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Bin {
pub name: String,
pub path: Option<PathBuf>,
// pub crate_type: Vec<CrateType>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct Example {
pub name: String,
pub path: Option<PathBuf>,
// pub crate_type: Vec<CrateType>,
}
Loading

0 comments on commit c20ac24

Please sign in to comment.