Skip to main content

lux_cli/
lint.rs

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    /// Arguments to pass to the luacheck command.{n}
12    /// If you pass arguments to luacheck, Lux will not pass any default arguments.
13    args: Option<Vec<String>>,
14    /// By default, Lux will add top-level ignored files and directories{n}
15    /// (like those in .gitignore) to luacheck's exclude files.{n}
16    /// This flag disables that behaviour.{n}
17    #[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}