gh_workflow_parser/
config.rs1use crate::gh::gh_cli;
3use crate::util::check_gh_cli_version;
4
5use super::commands::Command;
6use clap::builder::styling::{AnsiColor, Effects, Styles};
7use clap::*;
8use std::error::Error;
9use which::which;
10
11pub const GH_CLI_MIN_VERSION: semver::Version = semver::Version::new(2, 43, 1);
13
14#[derive(Parser, Debug)]
15#[command(version, about = "Parse GitHub CI workflows", author, styles = config_styles())]
16pub struct Config {
17 #[command(subcommand)]
18 command: Option<Command>,
19 #[arg(long, default_value_t = false, global = true)]
21 dry_run: bool,
22 #[arg(long, default_value_t = false, global = true)]
24 fake_github_cli: bool,
25 #[arg(short, long, global = true, default_value_t = 2)]
27 verbosity: u8,
28 #[arg(long, global = true, value_hint = ValueHint::Other, name = "SHELL")]
30 completions: Option<clap_complete::Shell>,
31}
32
33impl Config {
34 pub fn dry_run(&self) -> bool {
36 self.dry_run
37 }
38
39 pub fn fake_github_cli(&self) -> bool {
41 self.fake_github_cli
42 }
43
44 pub fn subcmd(&self) -> &Command {
46 if self.command.is_none() {
47 log::error!("Subcommand required! use `--help` for more information");
48 std::process::exit(1);
49 }
50 self.command.as_ref().expect("Subcommand not set")
51 }
52
53 pub fn verbosity(&self) -> u8 {
55 self.verbosity
56 }
57
58 pub fn generate_completion_script(&self) -> bool {
59 match self.completions {
60 Some(shell) => {
61 generate_completion_script(shell);
62 true
63 },
64 None => false,
65 }
66 }
67}
68
69pub fn init() -> Result<Config, Box<dyn Error>> {
71 let config = Config::parse();
72 use stderrlog::LogLevelNum;
73 let log_level = match config.verbosity() {
74 0 => LogLevelNum::Error,
75 1 => LogLevelNum::Warn,
76 2 => LogLevelNum::Info,
77 3 => LogLevelNum::Debug,
78 4 => LogLevelNum::Trace,
79 _ => {
80 eprintln!("Invalid verbosity level: {}", config.verbosity());
81 eprintln!("Using highest verbosity level: Trace");
82 LogLevelNum::Trace
83 },
84 };
85 stderrlog::new().verbosity(log_level).quiet(false).init()?;
86 if config.dry_run() {
87 log::warn!("Running in dry-run mode. No writes/changes will be made");
88 }
89
90 if let Err(e) = which(gh_cli()) {
92 log::error!("GitHub CLI not found: {e}");
93 std::process::exit(1);
94 }
95 check_gh_cli_version(GH_CLI_MIN_VERSION)?;
96
97 Ok(config)
98}
99
100fn config_styles() -> Styles {
102 Styles::styled()
103 .header(AnsiColor::Red.on_default() | Effects::BOLD)
104 .usage(AnsiColor::Yellow.on_default() | Effects::BOLD)
105 .literal(AnsiColor::Green.on_default() | Effects::BOLD)
106 .placeholder(AnsiColor::Blue.on_default())
107}
108
109fn generate_completion_script(shell: clap_complete::Shell) {
111 log::info!("Generating completion script for {shell:?}");
112 clap_complete::generate(
113 shell,
114 &mut <Config as clap::CommandFactory>::command(),
115 "gh-workflow-parser",
116 &mut std::io::stdout(),
117 );
118}