Skip to main content

lux_cli/
build.rs

1use clap::Args;
2use eyre::Result;
3use lux_lib::{
4    config::Config,
5    lockfile::LocalPackage,
6    operations::{self},
7    package::PackageName,
8    workspace::Workspace,
9};
10
11#[derive(Args, Default)]
12pub struct Build {
13    /// Ignore the project's lockfile and don't create one.
14    #[arg(long)]
15    no_lock: bool,
16
17    /// Build only the dependencies
18    #[arg(long)]
19    only_deps: bool,
20
21    /// Package to build.
22    #[arg(short, long, visible_short_alias = 'p')]
23    pub(crate) package: Option<PackageName>,
24}
25
26/// Returns `Some` if the `only_deps` arg is set to `false`.
27pub async fn build(data: Build, config: Config) -> Result<Vec<LocalPackage>> {
28    let workspace = Workspace::current_or_err()?;
29    let result = operations::BuildWorkspace::new(&workspace, &config)
30        .maybe_package(data.package)
31        .no_lock(data.no_lock)
32        .only_deps(data.only_deps)
33        .build()
34        .await?;
35    Ok(result)
36}
37
38#[cfg(test)]
39mod tests {
40
41    use super::*;
42
43    use std::path::PathBuf;
44
45    use assert_fs::{
46        prelude::{FileWriteStr, PathChild, PathCreateDir},
47        TempDir,
48    };
49
50    use lux_lib::{
51        config::ConfigBuilder, lua_installation::detect_installed_lua_version,
52        lua_version::LuaVersion,
53    };
54    use serial_test::serial;
55
56    #[serial]
57    #[tokio::test]
58    async fn test_build_project_from_vendored() {
59        let cwd = &std::env::current_dir().unwrap();
60        let project_dir = TempDir::new().unwrap();
61        std::env::set_current_dir(&project_dir).unwrap();
62        // This test runs without a network connection when run with Nix
63        let vendor_dir = TempDir::new().unwrap();
64        let foo_dir = vendor_dir.child("foo@1.0.0-1");
65        foo_dir.create_dir_all().unwrap();
66        let foo_rockspec = vendor_dir.child("foo-1.0.0-1.rockspec");
67        foo_rockspec
68            .write_str(
69                r#"
70                package = 'foo'
71                version = '1.0.0-1'
72                source = {
73                    url = 'https://github.com/lumen-oss/luarocks-stub',
74                }
75            "#,
76            )
77            .unwrap();
78        let bar_dir = vendor_dir.child("bar@2.0.0-2");
79        bar_dir.create_dir_all().unwrap();
80        let bar_rockspec = vendor_dir.child("bar-2.0.0-2.rockspec");
81        bar_rockspec
82            .write_str(
83                r#"
84                package = 'bar'
85                version = '2.0.0-2'
86                source = {
87                    url = 'https://github.com/lumen-oss/luarocks-stub',
88                }
89            "#,
90            )
91            .unwrap();
92        let baz_dir = vendor_dir.child("baz@2.0.0-1");
93        baz_dir.create_dir_all().unwrap();
94        let baz_rockspec = vendor_dir.child("baz-2.0.0-1.rockspec");
95        baz_rockspec
96            .write_str(
97                r#"
98                package = 'baz'
99                version = '2.0.0-1'
100                source = {
101                    url = 'https://github.com/lumen-oss/luarocks-stub',
102                }
103            "#,
104            )
105            .unwrap();
106        let toml_content = r#"
107        package = "test_rock"
108        version = "scm-1"
109
110        lua = ">= 5.1"
111
112        [dependencies]
113        foo = ">= 1.0.0"
114        bar = ">= 1.0.0"
115        baz = "== 2.0.0"
116        "#;
117        let toml = project_dir.child("lux.toml");
118        toml.write_str(toml_content).unwrap();
119        let lua_version = detect_installed_lua_version().or(Some(LuaVersion::Lua51));
120        let data_dir: PathBuf = assert_fs::TempDir::new().unwrap().path().into();
121        let config = ConfigBuilder::new()
122            .unwrap()
123            .vendor_dir(Some(vendor_dir.to_path_buf()))
124            .lua_version(lua_version)
125            .data_dir(Some(data_dir))
126            .build()
127            .unwrap();
128        build(Build::default(), config).await.unwrap();
129        std::env::set_current_dir(cwd).unwrap();
130    }
131}