Skip to main content

lux_cli/
vendor.rs

1use clap::Args;
2use eyre::{eyre, Context, OptionExt, Result};
3use lux_lib::{
4    config::Config,
5    lua_rockspec::RemoteLuaRockspec,
6    operations::{self, VendorTarget},
7    project::Project,
8};
9use std::path::PathBuf;
10
11#[derive(Args)]
12pub struct Vendor {
13    /// The directory in which to vendor the dependencies.
14    /// Must be set if `--vendor-dir` is not set.
15    vendor_dir: Option<PathBuf>,
16
17    /// RockSpec to vendor the packages for.{n}
18    /// If not set, Lux will vendor dependencies of the current project.
19    #[arg(long)]
20    rockspec: Option<PathBuf>,
21
22    /// Ignore the project's lockfile, if present.
23    #[arg(long)]
24    no_lock: bool,
25
26    /// Don't delete the <vendor-dir> when vendoring,{n}
27    /// but rather keep all existing contents of the vendor directory.
28    #[arg(long)]
29    no_delete: bool,
30}
31
32pub async fn vendor(data: Vendor, config: Config) -> Result<()> {
33    let target =
34        match data.rockspec {
35            Some(rockspec_path) => {
36                let content = tokio::fs::read_to_string(&rockspec_path).await?;
37                let rockspec = match rockspec_path
38                    .extension()
39                    .map(|ext| ext.to_string_lossy().to_string())
40                    .unwrap_or("".into())
41                    .as_str()
42                {
43                    "rockspec" => Ok(RemoteLuaRockspec::new(&content)?),
44                    _ => Err(eyre!(
45                        "expected a path to a .rockspec file, but got:\n{}",
46                        rockspec_path.display()
47                    )),
48                }?;
49                VendorTarget::Rockspec(rockspec)
50            }
51            None => VendorTarget::Project(Project::current_or_err().context(
52                "`lx vendor` must be run in a project root or with a rockspec argument.",
53            )?),
54        };
55
56    let vendor_dir = data
57        .vendor_dir
58        .or_else(|| config.vendor_dir().cloned())
59        .ok_or_eyre(
60            r#"<vendor-dir> not set.
61        It must either be specified via `--vendor-dir` or passed to this command.
62        "#,
63        )?;
64
65    operations::Vendor::new()
66        .vendor_dir(vendor_dir)
67        .no_lock(data.no_lock)
68        .no_delete(data.no_delete)
69        .config(&config)
70        .target(target)
71        .vendor_dependencies()
72        .await?;
73
74    Ok(())
75}