use std::{collections::HashSet, path::PathBuf};
use std::{str::FromStr, sync::Arc};
use eyre::{Context, Result};
use itertools::Itertools;
use lux_lib::{
config::Config,
git::shorthand::RemoteGitUrlShorthand,
lua_version::LuaVersion,
operations::Sync,
package::PackageReq,
progress::{MultiProgress, Progress},
tree::Tree,
workspace::Workspace,
};
use walkdir::WalkDir;
pub fn top_level_ignored_files(project: &Workspace) -> Vec<PathBuf> {
let top_level_project_files = ignore::WalkBuilder::new(project.root())
.max_depth(Some(1))
.build()
.filter_map(Result::ok)
.filter_map(|entry| {
let file = entry.into_path();
if file.is_dir() || file.extension().is_some_and(|ext| ext == "lua") {
Some(file)
} else {
None
}
})
.collect::<HashSet<_>>();
let top_level_files = WalkDir::new(project.root())
.max_depth(1)
.into_iter()
.filter_map(Result::ok)
.filter_map(|entry| {
let file = entry.into_path();
if file.is_dir() || file.extension().is_some_and(|ext| ext == "lua") {
Some(file)
} else {
None
}
})
.collect::<HashSet<_>>();
top_level_files
.difference(&top_level_project_files)
.cloned()
.collect_vec()
}
#[derive(Debug, Clone)]
pub enum PackageReqOrGitShorthand {
PackageReq(PackageReq),
GitShorthand(RemoteGitUrlShorthand),
}
impl FromStr for PackageReqOrGitShorthand {
type Err = eyre::Error;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match RemoteGitUrlShorthand::parse_with_prefix(s) {
Ok(shorthand) => Ok(Self::GitShorthand(shorthand)),
Err(_) => Ok(Self::PackageReq(PackageReq::parse(s)?)),
}
}
}
pub fn current_workspace_or_user_tree(config: &Config) -> Result<Tree> {
let workspace = Workspace::current()?;
Ok(match &workspace {
Some(workspace) => workspace.tree(config)?,
None => {
let lua_version = LuaVersion::from(config)?.clone();
config.user_tree(lua_version)?
}
})
}
pub async fn sync_dependencies_if_locked(
workspace: &Workspace,
progress: Arc<Progress<MultiProgress>>,
config: &Config,
) -> Result<()> {
Sync::new(workspace, config)
.progress(progress)
.sync_dependencies()
.await
.wrap_err("syncing dependencies with the project lockfile failed.")?;
Ok(())
}
pub async fn sync_build_dependencies_if_locked(
workspace: &Workspace,
progress: Arc<Progress<MultiProgress>>,
config: &Config,
) -> Result<()> {
Sync::new(workspace, config)
.progress(progress.clone())
.sync_build_dependencies()
.await
.wrap_err("syncing build dependencies with the project lockfile failed.")?;
Ok(())
}
pub async fn sync_test_dependencies_if_locked(
workspace: &Workspace,
progress: Arc<Progress<MultiProgress>>,
config: &Config,
) -> Result<()> {
Sync::new(workspace, config)
.progress(progress.clone())
.sync_test_dependencies()
.await
.wrap_err("syncing test dependencies with the project lockfile failed.")?;
Ok(())
}