use breezyshim::controldir::open;
use breezyshim::error::Error;
use breezyshim::prelude::*;
use breezyshim::workingtree;
use clap::Parser;
use debian_workbench::publish::{create_vcs_url, update_official_vcs};
use debian_changelog::get_maintainer;
use debian_workbench::get_committer;
use std::io::Write as _;
#[derive(clap::Args, Clone, Debug)]
#[group()]
struct OutputArgs {}
#[derive(Parser, Debug)]
#[command(author, version)]
struct Args {
#[arg(long, default_value_t = false)]
debug: bool,
#[arg(long, default_value_t = false)]
identity: bool,
#[arg(short, long, default_value = std::env::current_dir().unwrap().into_os_string(), value_name = "DIR")]
directory: std::path::PathBuf,
#[arg(default_value_t = false)]
no_create: bool,
#[arg(default_value_t = false)]
force: bool,
#[arg(default_value_t = false)]
push: bool,
url: Option<url::Url>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
env_logger::builder()
.format(|buf, record| writeln!(buf, "{}", record.args()))
.filter(
None,
if args.debug {
log::LevelFilter::Debug
} else {
log::LevelFilter::Info
},
)
.init();
breezyshim::init();
let (wt, subpath) = match workingtree::open_containing(&args.directory) {
Ok((wt, subpath)) => (wt, subpath.display().to_string()),
Err(Error::NotBranchError(_msg, _)) => {
log::error!("No version control directory found (e.g. a .git directory).");
std::process::exit(1);
}
Err(Error::DependencyNotPresent(name, _reason)) => {
log::error!(
"Unable to open tree at {}: missing package {}",
args.directory.display(),
name
);
std::process::exit(1);
}
Err(e) => {
log::error!("Unable to open tree at {}: {}", args.directory.display(), e);
std::process::exit(1);
}
};
if args.identity {
println!("Committer identity: {}", get_committer(&wt));
let (maintainer, email) = get_maintainer().unwrap_or(("".to_string(), "".to_string()));
println!("Changelog identity: {} <{}>", maintainer, email);
std::process::exit(0);
}
let parsed_vcs = match update_official_vcs(
&wt,
std::path::Path::new(subpath.as_str()),
args.url.as_ref(),
None,
None,
Some(args.force),
) {
Ok(o) => o,
Err(e) => {
log::error!("Unable to update official VCS: {}", e);
std::process::exit(1);
}
};
let repo_url: url::Url = parsed_vcs.repo_url.parse().unwrap();
if !args.no_create {
match create_vcs_url(&repo_url, parsed_vcs.branch.as_deref()) {
Ok(()) => {}
Err(Error::UnsupportedForge(_)) => {
log::error!("Unable to find a way to create {}", repo_url);
}
Err(Error::ForgeProjectExists(..)) | Err(Error::AlreadyControlDir(..)) => {
log::error!("Unable to create {}: already exists", repo_url);
std::process::exit(1);
}
Err(Error::ForgeLoginRequired) => {
log::error!("Unable to create {}: login required", repo_url);
std::process::exit(1);
}
Err(e) => {
log::error!("Unable to create {}: {}", repo_url, e);
std::process::exit(1);
}
}
}
let controldir = open(&repo_url, None).unwrap();
let branch = match controldir.open_branch(parsed_vcs.branch.as_deref()) {
Ok(branch) => branch,
Err(Error::NotBranchError(_, _)) => controldir
.create_branch(parsed_vcs.branch.as_deref())
.unwrap(),
Err(e) => {
log::error!("Unable to open or create branch: {}", e);
std::process::exit(1);
}
};
wt.branch()
.push(branch.as_ref(), false, None, None)
.unwrap();
Ok(())
}