mirror of
https://seed.radicle.dev/rad:z39mP9rQAaGmERfUMPULfPUi473tY.git
synced 2026-10-18 19:10:36 +08:00
bin: Print version as json
This commit is contained in:
+16
-5
@@ -3,19 +3,27 @@ mod terminal;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::{iter, process};
|
||||
|
||||
use anyhow::anyhow;
|
||||
|
||||
use radicle::version;
|
||||
use radicle::version::Version;
|
||||
use radicle_term as term;
|
||||
|
||||
use commands::*;
|
||||
|
||||
pub const NAME: &str = "rad-tui";
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const DESCRIPTION: &str = "Radicle terminal interfaces";
|
||||
pub const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const GIT_HEAD: &str = env!("GIT_HEAD");
|
||||
pub const TIMESTAMP: &str = env!("GIT_COMMIT_TIME");
|
||||
pub const VERSION: Version = Version {
|
||||
name: NAME,
|
||||
version: PKG_VERSION,
|
||||
commit: GIT_HEAD,
|
||||
timestamp: TIMESTAMP,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Command {
|
||||
@@ -65,18 +73,21 @@ fn parse_args() -> anyhow::Result<Command> {
|
||||
}
|
||||
|
||||
fn print_help() -> anyhow::Result<()> {
|
||||
version::print(&mut io::stdout(), NAME, VERSION, GIT_HEAD)?;
|
||||
VERSION.write(&mut io::stdout())?;
|
||||
println!("{DESCRIPTION}");
|
||||
println!();
|
||||
|
||||
tui_help::run(Default::default(), terminal::profile)
|
||||
tui_help::run(Default::default(), terminal::DefaultContext)
|
||||
}
|
||||
|
||||
fn run(command: Command) -> Result<(), Option<anyhow::Error>> {
|
||||
match command {
|
||||
Command::Version => {
|
||||
version::print(&mut io::stdout(), NAME, VERSION, GIT_HEAD)
|
||||
let mut stdout = io::stdout();
|
||||
VERSION
|
||||
.write_json(&mut stdout)
|
||||
.map_err(|e| Some(e.into()))?;
|
||||
writeln!(&mut stdout).ok();
|
||||
}
|
||||
Command::Help => {
|
||||
print_help()?;
|
||||
|
||||
+26
-8
@@ -8,26 +8,44 @@ pub use args::{Args, Error, Help};
|
||||
|
||||
use radicle_term as term;
|
||||
|
||||
use radicle::profile::Profile;
|
||||
use radicle::profile::{Home, Profile};
|
||||
|
||||
/// Context passed to all commands.
|
||||
pub trait Context {
|
||||
/// Return the currently active profile, or an error if no profile is active.
|
||||
fn profile(&self) -> Result<Profile, anyhow::Error>;
|
||||
/// Return the Radicle home.
|
||||
fn home(&self) -> Result<Home, std::io::Error>;
|
||||
}
|
||||
|
||||
impl Context for Profile {
|
||||
fn profile(&self) -> Result<Profile, anyhow::Error> {
|
||||
Ok(self.clone())
|
||||
}
|
||||
|
||||
fn home(&self) -> Result<Home, std::io::Error> {
|
||||
Ok(self.home.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Context for F
|
||||
where
|
||||
F: Fn() -> Result<Profile, anyhow::Error>,
|
||||
{
|
||||
pub struct DefaultContext;
|
||||
|
||||
impl Context for DefaultContext {
|
||||
fn home(&self) -> Result<Home, std::io::Error> {
|
||||
radicle::profile::home()
|
||||
}
|
||||
|
||||
fn profile(&self) -> Result<Profile, anyhow::Error> {
|
||||
self()
|
||||
match Profile::load() {
|
||||
Ok(profile) => Ok(profile),
|
||||
Err(radicle::profile::Error::NotFound(path)) => Err(args::Error::WithHint {
|
||||
err: anyhow::anyhow!("Radicle profile not found in '{}'.", path.display()),
|
||||
hint: "To setup your radicle profile, run `rad auth`.",
|
||||
}
|
||||
.into()),
|
||||
Err(radicle::profile::Error::Config(e)) => Err(e.into()),
|
||||
Err(e) => Err(anyhow::anyhow!("Could not load radicle profile: {e}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +67,7 @@ where
|
||||
pub fn run_command_args<A, C>(help: Help, cmd: C, args: Vec<OsString>) -> !
|
||||
where
|
||||
A: Args,
|
||||
C: Command<A, fn() -> anyhow::Result<Profile>>,
|
||||
C: Command<A, DefaultContext>,
|
||||
{
|
||||
let options = match A::from_args(args) {
|
||||
Ok((opts, unparsed)) => {
|
||||
@@ -88,7 +106,7 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
match cmd.run(options, self::profile) {
|
||||
match cmd.run(options, DefaultContext) {
|
||||
Ok(()) => process::exit(0),
|
||||
Err(err) => {
|
||||
fail(help.name, &err);
|
||||
|
||||
@@ -18,6 +18,23 @@ fn main() {
|
||||
})
|
||||
.unwrap_or_else(|| String::from("unknown"));
|
||||
|
||||
// Set a build-time `GIT_COMMIT_TIME` env var which includes the commit time.
|
||||
let commit_time = Command::new("git")
|
||||
.arg("show")
|
||||
.arg("--format=%ct")
|
||||
.arg("HEAD")
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|output| {
|
||||
if output.status.success() {
|
||||
String::from_utf8(output.stdout).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or(0.to_string());
|
||||
|
||||
println!("cargo:rustc-env=GIT_COMMIT_TIME={commit_time}");
|
||||
println!("cargo:rustc-env=GIT_HEAD={hash}");
|
||||
println!("cargo:rustc-rerun-if-changed=.git/HEAD");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user