use anyhow::Result;
use std::path::PathBuf;
use crate::{ci_patcher, commands::generate::Generate};
pub const DEFAULT_DOCKER_ORB_VERSION: &str = "3.0.1";
pub const DEFAULT_GEN_ORB_MCP_ORB_VERSION: &str = "0.1.14";
#[derive(Debug, clap::Args)]
pub struct Init {
#[arg(long)]
pub binary: String,
#[arg(long = "public-orb-namespace")]
pub public_orb_namespaces: Vec<String>,
#[arg(long = "private-orb-namespace")]
pub private_orb_namespaces: Vec<String>,
#[arg(long)]
pub build_workflow: String,
#[arg(long)]
pub release_workflow: String,
#[arg(long)]
pub requires_job: Option<String>,
#[arg(long)]
pub crate_tag_prefix: String,
#[arg(long)]
pub release_after_job: String,
#[arg(long, default_value = "orb")]
pub orb_dir: String,
#[arg(long, default_value = ".circleci")]
pub ci_dir: PathBuf,
#[arg(long, default_value = "12.3.3")]
pub orb_tools_version: String,
#[arg(long, default_value = DEFAULT_DOCKER_ORB_VERSION)]
pub docker_orb_version: String,
#[arg(long)]
pub docker_namespace: String,
#[arg(long, default_value = "docker-credentials")]
pub docker_context: String,
#[arg(long, default_value = "orb-publishing")]
pub orb_context: String,
#[arg(long, default_value = env!("CARGO_PKG_VERSION"))]
pub gen_circleci_orb_version: String,
#[arg(long)]
pub mcp: bool,
#[arg(long, default_value = DEFAULT_GEN_ORB_MCP_ORB_VERSION)]
pub gen_orb_mcp_version: String,
#[arg(long, default_value = "pcu-app")]
pub mcp_context: String,
#[arg(long)]
pub dry_run: bool,
}
impl Init {
pub fn run(&self) -> Result<()> {
let namespaces: Vec<String> = self
.public_orb_namespaces
.iter()
.chain(self.private_orb_namespaces.iter())
.cloned()
.collect();
tracing::info!("Generating orb source into ./{}", self.orb_dir);
let gen = Generate {
binary: self.binary.clone(),
namespaces: namespaces.clone(),
output: PathBuf::from("."),
orb_dir: self.orb_dir.clone(),
install_method: crate::commands::generate::InstallMethod::Binstall,
base_image: crate::commands::generate::DEFAULT_BASE_IMAGE.to_string(),
home_url: None,
source_url: None,
git_push_subcommands: vec![],
dry_run: self.dry_run,
};
gen.run()?;
let opts = ci_patcher::PatchOpts {
binary: self.binary.clone(),
namespaces,
docker_namespace: self.docker_namespace.clone(),
orb_dir: self.orb_dir.clone(),
build_workflow: self.build_workflow.clone(),
release_workflow: self.release_workflow.clone(),
requires_job: self.requires_job.clone(),
crate_tag_prefix: self.crate_tag_prefix.clone(),
release_after_job: self.release_after_job.clone(),
orb_tools_version: self.orb_tools_version.clone(),
docker_orb_version: self.docker_orb_version.clone(),
docker_context: self.docker_context.clone(),
orb_context: self.orb_context.clone(),
private_namespaces: self.private_orb_namespaces.clone(),
gen_circleci_orb_version: self.gen_circleci_orb_version.clone(),
mcp: self.mcp,
gen_orb_mcp_version: self.gen_orb_mcp_version.clone(),
mcp_context: self.mcp_context.clone(),
};
let summary = ci_patcher::apply_patches(&self.ci_dir, &opts, self.dry_run)?;
for line in &summary {
println!("{line}");
}
if self.dry_run {
println!("(dry-run: no files written)");
} else {
println!("Done.");
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::DEFAULT_DOCKER_ORB_VERSION;
#[test]
fn default_docker_orb_version_matches_registry() {
assert_eq!(
DEFAULT_DOCKER_ORB_VERSION, "3.0.1",
"DEFAULT_DOCKER_ORB_VERSION must be the registry-available version"
);
}
}