Skip to content

Commit f715c99

Browse files
committed
Support autobins and target renaming [lib] and [[bin]]
1 parent 9d83a34 commit f715c99

9 files changed

+280
-62
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "cargo-subcommand"
33
version = "0.11.0"
44
authors = ["David Craven <david@craven.ch>", "Marijn Suijten <marijn@traverseresearch.nl>"]
5-
edition = "2018"
5+
edition = "2021"
66
description = "Library for creating cargo subcommands."
77
repository = "https://github.com/dvc94ch/cargo-subcommand"
88
license = "ISC"

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
# cargo-subcommand library for building subcommands
2-
Is used by `cargo-apk` and `cargo-flutter`.
1+
# `cargo-subcommand` library for building subcommands
2+
3+
Is used by [`cargo-apk`](https://crates.io/crates/cargo-apk) and `cargo-flutter`.
34

45
# License
6+
57
Copyright 2020 David Craven <david@craven.ch>
68

79
Permission is hereby granted, free of charge, to any person obtaining a copy of

src/args.rs

+9
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,13 @@ impl Args {
130130
Profile::Dev
131131
}
132132
}
133+
134+
/// Returns [`true`] when one or more target selection options are active.
135+
/// This is generally used to deduce whether to default to binary and
136+
/// library targets, in accordance with [`cargo build`].
137+
///
138+
/// [`cargo build`]: https://doc.rust-lang.org/cargo/commands/cargo-build.html#target-selection
139+
pub fn specific_target_selected(&self) -> bool {
140+
self.lib || self.bins || self.examples || !self.bin.is_empty() || !self.example.is_empty()
141+
}
133142
}

src/artifact.rs

+40-33
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,57 @@
1-
use std::path::Path;
1+
use std::path::{Path, PathBuf};
22

3-
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
4-
pub enum Artifact {
5-
Root(String),
6-
Example(String),
3+
use crate::manifest::CrateType;
4+
5+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
6+
pub enum ArtifactType {
7+
Lib,
8+
Bin,
9+
Example,
10+
// Bench,
11+
// Test,
712
}
813

9-
impl AsRef<Path> for Artifact {
10-
fn as_ref(&self) -> &Path {
11-
Path::new(match self {
12-
Self::Root(_) => "",
13-
Self::Example(_) => "examples",
14-
})
15-
}
14+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
15+
pub struct Artifact {
16+
pub name: String,
17+
pub path: PathBuf,
18+
pub r#type: ArtifactType,
19+
// TODO: root, with a ty, because examples can also have a ty
20+
// Bin { name: String, path: PathBuf },
21+
// Example { name: String, path: PathBuf },
1622
}
1723

1824
impl Artifact {
19-
pub fn name(&self) -> &str {
20-
match self {
21-
Self::Root(name) => name,
22-
Self::Example(name) => name,
23-
}
25+
pub fn build_dir(&self) -> &'static Path {
26+
Path::new(match self.r#type {
27+
ArtifactType::Lib | ArtifactType::Bin => "",
28+
ArtifactType::Example => "examples",
29+
})
2430
}
2531

32+
// TODO: CrateType should be read from the manifest' crate-type array,
33+
// and validated that the requested format is in that array
2634
pub fn file_name(&self, ty: CrateType, target: &str) -> String {
27-
match ty {
28-
CrateType::Bin => {
35+
match (self.r#type, ty) {
36+
(ArtifactType::Bin | ArtifactType::Example, CrateType::Bin) => {
2937
if target.contains("windows") {
30-
format!("{}.exe", self.name())
38+
format!("{}.exe", self.name)
3139
} else if target.contains("wasm") {
32-
format!("{}.wasm", self.name())
40+
format!("{}.wasm", self.name)
3341
} else {
34-
self.name().to_string()
42+
self.name.to_string()
3543
}
3644
}
37-
CrateType::Lib => format!("lib{}.rlib", self.name().replace('-', "_")),
38-
CrateType::Staticlib => format!("lib{}.a", self.name().replace('-', "_")),
39-
CrateType::Cdylib => format!("lib{}.so", self.name().replace('-', "_")),
45+
(ArtifactType::Lib | ArtifactType::Example, CrateType::Lib) => {
46+
format!("lib{}.rlib", self.name.replace('-', "_"))
47+
}
48+
(ArtifactType::Lib | ArtifactType::Example, CrateType::Staticlib) => {
49+
format!("lib{}.a", self.name.replace('-', "_"))
50+
}
51+
(ArtifactType::Lib | ArtifactType::Example, CrateType::Cdylib) => {
52+
format!("lib{}.so", self.name.replace('-', "_"))
53+
}
54+
(a, c) => panic!("{a:?} is not compatible with {c:?}"),
4055
}
4156
}
4257
}
43-
44-
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
45-
pub enum CrateType {
46-
Bin,
47-
Lib,
48-
Staticlib,
49-
Cdylib,
50-
}

src/error.rs

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ pub enum Error {
2222
},
2323
Io(PathBuf, IoError),
2424
Toml(PathBuf, TomlError),
25+
BinNotFound(String),
26+
DuplicateBin(String),
27+
DuplicateExample(String),
2528
}
2629

2730
pub type Result<T, E = Error> = std::result::Result<T, E>;
@@ -74,6 +77,9 @@ Alternatively, to keep it out of the workspace, add an empty `[workspace]` table
7477
},
7578
Self::Io(path, error) => return write!(f, "{}: {}", path.display(), error),
7679
Self::Toml(file, error) => return write!(f, "{}: {}", file.display(), error),
80+
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),
81+
Self::DuplicateBin(name) => return write!(f, "found duplicate binary name {name}, but all binary targets must have a unique name"),
82+
Self::DuplicateExample(name) => return write!(f, "found duplicate example name {name}, but all example targets must have a unique name"),
7783
})
7884
}
7985
}

