1use std::{collections::HashSet, path::PathBuf};
2
3use std::{str::FromStr, sync::Arc};
4
5use eyre::{Context, Result};
6use itertools::Itertools;
7use lux_lib::{
8 config::Config,
9 git::shorthand::RemoteGitUrlShorthand,
10 lua_version::LuaVersion,
11 operations::Sync,
12 package::PackageReq,
13 progress::{MultiProgress, Progress},
14 tree::Tree,
15 workspace::Workspace,
16};
17use walkdir::WalkDir;
18
19pub fn top_level_ignored_files(project: &Workspace) -> Vec<PathBuf> {
20 let top_level_project_files = ignore::WalkBuilder::new(project.root())
21 .max_depth(Some(1))
22 .build()
23 .filter_map(Result::ok)
24 .filter_map(|entry| {
25 let file = entry.into_path();
26 if file.is_dir() || file.extension().is_some_and(|ext| ext == "lua") {
27 Some(file)
28 } else {
29 None
30 }
31 })
32 .collect::<HashSet<_>>();
33
34 let top_level_files = WalkDir::new(project.root())
35 .max_depth(1)
36 .into_iter()
37 .filter_map(Result::ok)
38 .filter_map(|entry| {
39 let file = entry.into_path();
40 if file.is_dir() || file.extension().is_some_and(|ext| ext == "lua") {
41 Some(file)
42 } else {
43 None
44 }
45 })
46 .collect::<HashSet<_>>();
47
48 top_level_files
49 .difference(&top_level_project_files)
50 .cloned()
51 .collect_vec()
52}
53
54#[derive(Debug, Clone)]
58pub enum PackageReqOrGitShorthand {
59 PackageReq(PackageReq),
60 GitShorthand(RemoteGitUrlShorthand),
61}
62
63impl FromStr for PackageReqOrGitShorthand {
64 type Err = eyre::Error;
65
66 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
67 match RemoteGitUrlShorthand::parse_with_prefix(s) {
68 Ok(shorthand) => Ok(Self::GitShorthand(shorthand)),
69 Err(_) => Ok(Self::PackageReq(PackageReq::parse(s)?)),
70 }
71 }
72}
73
74pub fn current_workspace_or_user_tree(config: &Config) -> Result<Tree> {
77 let workspace = Workspace::current()?;
78 Ok(match &workspace {
79 Some(workspace) => workspace.tree(config)?,
80 None => {
81 let lua_version = LuaVersion::from(config)?.clone();
82 config.user_tree(lua_version)?
83 }
84 })
85}
86
87pub async fn sync_dependencies_if_locked(
88 workspace: &Workspace,
89 progress: Arc<Progress<MultiProgress>>,
90 config: &Config,
91) -> Result<()> {
92 Sync::new(workspace, config)
95 .progress(progress)
96 .sync_dependencies()
97 .await
98 .wrap_err("syncing dependencies with the project lockfile failed.")?;
99 Ok(())
100}
101
102pub async fn sync_build_dependencies_if_locked(
103 workspace: &Workspace,
104 progress: Arc<Progress<MultiProgress>>,
105 config: &Config,
106) -> Result<()> {
107 Sync::new(workspace, config)
108 .progress(progress.clone())
109 .sync_build_dependencies()
110 .await
111 .wrap_err("syncing build dependencies with the project lockfile failed.")?;
112 Ok(())
113}
114
115pub async fn sync_test_dependencies_if_locked(
116 workspace: &Workspace,
117 progress: Arc<Progress<MultiProgress>>,
118 config: &Config,
119) -> Result<()> {
120 Sync::new(workspace, config)
121 .progress(progress.clone())
122 .sync_test_dependencies()
123 .await
124 .wrap_err("syncing test dependencies with the project lockfile failed.")?;
125 Ok(())
126}