lux_lib/pipeline/
discover.rs1use miette::Diagnostic;
2use thiserror::Error;
3
4use crate::{
5 lua_rockspec::RemoteLuaRockspec,
6 operations,
7 package::{PackageReq, PackageSpec, RemotePackage},
8 package_db::SearchError,
9 remote_package_source::RemotePackageSource,
10 rockspec::Rockspec,
11};
12use std::path::PathBuf;
13
14use super::materialise::PackageSource;
15
16#[derive(Clone, Debug)]
17pub(crate) struct FoundPackage {
18 pub(crate) remote: RemotePackage,
19 pub(crate) rockspec: RemoteLuaRockspec,
20 pub(crate) artifact: Option<PackageSource>,
21}
22
23impl FoundPackage {
24 pub(crate) fn from_rockspec(rockspec: RemoteLuaRockspec) -> Self {
27 let source = rockspec
28 .to_lua_remote_rockspec_string()
29 .map(RemotePackageSource::RockspecContent)
30 .unwrap_or(RemotePackageSource::Local);
31 let remote = RemotePackage::new(
32 PackageSpec::new(rockspec.package().clone(), rockspec.version().clone()),
33 source,
34 None,
35 );
36 Self {
37 remote,
38 rockspec,
39 artifact: None,
40 }
41 }
42
43 pub(crate) fn from_project_root(rockspec: RemoteLuaRockspec, root_dir: PathBuf) -> Self {
46 let remote = RemotePackage::new(
47 PackageSpec::new(rockspec.package().clone(), rockspec.version().clone()),
48 RemotePackageSource::Local,
49 None,
50 );
51 Self {
52 remote,
53 rockspec,
54 artifact: Some(PackageSource::SourceDir(root_dir)),
55 }
56 }
57}
58
59#[derive(Error, Debug, Diagnostic)]
60#[non_exhaustive]
61pub enum DiscoverError {
62 #[error(transparent)]
63 #[diagnostic(transparent)]
64 Search(#[from] SearchError),
65 #[error("failed to acquire metadata for '{0}'")]
66 #[diagnostic(forward(1))]
67 Download(PackageReq, Box<operations::SearchAndDownloadError>),
68 #[error("failed to fetch vendored package for '{0}'")]
69 #[diagnostic(forward(1))]
70 FetchVendored(PackageReq, Box<operations::FetchVendoredError>),
71 #[error(transparent)]
72 #[diagnostic(transparent)]
73 Project(#[from] crate::project::ProjectError),
74 #[error(transparent)]
75 #[diagnostic(transparent)]
76 LocalRockspec(#[from] crate::project::IntoLocalRockspecError),
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn from_rockspec_builds_local_found_package() {
85 let content = "rockspec_format = '1.0'\npackage = 'foo'\nversion = '1.0.0-1'\nsource = { url = 'https://example.com/foo.zip' }";
86 let Ok(rockspec) = RemoteLuaRockspec::new(content) else {
87 unreachable!("invalid test rockspec");
88 };
89
90 let found = FoundPackage::from_rockspec(rockspec);
91
92 assert_eq!(found.remote.spec.name().to_string(), "foo");
93 assert_eq!(found.remote.spec.version().to_string(), "1.0.0-1");
94 assert!(matches!(
95 found.remote.source,
96 RemotePackageSource::RockspecContent(_)
97 ));
98 assert!(found.artifact.is_none());
99 }
100}