Skip to content

Commit 8affc51

Browse files
committed
release: 0.6.1
2 parents 6bfa997 + 480a3c2 commit 8affc51

File tree

17 files changed

+21488
-632
lines changed

17 files changed

+21488
-632
lines changed

CREDITS.md

Lines changed: 78 additions & 69 deletions
Large diffs are not rendered by default.

Cargo.toml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cargo-bashman"
3-
version = "0.6.0"
3+
version = "0.6.1"
44
license = "WTFPL"
55
authors = ["Josh Stoik <[email protected]>"]
66
edition = "2021"
@@ -9,7 +9,7 @@ repository = "https://github.com/Blobfolio/bashman"
99
publish = false
1010

1111
[package.metadata.deb]
12-
maintainer = "Josh Stoik <hello@blobfolio.com>"
12+
maintainer = "Josh Stoik <josh@blobfolio.com>"
1313
copyright = "2024, Blobfolio, LLC <[email protected]>"
1414
license-file = ["./LICENSE", "0"]
1515
revision = "1"
@@ -45,6 +45,10 @@ description = "Do not generate CREDITS.md."
4545
long = "--no-man"
4646
description = "Do not generate MAN page(s)."
4747

48+
[[package.metadata.bashman.switches]]
49+
long = "--print-targets"
50+
description = "Print the supported target triples (for use with -t/--target) to STDOUT and exit."
51+
4852
[[package.metadata.bashman.switches]]
4953
short = "-V"
5054
long = "--version"
@@ -57,16 +61,22 @@ description = "Path to the Cargo.toml file to use."
5761
label = "<Cargo.toml>"
5862
path = true
5963

64+
[[package.metadata.bashman.options]]
65+
short = "-t"
66+
long = "--target"
67+
description = "Limit CREDITS.md to dependencies used by the target <TRIPLE>, e.g. x86_64-unknown-linux-gnu. See --print-targets for the supported values."
68+
label = "<TRIPLE>"
69+
6070
[build-dependencies]
6171
argyle = "0.10.*"
6272

6373
[dependencies]
6474
argyle = "0.10.*"
6575
adbyss_psl = "0.14.*"
66-
cargo_metadata = "=0.18.1"
6776
dactyl = "0.7.4"
6877
fyi_msg = "1.1.*"
6978
oxford_join = "0.4.*"
79+
serde_json = "1.0.*"
7080
trimothy = "0.3.*"
7181
utc2k = "0.11.*"
7282
write_atomic = "0.5.*"
@@ -87,6 +97,10 @@ features = [ "derive" ]
8797
version = "0.8.*"
8898
features = [ "preserve_order" ]
8999

100+
[dependencies.url]
101+
version = "2.5.*"
102+
features = [ "serde" ]
103+
90104
[profile.release]
91105
lto = true
92106
codegen-units = 1

README.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ cargo bashman [-h/--help]
5252

5353
The flags `--no-bash`, `--no-man`, and `--no-credits` can be used to skip the generation of BASH completions, MAN pages, and/or `CREDITS.md` respectively.
5454

