1use clap::Args;
2use eyre::Result;
3use itertools::Itertools;
4use lux_lib::{
5 config::Config,
6 operations::{Exec, Install, PackageInstallSpec},
7 progress::MultiProgress,
8 project::Project,
9 tree,
10};
11use path_slash::PathBufExt;
12
13use crate::project::top_level_ignored_files;
14
15#[derive(Args)]
16pub struct Lint {
17 args: Option<Vec<String>>,
20 #[arg(long)]
24 no_ignore: bool,
25}
26
27pub async fn lint(lint_args: Lint, config: Config) -> Result<()> {
28 let project = Project::current_or_err()?;
29
30 let luacheck =
31 PackageInstallSpec::new("luacheck".parse()?, tree::EntryType::Entrypoint).build();
32
33 Install::new(&config)
34 .package(luacheck)
35 .project(&project)?
36 .progress(MultiProgress::new_arc())
37 .install()
38 .await?;
39
40 let check_args: Vec<String> = match lint_args.args {
41 Some(args) => args,
42 None if lint_args.no_ignore => Vec::new(),
43 None => {
44 let ignored_files = top_level_ignored_files(&project)
45 .into_iter()
46 .map(|file| file.to_slash_lossy().to_string());
47 std::iter::once("--exclude-files".into())
48 .chain(ignored_files)
49 .collect_vec()
50 }
51 };
52
53 Exec::new("luacheck", Some(&project), &config)
54 .arg(project.root().to_slash_lossy())
55 .args(check_args)
56 .exec()
57 .await?;
58
59 Ok(())
60}