use clap::Args;
use eyre::{eyre, Context, OptionExt, Result};
use lux_lib::{
config::Config,
lua_rockspec::RemoteLuaRockspec,
operations::{self, VendorTarget},
workspace::Workspace,
};
use std::path::PathBuf;
#[derive(Args)]
pub struct Vendor {
vendor_dir: Option<PathBuf>,
#[arg(long)]
rockspec: Option<PathBuf>,
#[arg(long)]
no_lock: bool,
#[arg(long)]
no_delete: bool,
}
pub async fn vendor(data: Vendor, config: Config) -> Result<()> {
let target =
match data.rockspec {
Some(rockspec_path) => {
let content = tokio::fs::read_to_string(&rockspec_path).await?;
let rockspec = match rockspec_path
.extension()
.map(|ext| ext.to_string_lossy().to_string())
.unwrap_or("".into())
.as_str()
{
"rockspec" => Ok(RemoteLuaRockspec::new(&content)?),
_ => Err(eyre!(
"expected a path to a .rockspec file, but got:\n{}",
rockspec_path.display()
)),
}?;
VendorTarget::Rockspec(rockspec)
}
None => VendorTarget::Workspace(Workspace::current_or_err().context(
"`lx vendor` must be run in a workspace root or with a rockspec argument.",
)?),
};
let vendor_dir = data
.vendor_dir
.or_else(|| config.vendor_dir().cloned())
.ok_or_eyre(
r#"<vendor-dir> not set.
It must either be specified via `--vendor-dir` or passed to this command.
"#,
)?;
operations::Vendor::new()
.vendor_dir(vendor_dir)
.no_lock(data.no_lock)
.no_delete(data.no_delete)
.config(&config)
.target(target)
.vendor_dependencies()
.await?;
Ok(())
}