55-
Note that for the `CREDITS.md` feature, [Cargo](https://github.com/rust-lang/cargo) is required. (It pulls the dependency tree from the `cargo metadata` output.)
55+
Note that for the `CREDITS.md` feature, [Cargo](https://github.com/rust-lang/cargo) is explicitly required. (It pulls the dependency tree from the `cargo metadata` output.)
5656

5757

5858
## CONFIGURATION
@@ -80,6 +80,7 @@ credits-dir = "../"
8080
| options | *array* | An array of your app's key=value options, if any. | |
8181
| arguments | *array* | An array of any trailing arguments expected by your app. | |
8282
| sections | *array* | Arbitrary sections to append to the MAN page. | |
83+
| credits | *array* | An array of non-Rust dependencies to add to CREDITS.md. | |
8384

8485
While `bash-dir`, `man-dir`, and `credits-dir` are required, the actual content generation can be skipped by using the CLI flags `--no-bash`, `--no-man`, and/or `--no-credits` respectively.
8586

@@ -227,6 +228,35 @@ items = [
227228
```
228229

229230

231+
### CREDITS
232+
233+
To include non-Rust dependencies — i.e. anything `cargo metadata` doesn't know about — in the `CREDITS.md` file generated by `BashMan`, add them to your manifest!
234+
235+
The fields for `credits` sections have the same formatting requirements as their equivalent Cargo Manifest counterparts. The `name` and `version` parts, in particular, may require a little finessing to make them fit the standard.
236+
237+
| Key | Type | Description |
238+
| --- | ---- | ----------- |
239+
| name | *string* | ["Package" name](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field). |
240+
| version | *string* | [Version](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field). |
241+
| license | *string* | [License](https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields). |
242+
| authors | *array* | One or more [authors](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field). |
243+
| repository | *string* | [URL](https://doc.rust-lang.org/cargo/reference/manifest.html#the-repository-field). |
244+
| optional | *bool* | Whether or not the dependency is optional. Default: `false` |
245+
246+
Both `name` and `version` are required; everything else is optional.
247+
248+
Example:
249+
```toml
250+
[[package.metadata.bashman.credits]]
251+
name = "lodepng"
252+
version = "2024.10.15" # Altered to meet semver requirement.
253+
license = "Zlib"
254+
authors = [ "Lode Vandevenne" ] # Or w/ email: Jane Doe <[email protected]>
255+
repository = "https://github.com/lvandeve/lodepng"
256+
optional = true
257+
```
258+
259+
230260
### ALL TOGETHER NOW
231261

232262
Taking `BashMan` as an example, the `Cargo.toml` will end up containing something like:
@@ -261,27 +291,3 @@ description = "Path to the Cargo.toml file to use."
261291
label = "<Cargo.toml>"
262292
path = true
263293
```
264-
265-
266-
267-
## License
268-
269-
See also: [CREDITS.md](CREDITS.md)
270-
271-
Copyright © 2024 [Blobfolio, LLC](https://blobfolio.com) &lt;[email protected]&gt;
272-
273-
This work is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2.
274-
275-
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
276-
Version 2, December 2004
277-
278-
Copyright (C) 2004 Sam Hocevar <[email protected]>
279-
280-
Everyone is permitted to copy and distribute verbatim or modified
281-
copies of this license document, and changing it is allowed as long
282-
as the name is changed.
283-
284-
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
285-
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
286-
287-
0. You just DO WHAT THE FUCK YOU WANT TO.

build.rs

Lines changed: 184 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,205 @@
33
*/
44

55
use argyle::KeyWordsBuilder;
6-
use std::path::PathBuf;
6+
use std::{
7+
borrow::Cow,
8+
collections::BTreeSet,
9+
ffi::OsStr,
10+
fs::File,
11+
io::{
12+
Error,
13+
ErrorKind,
14+
},
15+
path::PathBuf,
16+
process::{
17+
Command,
18+
Stdio,
19+
},
20+
};
721

822

923

10-
/// # Set Up CLI Arguments.
24+
/// # Build!
1125
pub fn main() {
26+
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");
27+
28+
build_cli();
29+
build_targets();
30+
}
31+
32+
/// # Build CLI Arguments.
33+
fn build_cli() {
1234
let mut builder = KeyWordsBuilder::default();
1335
builder.push_keys([
1436
"-h", "--help",
1537
"--no-bash",
1638
"--no-credits",
1739
"--no-man",
40+
"--print-targets",
1841
"-V", "--version",
1942
]);
20-
builder.push_keys_with_values(["-m", "--manifest-path"]);
43+
builder.push_keys_with_values([
44+
"-m", "--manifest-path",
45+
"-t", "--target",
46+
]);
2147
builder.save(out_path("argyle.rs"));
2248
}
2349

50+
/// # Build Targets.
51+
///
52+
/// This method generates an enum and supporting code matching all of the
53+
/// target triples supported by rustc.
54+
///
55+
/// It's a bit much, but this way we can detect and alert users to invalid
56+
/// <TARGET> values passed via CLI without having to pass through cargo's
57+
/// illegible error response.
58+
///
59+
/// This does, however, mean that for any given environment, the supported
60+
/// targets will be the _intersection_ of ours and theirs. Not ideal, but an
61+
/// acceptable tradeoff, I think.
62+
fn build_targets() {
63+
use std::fmt::Write;
64+
65+
let raw = Command::new({
66+
let out = std::env::var_os("RUSTC").unwrap_or_default();
67+
if out.is_empty() { Cow::Borrowed(OsStr::new("rustc")) }
68+
else { Cow::Owned(out) }
69+
})
70+
.args(["--print", "target-list"])
71+
.stdin(Stdio::null())
72+
.stdout(Stdio::piped())
73+
.stderr(Stdio::piped())
74+
.output()
75+
.and_then(|o|
76+
if o.status.success() {
77+
String::from_utf8(o.stdout)
78+
.map_err(|e| Error::new(ErrorKind::Other, e))
79+
}
80+
else {
81+
Err(Error::new(ErrorKind::Other, String::from_utf8_lossy(&o.stderr)))
82+
}
83+
);
84+
85+
let raw = match raw {
86+
Ok(raw) => raw,
87+
Err(e) => panic!("Unable to obtain target triples from rustc: {e}"),
88+
};
89+
90+
let all: BTreeSet<&str> = raw.lines()
91+
.filter_map(|line| {
92+
let line = line.trim();
93+
if line.is_empty() { None }
94+
else { Some(line) }
95+
})
96+
.collect();
97+
98+
// Codegen time!
99+
let mut out = String::with_capacity(32_768); // Probably about right.
100+
101+
// Define the enum.
102+
out.push_str("#[derive(Debug, Clone, Copy, Eq, PartialEq)]
103+
/// # Target Triples.
104+
pub(crate) enum TargetTriple {
105+
");
106+
107+
for (k, v) in all.iter().enumerate() {
108+
writeln!(&mut out, "\t/// # {v}\n\tT{k:03},").unwrap();
109+
}
110+
111+
// Close that off and add a TryFrom impl.
112+
out.push_str("}
113+
114+
impl TryFrom<String> for TargetTriple {
115+
type Error = BashManError;
116+
117+
fn try_from(mut src: String) -> Result<Self, Self::Error> {
118+
src.make_ascii_lowercase();
119+
match src.trim() {
120+
");
121+
122+
for (k, v) in all.iter().enumerate() {
123+
writeln!(&mut out, "\t\t\t{:?} => Ok(Self::T{k:03}),", v.to_ascii_lowercase()).unwrap();
124+
}
125+
126+
// Close it off and start a new impl to format as a string.
127+
out.push_str("\t\t\t_ => Err(BashManError::Target),
128+
}
129+
}
130+
}
131+
132+
impl fmt::Display for TargetTriple {
133+
#[inline]
134+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135+
f.pad(self.as_str())
136+
}
137+
}
138+
139+
impl TargetTriple {
140+
/// # As String Slice.
141+
pub(crate) const fn as_str(self) -> &'static str {
142+
match self {
143+
");
144+
145+
for (k, v) in all.iter().enumerate() {
146+
writeln!(&mut out, "\t\t\tSelf::T{k:03} => {v:?},").unwrap();
147+
}
148+
149+
// Close it off and start a code for an iterator.
150+
out.push_str("\t\t}
151+
}
152+
153+
/// # Target Triple Iterator.
154+
const fn all() -> TargetTripleIter { TargetTripleIter(0) }
155+
}
156+
157+
158+
159+
/// # Target Triple Iterator.
160+
struct TargetTripleIter(u16);
161+
162+
impl Iterator for TargetTripleIter {
163+
type Item = TargetTriple;
164+
165+
fn next(&mut self) -> Option<Self::Item> {
166+
let pos = self.0;
167+
self.0 += 1;
168+
match pos {
169+
");
170+
171+
// Note: transmute would be more economical here, but this crate forbids
172+
// unsafe_code. Hopefully the compiler will do that all on its own.
173+
let len = all.len();
174+
for k in 0..len {
175+
writeln!(&mut out, "\t\t\t{k} => Some(TargetTriple::T{k:03}),").unwrap();
176+
}
177+
178+
// Close it off and add ExactSizeIterator bits.
179+
writeln!(
180+
&mut out,
181+
"\t\t\t_ => None,
182+
}}
183+
}}
184+
185+
fn size_hint(&self) -> (usize, Option<usize>) {{
186+
let len = self.len();
187+
(len, Some(len))
188+
}}
189+
}}
190+
191+
impl ExactSizeIterator for TargetTripleIter {{
192+
#[inline]
193+
fn len(&self) -> usize {{ usize::from({len}_u16.saturating_sub(self.0)) }}
194+
}}"
195+
).unwrap();
196+
197+
// Save it!
198+
File::create(out_path("target-triples.rs")).and_then(|mut f| {
199+
use std::io::Write;
200+
f.write_all(out.as_bytes()).and_then(|_| f.flush())
201+
})
202+
.expect("Unable to save target-triples.rs");
203+
}
204+
24205
/// # Output Path.
25206
///
26207
/// Append the sub-path to OUT_DIR and return it.

justfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ export RUSTFLAGS := "-C target-cpu=x86-64-v3"
3939
# Build Debian package!
4040
@build-deb: clean build
4141
# Do completions/man.
42-
{{ cargo_bin }} -m "{{ justfile_directory() }}/Cargo.toml"
42+
{{ cargo_bin }} \
43+
-m "{{ justfile_directory() }}/Cargo.toml" \
44+
-t x86_64-unknown-linux-gnu
4345

4446
# cargo-deb doesn't support target_dir flags yet.
4547
[ ! -d "{{ justfile_directory() }}/target" ] || rm -rf "{{ justfile_directory() }}/target"

release/completions/cargo-bashman.bash

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ _basher___cargo_bashman() {
1111
[[ " ${COMP_LINE} " =~ " --no-bash " ]] || opts+=("--no-bash")
1212
[[ " ${COMP_LINE} " =~ " --no-credits " ]] || opts+=("--no-credits")
1313
[[ " ${COMP_LINE} " =~ " --no-man " ]] || opts+=("--no-man")
14+
[[ " ${COMP_LINE} " =~ " --print-targets " ]] || opts+=("--print-targets")
1415
if [[ ! " ${COMP_LINE} " =~ " -V " ]] && [[ ! " ${COMP_LINE} " =~ " --version " ]]; then
1516
opts+=("-V")
1617
opts+=("--version")
@@ -19,6 +20,10 @@ _basher___cargo_bashman() {
1920
opts+=("-m")
2021
opts+=("--manifest-path")
2122
fi
23+
if [[ ! " ${COMP_LINE} " =~ " -t " ]] && [[ ! " ${COMP_LINE} " =~ " --target " ]]; then
24+
opts+=("-t")
25+
opts+=("--target")
26+
fi
2227
opts=" ${opts[@]} "
2328
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
2429
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )

0 commit comments

Comments
 (0)