lux_lib/operations/
generate_lockfile.rs1use bon::Builder;
2use miette::Diagnostic;
3use thiserror::Error;
4
5use crate::{
6 config::Config,
7 drivers::sync::{gather_dependencies, DependencyKind, SyncError},
8 package_db::{PackageDB, PackageDBError},
9 pipeline::{
10 emit_lockfile::LockfileHandle,
11 materialise::{Error as MaterialiseError, Materialise},
12 resolve::{ResolveError, ResolvePackageDependencies},
13 },
14 workspace::{Workspace, WorkspaceError},
15};
16
17#[derive(Builder)]
19#[builder(start_fn = new, finish_fn(name = _build, vis = ""))]
20pub struct GenerateLockfile<'a> {
21 #[builder(start_fn)]
22 config: &'a Config,
23 #[builder(start_fn)]
24 workspace: &'a Workspace,
25}
26
27impl<State> GenerateLockfileBuilder<'_, State>
28where
29 State: generate_lockfile_builder::State + generate_lockfile_builder::IsComplete,
30{
31 pub async fn generate(self) -> Result<(), GenerateLockfileError> {
32 generate_lockfile(self._build()).await
33 }
34}
35
36async fn generate_lockfile(args: GenerateLockfile<'_>) -> Result<(), GenerateLockfileError> {
37 let GenerateLockfile { config, workspace } = args;
38
39 let members = workspace.member_names()?;
40 let package_db = PackageDB::open(config, workspace).await?;
41
42 let resolve = ResolvePackageDependencies::new(package_db, config)
43 .packages(gather_dependencies(
44 workspace,
45 DependencyKind::Regular,
46 &members,
47 )?)
48 .build_packages(gather_dependencies(
49 workspace,
50 DependencyKind::Build,
51 &members,
52 )?)
53 .test_packages(gather_dependencies(
54 workspace,
55 DependencyKind::Test,
56 &members,
57 )?);
58
59 let resolved = resolve.resolve().await?;
60 let artifacts = Materialise::new(config)
61 .resolved(resolved)
62 .materialise()
63 .await?;
64
65 let handle = LockfileHandle::from_artifacts(&artifacts);
66
67 let mut lockfile = workspace.lockfile()?.write_guard();
68 handle.commit(&mut lockfile);
69
70 Ok(())
71}
72
73#[derive(Error, Debug, Diagnostic)]
74pub enum GenerateLockfileError {
75 #[error(transparent)]
76 #[diagnostic(transparent)]
77 PackageDB(#[from] PackageDBError),
78 #[error(transparent)]
79 #[diagnostic(transparent)]
80 Workspace(#[from] WorkspaceError),
81 #[error(transparent)]
82 #[diagnostic(transparent)]
83 Sync(Box<SyncError>),
84 #[error(transparent)]
85 #[diagnostic(transparent)]
86 Resolve(#[from] ResolveError),
87 #[error(transparent)]
88 #[diagnostic(transparent)]
89 Materialise(#[from] MaterialiseError),
90}
91
92impl From<SyncError> for GenerateLockfileError {
93 fn from(source: SyncError) -> Self {
94 Self::Sync(Box::new(source))
95 }
96}