Skip to content

Commit

Permalink
release: 0.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
joshstoik1 committed Oct 31, 2024
2 parents 6bfa997 + 480a3c2 commit 8affc51
Show file tree
Hide file tree
Showing 17 changed files with 21,488 additions and 632 deletions.
147 changes: 78 additions & 69 deletions CREDITS.md

Large diffs are not rendered by default.

20 changes: 17 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-bashman"
version = "0.6.0"
version = "0.6.1"
license = "WTFPL"
authors = ["Josh Stoik <[email protected]>"]
edition = "2021"
Expand All @@ -9,7 +9,7 @@ repository = "https://github.com/Blobfolio/bashman"
publish = false

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

[[package.metadata.bashman.switches]]
long = "--print-targets"
description = "Print the supported target triples (for use with -t/--target) to STDOUT and exit."

[[package.metadata.bashman.switches]]
short = "-V"
long = "--version"
Expand All @@ -57,16 +61,22 @@ description = "Path to the Cargo.toml file to use."
label = "<Cargo.toml>"
path = true

[[package.metadata.bashman.options]]
short = "-t"
long = "--target"
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."
label = "<TRIPLE>"

[build-dependencies]
argyle = "0.10.*"

[dependencies]
argyle = "0.10.*"
adbyss_psl = "0.14.*"
cargo_metadata = "=0.18.1"
dactyl = "0.7.4"
fyi_msg = "1.1.*"
oxford_join = "0.4.*"
serde_json = "1.0.*"
trimothy = "0.3.*"
utc2k = "0.11.*"
write_atomic = "0.5.*"
Expand All @@ -87,6 +97,10 @@ features = [ "derive" ]
version = "0.8.*"
features = [ "preserve_order" ]

[dependencies.url]
version = "2.5.*"
features = [ "serde" ]

[profile.release]
lto = true
codegen-units = 1
Expand Down
56 changes: 31 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ cargo bashman [-h/--help]

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.

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.)
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.)


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

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.

