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] Box<LuaRocksInstallError>),
38 #[error("error installind dependencies")]
39 #[diagnostic(forward(0))]
40 InstallDependencies(Box<InstallError>),
41 #[error("error installind build dependencies")]
42 #[diagnostic(forward(0))]
43 InstallBuildDependencies(Box<InstallError>),
44 #[error("error building project")]
45 #[diagnostic(forward(0))]
46 Build(#[from] Box<BuildError>),
47}
48
49impl From<LuaRocksInstallError> for InstallProjectError {
50 fn from(source: LuaRocksInstallError) -> Self {
51 Self::LuaRocksInstall(Box::new(source))
52 }
53}
54
55impl From<BuildError> for InstallProjectError {
56 fn from(source: BuildError) -> Self {
57 Self::Build(Box::new(source))
58 }
59}
60
61#[derive(Builder)]
65#[builder(start_fn = new, finish_fn(name = _build, vis = ""))]
66pub struct InstallProject<'a, T>
67where
68 T: InstallTree,
69{
70 project: &'a Project,
71
72 config: &'a Config,
73
74 tree: &'a T,
75}
76
77impl<
78 T: InstallTree + Sync + Send + Clone + 'static,
79 State: install_project_builder::State + install_project_builder::IsComplete,
80 > InstallProjectBuilder<'_, T, State>
81{
82 pub async fn build(self) -> Result<LocalPackage, InstallProjectError> {
84 let args = self._build();
85 let config = args.config;
86 let project = args.project;
87 let tree = args.tree;
88 let build_tree = tree.build_tree(config)?;
89 let lua = LuaInstallation::new_from_config(config).await?;
90 let luarocks = LuaRocksInstallation::new(config, build_tree.clone())?;
91 let mut dependencies_to_install = Vec::new();
92 let mut build_dependencies_to_install = Vec::new();
93 let project_toml = project.toml().into_local()?;
94 prepare_dependencies_for_build(
95 &project_toml,
96 tree,
97 &mut dependencies_to_install,
98 &mut build_dependencies_to_install,
99 tree::EntryType::DependencyOnly,
100 );
101
102 let dependencies = InstallDependencies::new()
103 .dependencies(dependencies_to_install.into_iter().unique().collect_vec())
104 .build_dependencies(
105 build_dependencies_to_install
106 .into_iter()
107 .unique()
108 .collect_vec(),
109 )
110 .tree(tree)
111 .lua(&lua)
112 .luarocks(&luarocks)
113 .config(config)
114 .build()
115 .await
116 .map_err(|err| InstallProjectError::InstallBuildDependencies(Box::new(err)))?;
117
118 let package = Build::new()
119 .rockspec(&project_toml)
120 .lua(&lua)
121 .tree(tree)
122 .entry_type(tree::EntryType::Entrypoint)
123 .config(config)
124 .behaviour(BuildBehaviour::Force)
125 .build()
126 .await?;
127
128 let lockfile = tree.lockfile()?;
129 let mut lockfile = lockfile.write_guard();
130 let build_lockfile = tree.build_tree(config)?.lockfile()?;
131
132 lockfile.add_entrypoint(&package);
133 for dep in dependencies {
134 lockfile.add_dependency(&package, &dep);
135 }
136 for dep in build_lockfile.rocks().values() {
137 lockfile.add_build_dependency(&package, dep);
138 }
139 Ok(package)
140 }
141}