Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cargo-shuttle): generate manpage #1388

Merged
merged 10 commits into from
Dec 6, 2023
Merged
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cargo-shuttle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ cargo_metadata = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["env"] }
clap_complete = "4.3.1"
clap_mangen = "0.2.15"
crossterm = { workspace = true }
dialoguer = { version = "0.11.0", features = ["fuzzy-select"] }
dirs = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion cargo-shuttle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Commands:
clean Remove cargo build artifacts in the shuttle environment
login Login to the shuttle platform
logout Log out of the shuttle platform
generate Generate shell completions
generate Generate shell completions and manpage
feedback Open an issue on GitHub and provide feedback
help Print this message or the help of the given subcommand(s)

Expand Down
9 changes: 6 additions & 3 deletions cargo-shuttle/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,17 @@ pub enum Command {
Login(LoginArgs),
/// Log out of the Shuttle platform
Logout(LogoutArgs),
/// Generate shell completions
/// Generate shell completions and manpage
jonaro00 marked this conversation as resolved.
Show resolved Hide resolved
Generate {
/// Which shell
#[arg(short, long, env, default_value_t = Shell::Bash)]
shell: Shell,
#[arg(short, long)]
shell: Option<Shell>,
/// Output to a file (stdout by default)
#[arg(short, long, env)]
output: Option<PathBuf>,
/// Generate manpage to the standard output
#[arg(short, long)]
manpage: bool,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since they are mutually exclusive, it feels cleaner if they were separate subcommands: cargo shuttle generate shell <SHELL> and cargo shuttle generate manpage. Although a breaking change, could this be acceptable? @oddgrd

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OUTPUT env var usage feels weird as well. Could be a risk of collision with other programs using it. How do we feel about it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah using OUTPUT is a bit risky. OTOH although the subcommand approach might look cleaner it would add unnecessary complexity to the code IMO. But I'm fine with either way - and I would say let's have this ready soon and not get caught up into discussion too much 🐻

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since they are mutually exclusive, it feels cleaner if they were separate subcommands: cargo shuttle generate shell <SHELL> and cargo shuttle generate manpage. Although a breaking change, could this be acceptable?

I think having them as separate subcommands makes the most sense. Regarding the output arg, we could remove the env. That makes two breaking changes, but I doubt it will affect many (if any) users.

},
/// Open an issue on GitHub and provide feedback
Feedback,
Expand Down
36 changes: 31 additions & 5 deletions cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::path::{Path, PathBuf};
use std::process::exit;
use std::str::FromStr;

use clap_mangen::Man;

use shuttle_common::{
claims::{ClaimService, InjectPropagation},
constants::{
Expand Down Expand Up @@ -205,7 +207,11 @@ impl Shuttle {
self.init(init_args, args.project_args, provided_path_to_init)
.await
}
Command::Generate { shell, output } => self.complete(shell, output),
Command::Generate {
shell,
output,
manpage,
} => self.complete(shell, output, manpage),
Command::Login(login_args) => self.login(login_args).await,
Command::Logout(logout_args) => self.logout(logout_args).await,
Command::Feedback => self.feedback(),
Expand Down Expand Up @@ -615,13 +621,24 @@ impl Shuttle {
Ok(CommandOutcome::Ok)
}

fn complete(&self, shell: Shell, output: Option<PathBuf>) -> Result<CommandOutcome> {
fn complete(
&self,
shell: Option<Shell>,
output: Option<PathBuf>,
manpage: bool,
) -> Result<CommandOutcome> {
let name = env!("CARGO_PKG_NAME");
let mut app = Command::command();
match output {
Some(v) => generate(shell, &mut app, name, &mut File::create(v)?),
None => generate(shell, &mut app, name, &mut stdout()),
match (shell, output) {
(Some(shell), Some(output)) => {
generate(shell, &mut app, name, &mut File::create(output)?)
}
(Some(shell), None) => generate(shell, &mut app, name, &mut stdout()),
(None, _) => {}
};
if manpage {
generate_manpage()?;
}

Ok(CommandOutcome::Ok)
}
Expand Down Expand Up @@ -1981,6 +1998,15 @@ impl Shuttle {
}
}

fn generate_manpage() -> Result<(), std::io::Error> {
let app = ShuttleArgs::command();
let output = std::io::stdout();
let mut output_handle = output.lock();
Man::new(app).render(&mut output_handle)?;

Ok(())
}

fn is_dirty(repo: &Repository) -> Result<()> {
let mut status_options = StatusOptions::new();
status_options.include_untracked(true);
Expand Down