src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ mod subcommand;
88
mod utils;
99

1010
pub use args::Args;
11-
pub use artifact::{Artifact, CrateType};
11+
pub use artifact::{Artifact, ArtifactType};
1212
pub use config::{EnvError, EnvOption, LocalizedConfig};
1313
pub use error::Error;
14+
pub use manifest::CrateType;
1415
pub use profile::Profile;
1516
pub use subcommand::Subcommand;

src/manifest.rs

+48
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ use crate::utils;
1111
pub struct Manifest {
1212
pub workspace: Option<Workspace>,
1313
pub package: Option<Package>,
14+
pub lib: Option<Lib>,
15+
#[serde(default, rename = "bin")]
16+
pub bins: Vec<Bin>,
17+
#[serde(default, rename = "example")]
18+
pub examples: Vec<Example>,
1419
}
1520

1621
impl Manifest {
@@ -90,7 +95,50 @@ pub struct Workspace {
9095
pub members: Vec<String>,
9196
}
9297

98+
const fn default_true() -> bool {
99+
true
100+
}
101+
93102
#[derive(Clone, Debug, Deserialize)]
94103
pub struct Package {
95104
pub name: String,
105+
106+
// https://doc.rust-lang.org/cargo/reference/cargo-targets.html#target-auto-discovery
107+
#[serde(default = "default_true")]
108+
pub autobins: bool,
109+
#[serde(default = "default_true")]
110+
pub autoexamples: bool,
111+
// #[serde(default = "default_true")]
112+
// pub autotests: bool,
113+
// #[serde(default = "default_true")]
114+
// pub autobenches: bool,
115+
}
116+
117+
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize)]
118+
pub enum CrateType {
119+
Bin,
120+
Lib,
121+
Staticlib,
122+
Cdylib,
123+
}
124+
125+
#[derive(Clone, Debug, Deserialize)]
126+
pub struct Lib {
127+
pub name: Option<String>,
128+
pub path: Option<PathBuf>,
129+
// pub crate_type: Vec<CrateType>,
130+
}
131+
132+
#[derive(Clone, Debug, Deserialize)]
133+
pub struct Bin {
134+
pub name: String,
135+
pub path: Option<PathBuf>,
136+
// pub crate_type: Vec<CrateType>,
137+
}
138+
139+
#[derive(Clone, Debug, Deserialize)]
140+
pub struct Example {
141+
pub name: String,
142+
pub path: Option<PathBuf>,
143+
// pub crate_type: Vec<CrateType>,
96144
}

0 commit comments

Comments
 (0)