feat: add CLI asset generation for shell completions and man page
This commit is contained in:
Generated
+27
@@ -226,6 +226,15 @@ dependencies = [
|
|||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_complete"
|
||||||
|
version = "4.5.66"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c757a3b7e39161a4e56f9365141ada2a6c915a8622c408ab6bb4b5d047371031"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.55"
|
version = "4.5.55"
|
||||||
@@ -244,6 +253,16 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_mangen"
|
||||||
|
version = "0.2.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ea63a92086df93893164221ad4f24142086d535b3a0957b9b9bea2dc86301"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"roff",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -369,6 +388,8 @@ dependencies = [
|
|||||||
"ar",
|
"ar",
|
||||||
"bzip2",
|
"bzip2",
|
||||||
"clap",
|
"clap",
|
||||||
|
"clap_complete",
|
||||||
|
"clap_mangen",
|
||||||
"fd-lock",
|
"fd-lock",
|
||||||
"filetime",
|
"filetime",
|
||||||
"flate2",
|
"flate2",
|
||||||
@@ -1608,6 +1629,12 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "roff"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rpassword"
|
name = "rpassword"
|
||||||
version = "7.4.0"
|
version = "7.4.0"
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ petgraph = "0.8.3"
|
|||||||
fd-lock = "4.0.4"
|
fd-lock = "4.0.4"
|
||||||
reqwest = { version = "0.13.2", default-features = false, features = ["blocking", "native-tls"] }
|
reqwest = { version = "0.13.2", default-features = false, features = ["blocking", "native-tls"] }
|
||||||
filetime = "0.2.27"
|
filetime = "0.2.27"
|
||||||
|
clap_complete = "4.5.66"
|
||||||
|
clap_mangen = "0.2.31"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "=3.25.0"
|
tempfile = "=3.25.0"
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ Depot is a source-based package manager designed for Linux. It focuses on reprod
|
|||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
When installing via Meson (`meson install`), Depot now generates and installs:
|
||||||
|
- Shell completions for Bash, Zsh, and Fish
|
||||||
|
- A `depot(1)` man page
|
||||||
|
|
||||||
### Installing a Package
|
### Installing a Package
|
||||||
|
|
||||||
To install a package from a spec file:
|
To install a package from a spec file:
|
||||||
|
|||||||
+10
@@ -125,3 +125,13 @@ install_data(
|
|||||||
'contrib/README.md',
|
'contrib/README.md',
|
||||||
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
|
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
meson.add_install_script(
|
||||||
|
sh,
|
||||||
|
join_paths(src_root, 'tools', 'meson', 'install-cli-assets.sh'),
|
||||||
|
join_paths(build_root, 'depot'),
|
||||||
|
join_paths(get_option('datadir'), 'bash-completion', 'completions'),
|
||||||
|
join_paths(get_option('datadir'), 'zsh', 'site-functions'),
|
||||||
|
join_paths(get_option('datadir'), 'fish', 'vendor_completions.d'),
|
||||||
|
join_paths(get_option('mandir'), 'man1'),
|
||||||
|
)
|
||||||
|
|||||||
@@ -112,6 +112,13 @@ pub enum Commands {
|
|||||||
},
|
},
|
||||||
/// Show current configuration
|
/// Show current configuration
|
||||||
Config,
|
Config,
|
||||||
|
/// Generate shell completion scripts and a man page into an output directory.
|
||||||
|
#[command(hide = true)]
|
||||||
|
GenerateArtifacts {
|
||||||
|
/// Output directory for generated files
|
||||||
|
#[arg(long, value_name = "DIR")]
|
||||||
|
out_dir: PathBuf,
|
||||||
|
},
|
||||||
/// Create a new package specification interactively
|
/// Create a new package specification interactively
|
||||||
MakeSpec {
|
MakeSpec {
|
||||||
/// Output file path (defaults to <name>.toml)
|
/// Output file path (defaults to <name>.toml)
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
//! Generation helpers for CLI man pages and shell completions.
|
||||||
|
|
||||||
|
use crate::cli::Cli;
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use clap::CommandFactory;
|
||||||
|
use clap_complete::Shell;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
const BIN_NAME: &str = "depot";
|
||||||
|
|
||||||
|
/// Generate all supported shell completion scripts and a man page into `out_dir`.
|
||||||
|
pub fn generate_cli_assets(out_dir: &Path) -> Result<()> {
|
||||||
|
fs::create_dir_all(out_dir)
|
||||||
|
.with_context(|| format!("Failed to create output directory {}", out_dir.display()))?;
|
||||||
|
|
||||||
|
generate_completion(out_dir, Shell::Bash, "depot.bash")?;
|
||||||
|
generate_completion(out_dir, Shell::Zsh, "_depot")?;
|
||||||
|
generate_completion(out_dir, Shell::Fish, "depot.fish")?;
|
||||||
|
generate_man_page(out_dir, "depot.1")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_for_generation() -> clap::Command {
|
||||||
|
Cli::command().name(BIN_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_completion(out_dir: &Path, shell: Shell, filename: &str) -> Result<()> {
|
||||||
|
let mut command = command_for_generation();
|
||||||
|
let output_path = out_dir.join(filename);
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
clap_complete::generate(shell, &mut command, BIN_NAME, &mut buffer);
|
||||||
|
fs::write(&output_path, buffer).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"Failed to write {} completion to {}",
|
||||||
|
shell,
|
||||||
|
output_path.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_man_page(out_dir: &Path, filename: &str) -> Result<()> {
|
||||||
|
let output_path = out_dir.join(filename);
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
clap_mangen::Man::new(command_for_generation())
|
||||||
|
.render(&mut buffer)
|
||||||
|
.context("Failed to render clap man page")?;
|
||||||
|
fs::write(&output_path, buffer)
|
||||||
|
.with_context(|| format!("Failed to write man page {}", output_path.display()))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generate_cli_assets_writes_expected_files() {
|
||||||
|
let temp = tempfile::tempdir().unwrap();
|
||||||
|
generate_cli_assets(temp.path()).unwrap();
|
||||||
|
|
||||||
|
let bash = temp.path().join("depot.bash");
|
||||||
|
let zsh = temp.path().join("_depot");
|
||||||
|
let fish = temp.path().join("depot.fish");
|
||||||
|
let man = temp.path().join("depot.1");
|
||||||
|
|
||||||
|
assert!(bash.exists());
|
||||||
|
assert!(zsh.exists());
|
||||||
|
assert!(fish.exists());
|
||||||
|
assert!(man.exists());
|
||||||
|
assert!(!std::fs::read_to_string(&man).unwrap().is_empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-2
@@ -1,7 +1,7 @@
|
|||||||
use crate::cli::{Cli, Commands, RepoCommands, RepoKindArg};
|
use crate::cli::{Cli, Commands, RepoCommands, RepoKindArg};
|
||||||
use crate::{
|
use crate::{
|
||||||
builder, config, cross, db, deps, index, install, locking, package, planner, signing, source,
|
builder, cli_assets, config, cross, db, deps, index, install, locking, package, planner,
|
||||||
staging, ui,
|
signing, source, staging, ui,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -1949,6 +1949,10 @@ pub fn run(cli: Cli) -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Commands::GenerateArtifacts { out_dir } => {
|
||||||
|
cli_assets::generate_cli_assets(&out_dir)?;
|
||||||
|
ui::success(format!("Generated CLI assets in {}", out_dir.display()));
|
||||||
|
}
|
||||||
Commands::Config => {
|
Commands::Config => {
|
||||||
let config = config::Config::for_rootfs(&cli.rootfs);
|
let config = config::Config::for_rootfs(&cli.rootfs);
|
||||||
let config_lock = locking::open_lock(&config)?;
|
let config_lock = locking::open_lock(&config)?;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
mod cli;
|
mod cli;
|
||||||
|
mod cli_assets;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod config;
|
mod config;
|
||||||
mod cross;
|
mod cross;
|
||||||
|
|||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "$#" -ne 5 ]; then
|
||||||
|
echo "usage: $0 <depot-bin> <bash-dir> <zsh-dir> <fish-dir> <man1-dir>" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
depot_bin="$1"
|
||||||
|
bash_dir="$2"
|
||||||
|
zsh_dir="$3"
|
||||||
|
fish_dir="$4"
|
||||||
|
man1_dir="$5"
|
||||||
|
|
||||||
|
if [ ! -x "$depot_bin" ]; then
|
||||||
|
echo "error: depot binary is not executable: $depot_bin" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${MESON_INSTALL_DESTDIR_PREFIX:-}" ]; then
|
||||||
|
echo "error: MESON_INSTALL_DESTDIR_PREFIX is not set" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
resolve_dest() {
|
||||||
|
case "$1" in
|
||||||
|
/*) printf '%s%s\n' "${DESTDIR:-}" "$1" ;;
|
||||||
|
*) printf '%s/%s\n' "$MESON_INSTALL_DESTDIR_PREFIX" "$1" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmpdir"' EXIT
|
||||||
|
|
||||||
|
"$depot_bin" generate-artifacts --out-dir "$tmpdir"
|
||||||
|
|
||||||
|
bash_dest="$(resolve_dest "$bash_dir")"
|
||||||
|
zsh_dest="$(resolve_dest "$zsh_dir")"
|
||||||
|
fish_dest="$(resolve_dest "$fish_dir")"
|
||||||
|
man_dest="$(resolve_dest "$man1_dir")"
|
||||||
|
|
||||||
|
mkdir -p "$bash_dest" "$zsh_dest" "$fish_dest" "$man_dest"
|
||||||
|
cp "$tmpdir/depot.bash" "$bash_dest/depot"
|
||||||
|
cp "$tmpdir/_depot" "$zsh_dest/_depot"
|
||||||
|
cp "$tmpdir/depot.fish" "$fish_dest/depot.fish"
|
||||||
|
cp "$tmpdir/depot.1" "$man_dest/depot.1"
|
||||||
Reference in New Issue
Block a user