use anyhow::Result;
use async_fs_io::{
metadata,
try_exists,
};
use cargo_version_info::commands;
use cargo_version_info::commands::{
BadgeArgs,
BuildVersionArgs,
BumpArgs,
ChangedArgs,
ChangelogArgs,
CompareArgs,
CurrentArgs,
DevArgs,
DioxusArgs,
LatestArgs,
NextArgs,
PostBumpHookArgs,
PrLogArgs,
PreBumpHookArgs,
ReleasePageArgs,
RustToolchainArgs,
TagArgs,
UpdateReadmeArgs,
};
use clap::{
ArgAction,
CommandFactory,
Parser,
Subcommand,
};
#[derive(Parser, Debug)]
#[command(
bin_name = "cargo",
disable_version_flag = true,
arg_required_else_help = false
)]
struct CargoArgs {
#[arg(long = "tool-version", short = 'T', global = true)]
tool_version_flag: bool,
#[command(subcommand)]
subcmd: Option<TopCommand>,
}
#[derive(Subcommand, Debug)]
enum TopCommand {
#[command(name = "version-info")]
VersionInfo(VersionInfoCli),
}
#[derive(Parser, Debug)]
#[command(
disable_version_flag = true,
subcommand_required = false,
arg_required_else_help = false
)]
struct VersionInfoCli {
#[arg(long = "version", short = 'V', action = ArgAction::SetTrue)]
version_flag: bool,
#[command(subcommand)]
command: Option<VersionInfoCommand>,
}
#[derive(Parser, Debug)]
enum VersionInfoCommand {
#[command(name = "next")]
Next(NextArgs),
#[command(name = "current")]
Current(CurrentArgs),
#[command(name = "latest")]
Latest(LatestArgs),
#[command(name = "dev")]
Dev(DevArgs),
#[command(name = "tag")]
Tag(TagArgs),
#[command(name = "compare")]
Compare(CompareArgs),
#[command(name = "rust-toolchain")]
RustToolchain(RustToolchainArgs),
#[command(name = "dioxus")]
Dioxus(DioxusArgs),
#[command(name = "build-version")]
BuildVersion(BuildVersionArgs),
#[command(name = "changed")]
Changed(ChangedArgs),
#[command(name = "bump")]
Bump(BumpArgs),
#[command(name = "pre-bump-hook")]
PreBumpHook(PreBumpHookArgs),
#[command(name = "post-bump-hook")]
PostBumpHook(PostBumpHookArgs),
#[command(name = "changelog")]
Changelog(ChangelogArgs),
#[command(name = "pr-log")]
PrLog(PrLogArgs),
#[command(name = "release-page")]
ReleasePage(ReleasePageArgs),
#[command(name = "badge")]
Badge(BadgeArgs),
#[command(name = "update-readme")]
UpdateReadme(UpdateReadmeArgs),
#[command(name = "version")]
Version,
}
async fn has_env_files() -> anyhow::Result<bool> {
let current_dir = match std::env::current_dir() {
Ok(dir) => dir,
Err(error) => return Err(error.into()),
};
let patterns = [".env", ".env.local", ".env.prod", ".env.dev", ".env.test"];
for pattern in &patterns {
let path = current_dir.join(pattern);
if try_exists(&path).await? && !metadata(&path).await?.is_directory {
return Ok(true);
}
}
if let Ok(user) = std::env::var("USER") {
let user_env = format!(".env.{}", user);
let path = current_dir.join(user_env);
if try_exists(&path).await? && !metadata(&path).await?.is_directory {
return Ok(true);
}
}
Ok(false)
}
#[tokio::main]
async fn main() -> Result<()> {
let args = CargoArgs::parse();
if args.tool_version_flag {
println!("cargo-version-info {}", env!("CARGO_PKG_VERSION"));
return Ok(());
}
if has_env_files().await? {
dotenvage::EnvLoader::new()?.load()?;
}
if let Some(TopCommand::VersionInfo(cli)) = args.subcmd {
if cli.version_flag {
return commands::build_version_default().await;
}
if let Some(command) = cli.command {
return match command {
VersionInfoCommand::Next(args) => commands::next(args).await,
VersionInfoCommand::Current(args) => commands::current(args).await,
VersionInfoCommand::Latest(args) => commands::latest(args).await,
VersionInfoCommand::Dev(args) => commands::dev(args).await,
VersionInfoCommand::Tag(args) => commands::tag(args).await,
VersionInfoCommand::Compare(args) => commands::compare(args).await,
VersionInfoCommand::RustToolchain(args) => commands::rust_toolchain(args).await,
VersionInfoCommand::Dioxus(args) => commands::dioxus(args).await,
VersionInfoCommand::BuildVersion(args) => commands::build_version(args).await,
VersionInfoCommand::Changed(args) => commands::changed(args).await,
VersionInfoCommand::Bump(args) => commands::bump(args).await,
VersionInfoCommand::PreBumpHook(args) => commands::pre_bump_hook(args).await,
VersionInfoCommand::PostBumpHook(args) => commands::post_bump_hook(args).await,
VersionInfoCommand::Changelog(args) => commands::changelog(args).await,
VersionInfoCommand::PrLog(args) => commands::pr_log(args).await,
VersionInfoCommand::ReleasePage(args) => commands::release_page(args).await,
VersionInfoCommand::Badge(args) => commands::badge(args).await,
VersionInfoCommand::UpdateReadme(args) => commands::update_readme(args).await,
VersionInfoCommand::Version => commands::build_version_default().await,
};
}
VersionInfoCli::command().print_help()?;
println!();
return Ok(());
}
CargoArgs::command().print_help()?;
println!();
Ok(())
}