use crate::error::Error;
use crate::project::manifest::{Environment, Manifest, split_package_name};
use crate::registry::pack;
use crate::ui;
use clap::Args;
use std::path::Path;
#[derive(Args, Debug)]
pub struct PublishArgs {
#[arg(long)]
pub dry_run: bool,
#[arg(short, long)]
pub index: Option<String>,
}
pub fn run(args: PublishArgs) -> Result<(), Error> {
let manifest = Manifest::load()?;
let environment = publish_environment(&manifest)?;
let (scope, name) = split_package_name(&manifest.package.name)?;
let version = semver::Version::parse(&manifest.package.version)?;
let root = Path::new(".");
let files = pack::packed_files(root, &manifest)?;
let archive = ui::with_spinner("Packing package", || pack::pack(root, &manifest))?;
let asset_name = format!("{scope}_{name}-{version}.tar.gz");
if args.dry_run {
println!(
"Would publish {}@{version} ({environment}) as:",
manifest.package.name
);
println!(" {asset_name} ({} bytes)", archive.len());
for file in &files {
println!(" {}", file.display());
}
if let Some(index) = &args.index {
println!("Target index: {index}");
}
return Ok(());
}
Err(Error::PublishUnavailable)
}
fn publish_environment(manifest: &Manifest) -> Result<Environment, Error> {
manifest
.target
.as_ref()
.map(|target| target.environment)
.ok_or_else(|| {
Error::ManifestInvalid(
"publishing requires a [target] section with an environment".to_string(),
)
})
}