Expand Down Expand Up @@ -227,6 +228,35 @@ items = [
```


### CREDITS

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!

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.

| Key | Type | Description |
| --- | ---- | ----------- |
| name | *string* | ["Package" name](https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field). |
| version | *string* | [Version](https://doc.rust-lang.org/cargo/reference/manifest.html#the-version-field). |
| license | *string* | [License](https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields). |
| authors | *array* | One or more [authors](https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field). |
| repository | *string* | [URL](https://doc.rust-lang.org/cargo/reference/manifest.html#the-repository-field). |
| optional | *bool* | Whether or not the dependency is optional. Default: `false` |

Both `name` and `version` are required; everything else is optional.

Example:
```toml
[[package.metadata.bashman.credits]]
name = "lodepng"
version = "2024.10.15" # Altered to meet semver requirement.
license = "Zlib"
authors = [ "Lode Vandevenne" ] # Or w/ email: Jane Doe <[email protected]>
repository = "https://github.com/lvandeve/lodepng"
optional = true
```


### ALL TOGETHER NOW

Taking `BashMan` as an example, the `Cargo.toml` will end up containing something like:
Expand Down Expand Up @@ -261,27 +291,3 @@ description = "Path to the Cargo.toml file to use."
label = "<Cargo.toml>"
path = true
```



## License

See also: [CREDITS.md](CREDITS.md)

Copyright © 2024 [Blobfolio, LLC](https://blobfolio.com) &lt;[email protected]&gt;

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.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar <[email protected]>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.
187 changes: 184 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,205 @@
*/

use argyle::KeyWordsBuilder;
use std::path::PathBuf;
use std::{
borrow::Cow,
collections::BTreeSet,
ffi::OsStr,
fs::File,
io::{
Error,
ErrorKind,
},
path::PathBuf,
process::{
Command,
Stdio,
},
};



/// # Set Up CLI Arguments.
/// # Build!
pub fn main() {
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");

build_cli();
build_targets();
}

/// # Build CLI Arguments.
fn build_cli() {
let mut builder = KeyWordsBuilder::default();
builder.push_keys([
"-h", "--help",
"--no-bash",
"--no-credits",
"--no-man",
"--print-targets",
"-V", "--version",
]);
builder.push_keys_with_values(["-m", "--manifest-path"]);
builder.push_keys_with_values([
"-m", "--manifest-path",
"-t", "--target",
]);
builder.save(out_path("argyle.rs"));
}

/// # Build Targets.
///
/// This method generates an enum and supporting code matching all of the
/// target triples supported by rustc.
///
/// It's a bit much, but this way we can detect and alert users to invalid
/// <TARGET> values passed via CLI without having to pass through cargo's
/// illegible error response.
///
/// This does, however, mean that for any given environment, the supported
/// targets will be the _intersection_ of ours and theirs. Not ideal, but an
/// acceptable tradeoff, I think.
fn build_targets() {
use std::fmt::Write;

let raw = Command::new({
let out = std::env::var_os("RUSTC").unwrap_or_default();
if out.is_empty() { Cow::Borrowed(OsStr::new("rustc")) }
else { Cow::Owned(out) }
})
.args(["--print", "target-list"])
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.and_then(|o|
if o.status.success() {
String::from_utf8(o.stdout)
.map_err(|e| Error::new(ErrorKind::Other, e))
}
else {
Err(Error::new(ErrorKind::Other, String::from_utf8_lossy(&o.stderr)))
}
);

let raw = match raw {
Ok(raw) => raw,
Err(e) => panic!("Unable to obtain target triples from rustc: {e}"),
};

let all: BTreeSet<&str> = raw.lines()
.filter_map(|line| {
let line = line.trim();
if line.is_empty() { None }
else { Some(line) }
})
.collect();

// Codegen time!
let mut out = String::with_capacity(32_768); // Probably about right.

// Define the enum.
out.push_str("#[derive(Debug, Clone, Copy, Eq, PartialEq)]
/// # Target Triples.
pub(crate) enum TargetTriple {
");

for (k, v) in all.iter().enumerate() {
writeln!(&mut out, "\t/// # {v}\n\tT{k:03},").unwrap();
}

// Close that off and add a TryFrom impl.
out.push_str("}
impl TryFrom<String> for TargetTriple {
type Error = BashManError;
fn try_from(mut src: String) -> Result<Self, Self::Error> {
src.make_ascii_lowercase();
match src.trim() {
");

for (k, v) in all.iter().enumerate() {
writeln!(&mut out, "\t\t\t{:?} => Ok(Self::T{k:03}),", v.to_ascii_lowercase()).unwrap();
}

// Close it off and start a new impl to format as a string.
out.push_str("\t\t\t_ => Err(BashManError::Target),
}
}
}
impl fmt::Display for TargetTriple {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(self.as_str())
}
}
impl TargetTriple {
/// # As String Slice.
pub(crate) const fn as_str(self) -> &'static str {
match self {
");

for (k, v) in all.iter().enumerate() {
writeln!(&mut out, "\t\t\tSelf::T{k:03} => {v:?},").unwrap();
}

// Close it off and start a code for an iterator.
out.push_str("\t\t}
}
/// # Target Triple Iterator.
const fn all() -> TargetTripleIter { TargetTripleIter(0) }
}
/// # Target Triple Iterator.
struct TargetTripleIter(u16);
impl Iterator for TargetTripleIter {
type Item = TargetTriple;
fn next(&mut self) -> Option<Self::Item> {
let pos = self.0;
self.0 += 1;
match pos {
");

// Note: transmute would be more economical here, but this crate forbids
// unsafe_code. Hopefully the compiler will do that all on its own.
let len = all.len();
for k in 0..len {
writeln!(&mut out, "\t\t\t{k} => Some(TargetTriple::T{k:03}),").unwrap();
}

// Close it off and add ExactSizeIterator bits.
writeln!(
&mut out,
"\t\t\t_ => None,
}}
}}
fn size_hint(&self) -> (usize, Option<usize>) {{
let len = self.len();
(len, Some(len))
}}
}}
impl ExactSizeIterator for TargetTripleIter {{
#[inline]
fn len(&self) -> usize {{ usize::from({len}_u16.saturating_sub(self.0)) }}
}}"
).unwrap();

// Save it!
File::create(out_path("target-triples.rs")).and_then(|mut f| {
use std::io::Write;
f.write_all(out.as_bytes()).and_then(|_| f.flush())
})
.expect("Unable to save target-triples.rs");
}

/// # Output Path.
///
/// Append the sub-path to OUT_DIR and return it.
Expand Down
4 changes: 3 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export RUSTFLAGS := "-C target-cpu=x86-64-v3"
# Build Debian package!
@build-deb: clean build
# Do completions/man.
{{ cargo_bin }} -m "{{ justfile_directory() }}/Cargo.toml"
{{ cargo_bin }} \
-m "{{ justfile_directory() }}/Cargo.toml" \
-t x86_64-unknown-linux-gnu

# cargo-deb doesn't support target_dir flags yet.
[ ! -d "{{ justfile_directory() }}/target" ] || rm -rf "{{ justfile_directory() }}/target"
Expand Down
5 changes: 5 additions & 0 deletions release/completions/cargo-bashman.bash
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ _basher___cargo_bashman() {
[[ " ${COMP_LINE} " =~ " --no-bash " ]] || opts+=("--no-bash")
[[ " ${COMP_LINE} " =~ " --no-credits " ]] || opts+=("--no-credits")
[[ " ${COMP_LINE} " =~ " --no-man " ]] || opts+=("--no-man")
[[ " ${COMP_LINE} " =~ " --print-targets " ]] || opts+=("--print-targets")
if [[ ! " ${COMP_LINE} " =~ " -V " ]] && [[ ! " ${COMP_LINE} " =~ " --version " ]]; then
opts+=("-V")
opts+=("--version")
Expand All @@ -19,6 +20,10 @@ _basher___cargo_bashman() {
opts+=("-m")
opts+=("--manifest-path")
fi
if [[ ! " ${COMP_LINE} " =~ " -t " ]] && [[ ! " ${COMP_LINE} " =~ " --target " ]]; then
opts+=("-t")
opts+=("--target")
fi
opts=" ${opts[@]} "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
Expand Down
Loading

0 comments on commit 8affc51

Please sign in to comment.