You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.4 KiB
142 lines
4.4 KiB
use crate::action_init::{ClInit, cl_init};
|
|
use crate::action_log::cl_log;
|
|
use crate::action_pack::cl_pack;
|
|
use crate::config::{ChannelName, Config};
|
|
use anyhow::bail;
|
|
use clap::builder::NonEmptyStringValueParser;
|
|
use colored::Colorize;
|
|
use std::path::PathBuf;
|
|
use std::process::exit;
|
|
|
|
mod config;
|
|
|
|
mod git;
|
|
|
|
mod action_log;
|
|
mod action_pack;
|
|
|
|
mod action_init;
|
|
|
|
mod store;
|
|
|
|
#[derive(Debug)]
|
|
pub struct AppContext {
|
|
/// Name of the cl binary
|
|
pub binary_name: String,
|
|
|
|
/// Config loaded from file or defaults
|
|
pub config: Config,
|
|
|
|
/// Root of the project
|
|
pub root: PathBuf,
|
|
}
|
|
|
|
fn main() {
|
|
if let Err(e) = main_try() {
|
|
eprintln!("{}", format!("{:?}", e).red().bold());
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
fn main_try() -> anyhow::Result<()> {
|
|
let binary_name = std::env::current_exe()
|
|
.map(|p| p.file_name().map(|s| s.to_string_lossy().to_string()))
|
|
.ok()
|
|
.flatten()
|
|
.unwrap_or_else(|| "cl".to_string());
|
|
|
|
let args = clap::Command::new(&binary_name)
|
|
.version(env!("CARGO_PKG_VERSION"))
|
|
.author(env!("CARGO_PKG_AUTHORS"))
|
|
.about(env!("CARGO_PKG_DESCRIPTION"))
|
|
.subcommand(clap::Command::new("init")
|
|
.about("Create the changelog folder and the default config file in the current working directory, if they do not exist yet."))
|
|
.subcommand(
|
|
clap::Command::new("pack")
|
|
.visible_alias("release")
|
|
.about("Pack changelog entries to a changelog section")
|
|
.arg(clap::Arg::new("CHANNEL")
|
|
.short('x')
|
|
.long("channel")
|
|
.value_parser(NonEmptyStringValueParser::new())
|
|
.required(false)),
|
|
)
|
|
.subcommand(clap::Command::new("add")
|
|
.visible_alias("log")
|
|
.about("Add a changelog entry on the current branch"))
|
|
// .subcommand(clap::Command::new("flush")
|
|
// .about("Remove all changelog entries that were already released on all channels - clean up the changelog dir. Use e.g. when making a major release where all channel branches are merged."))
|
|
// .subcommand(clap::Command::new("status")
|
|
// .about("Show changelog entries currently waiting for release on the current channel"))
|
|
.subcommand_required(false)
|
|
.arg(clap::Arg::new("CONFIG")
|
|
.short('c')
|
|
.long("config")
|
|
.value_parser(NonEmptyStringValueParser::new())
|
|
.required(false))
|
|
.after_help(
|
|
"Call with no arguments to create a changelog entry (same as the \"add\" subcommand).",
|
|
)
|
|
.get_matches();
|
|
|
|
let specified_config_file = args.get_one::<String>("CONFIG").map(|s| s.as_str());
|
|
|
|
let config_file_name: &str = specified_config_file.unwrap_or("clpack.toml");
|
|
|
|
// eprintln!("Loading configuration from {}", config_file_name);
|
|
|
|
let Ok(root) = std::env::current_dir() else {
|
|
bail!("Failed to get current directory - is it deleted / inaccessible?");
|
|
};
|
|
|
|
let config_path = root.join(&config_file_name); // if absolute, it is replaced by it
|
|
|
|
if let Some(("init", _)) = args.subcommand() {
|
|
return cl_init(ClInit {
|
|
binary_name,
|
|
root,
|
|
config_path,
|
|
});
|
|
}
|
|
|
|
// Load and parse config
|
|
let config: Config = if let Ok(config_file_content) = std::fs::read_to_string(&config_path) {
|
|
match toml::from_str(&config_file_content) {
|
|
Ok(config) => config,
|
|
Err(e) => {
|
|
bail!(
|
|
"Failed to parse config file ({}): {}",
|
|
config_path.display(),
|
|
e
|
|
);
|
|
}
|
|
}
|
|
} else if specified_config_file.is_some() {
|
|
// Failed to load config the user specifically asked for - make it an error
|
|
bail!("Failed to load config file at {}", config_path.display());
|
|
} else {
|
|
Default::default()
|
|
};
|
|
|
|
let ctx = AppContext {
|
|
binary_name,
|
|
config,
|
|
root,
|
|
};
|
|
|
|
// eprintln!("AppCtx: {:?}", ctx);
|
|
|
|
match args.subcommand() {
|
|
Some(("pack", subargs)) => {
|
|
let channel: Option<ChannelName> = subargs.get_one("CHANNEL").cloned();
|
|
cl_pack(ctx, channel)?;
|
|
}
|
|
None | Some(("add", _)) => cl_log(ctx)?,
|
|
// TODO: status, flush
|
|
Some((other, _)) => {
|
|
bail!("Subcommand {other} is not implemented yet");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|