1use clap::Args;
2use eyre::Result;
3use itertools::Itertools;
4use lux_lib::{config::Config, operations::Exec, project::Project};
5use path_slash::PathBufExt;
6
7use crate::project::top_level_ignored_files;
8
9#[derive(Args)]
10pub struct Lint {
11 args: Option<Vec<String>>,
14 #[arg(long)]
18 no_ignore: bool,
19}
20
21pub async fn lint(lint_args: Lint, config: Config) -> Result<()> {
22 let project = Project::current()?;
23 let root_dir = match &project {
24 Some(project) => project.root().to_slash_lossy().to_string(),
25 None => std::env::current_dir()?.to_slash_lossy().to_string(),
26 };
27
28 let check_args: Vec<String> = match lint_args.args {
29 Some(args) => args,
30 None if lint_args.no_ignore => Vec::new(),
31 None => {
32 let ignored_files = project.iter().flat_map(|project| {
33 top_level_ignored_files(project)
34 .into_iter()
35 .map(|file| file.to_slash_lossy().to_string())
36 });
37 std::iter::once("--exclude-files".into())
38 .chain(ignored_files)
39 .collect_vec()
40 }
41 };
42
43 Exec::new("luacheck", None, &config)
44 .arg(root_dir)
45 .args(check_args)
46 .disable_loader(true)
47 .exec()
48 .await?;
49
50 Ok(())
51}