lux_lib/operations/
install_project.rs1use crate::{
2 build::{Build, BuildBehaviour, BuildError},
3 config::Config,
4 lockfile::LocalPackage,
5 lua_installation::{LuaInstallation, LuaInstallationError},
6 luarocks::luarocks_installation::{LuaRocksError, LuaRocksInstallError, LuaRocksInstallation},
7 operations::{install_dependencies::prepare_dependencies_for_build, InstallDependencies},
8 project::{project_toml::LocalProjectTomlValidationError, Project, ProjectError},
9 tree::{self, InstallTree, TreeError},
10};
11use bon::Builder;
12use itertools::Itertools;
13use miette::Diagnostic;
14use thiserror::Error;
15
16use super::InstallError;
17
18#[derive(Debug, Error, Diagnostic)]
19pub enum InstallProjectError {
20 #[error(transparent)]
21 #[diagnostic(transparent)]
22 LocalProjectTomlValidation(#[from] LocalProjectTomlValidationError),
23 #[error(transparent)]
24 #[diagnostic(transparent)]
25 Project(#[from] ProjectError),
26 #[error(transparent)]
27 #[diagnostic(transparent)]
28 LuaInstallation(#[from] LuaInstallationError),
29 #[error(transparent)]
30 #[diagnostic(transparent)]
31 Tree(#[from] TreeError),
32 #[error(transparent)]
33 #[diagnostic(transparent)]
34 LuaRocks(#[from] LuaRocksError),
35 #[error(transparent)]
36 #[diagnostic(transparent)]
37 LuaRocksInstall(#[from] LuaRocksInstallError),
38 #[error("error installind dependencies:\n{0}")]
39 #[diagnostic(forward(0))]
40 InstallDependencies(InstallError),
41 #[error("error installind build dependencies:\n{0}")]
42 #[diagnostic(forward(0))]
43 InstallBuildDependencies(InstallError),
44 #[error("error building project:\n{0}")]
45 #[diagnostic(forward(0))]
46 Build(#[from] BuildError),
47}
48
49#[derive(Builder)]
53#[builder(start_fn = new, finish_fn(name = _build, vis = ""))]
54pub struct InstallProject<'a, T>
55where
56 T: InstallTree,
57{
58 project: &'a Project,
59
60 config: &'a Config,
61
62 tree: &'a T,
63}
64
65impl<
66 T: InstallTree + Sync + Send + Clone + 'static,
67 State: install_project_builder::State + install_project_builder::IsComplete,
68 > InstallProjectBuilder<'_, T, State>
69{
70 pub async fn build(self) -> Result<LocalPackage, InstallProjectError> {
72 let args = self._build();
73 let config = args.config;
74 let project = args.project;
75 let tree = args.tree;
76 let build_tree = tree.build_tree(config)?;
77 let lua = LuaInstallation::new_from_config(config).await?;
78 let luarocks = LuaRocksInstallation::new(config, build_tree.clone())?;
79 let mut dependencies_to_install = Vec::new();
80 let mut build_dependencies_to_install = Vec::new();
81 let project_toml = project.toml().into_local()?;
82 prepare_dependencies_for_build(
83 &project_toml,
84 tree,
85 &mut dependencies_to_install,
86 &mut build_dependencies_to_install,
87 );
88
89 InstallDependencies::new()
90 .dependencies(dependencies_to_install.into_iter().unique().collect_vec())
91 .build_dependencies(
92 build_dependencies_to_install
93 .into_iter()
94 .unique()
95 .collect_vec(),
96 )
97 .tree(tree)
98 .lua(&lua)
99 .luarocks(&luarocks)
100 .config(config)
101 .build()
102 .await
103 .map_err(InstallProjectError::InstallBuildDependencies)?;
104
105 let package = Build::new()
106 .rockspec(&project_toml)
107 .lua(&lua)
108 .tree(tree)
109 .entry_type(tree::EntryType::Entrypoint)
110 .config(config)
111 .behaviour(BuildBehaviour::Force)
112 .build()
113 .await?;
114
115 let lockfile = tree.lockfile()?;
116 let dependencies = lockfile
117 .rocks()
118 .iter()
119 .filter_map(|(pkg_id, value)| {
120 if lockfile.is_entrypoint(pkg_id) {
121 Some(value)
122 } else {
123 None
124 }
125 })
126 .cloned()
127 .collect_vec();
128 let mut lockfile = lockfile.write_guard();
129 lockfile.add_entrypoint(&package);
130 for dep in dependencies {
131 lockfile.add_dependency(&package, &dep);
132 lockfile.remove_entrypoint(&dep);
133 }
134 Ok(package)
135 }
136}