sqruff_cli_lib/
lib.rs

1use clap::Parser as _;
2use commands::Format;
3use sqruff_lib::core::linter::core::Linter;
4use sqruff_lib::{Formatter, core::config::FluffConfig};
5use std::path::Path;
6use std::sync::Arc;
7use stdin::is_std_in_flag_input;
8
9use crate::commands::{Cli, Commands};
10#[cfg(feature = "codegen-docs")]
11use crate::docs::codegen_docs;
12use crate::formatters::OutputStreamFormatter;
13use crate::formatters::github_annotation_native_formatter::GithubAnnotationNativeFormatter;
14use crate::formatters::json::JsonFormatter;
15
16pub mod commands;
17mod commands_fix;
18mod commands_info;
19mod commands_lint;
20mod commands_rules;
21#[cfg(feature = "codegen-docs")]
22mod docs;
23mod formatters;
24mod github_action;
25mod ignore;
26mod logger;
27mod stdin;
28
29#[cfg(feature = "codegen-docs")]
30pub fn run_docs_generation() {
31    #[cfg(feature = "codegen-docs")]
32    return codegen_docs();
33}
34
35pub fn run_with_args<I, T>(args: I) -> i32
36where
37    I: IntoIterator<Item = T>,
38    T: Into<std::ffi::OsString> + Clone,
39{
40    let _ = logger::init();
41    let cli = Cli::parse_from(args);
42    let collect_parse_errors = cli.parsing_errors;
43
44    let config: FluffConfig = if let Some(config) = cli.config.as_ref() {
45        if !Path::new(config).is_file() {
46            eprintln!(
47                "The specified config file '{}' does not exist.",
48                cli.config.as_ref().unwrap()
49            );
50
51            std::process::exit(1);
52        };
53        let read_file = std::fs::read_to_string(config).unwrap();
54        FluffConfig::from_source(&read_file, None)
55    } else {
56        FluffConfig::from_root(None, false, None).unwrap()
57    };
58
59    let current_path = std::env::current_dir().unwrap();
60    let ignore_file = ignore::IgnoreFile::new_from_root(&current_path).unwrap();
61    let ignore_file = Arc::new(ignore_file);
62    let ignorer = {
63        let ignore_file = Arc::clone(&ignore_file);
64        move |path: &Path| ignore_file.is_ignored(path)
65    };
66
67    match cli.command {
68        Commands::Lint(args) => match is_std_in_flag_input(&args.paths) {
69            Err(e) => {
70                eprintln!("{e}");
71                1
72            }
73            Ok(false) => commands_lint::run_lint(args, config, ignorer, collect_parse_errors),
74            Ok(true) => commands_lint::run_lint_stdin(config, args.format, collect_parse_errors),
75        },
76        Commands::Fix(args) => match is_std_in_flag_input(&args.paths) {
77            Err(e) => {
78                eprintln!("{e}");
79                1
80            }
81            Ok(false) => commands_fix::run_fix(args, config, ignorer, collect_parse_errors),
82            Ok(true) => commands_fix::run_fix_stdin(config, args.format, collect_parse_errors),
83        },
84        Commands::Lsp => {
85            sqruff_lsp::run();
86            0
87        }
88        Commands::Info => {
89            commands_info::info();
90            0
91        }
92        Commands::Rules => {
93            commands_rules::rules_info(config);
94            0
95        }
96    }
97}
98
99pub(crate) fn linter(config: FluffConfig, format: Format, collect_parse_errors: bool) -> Linter {
100    let formatter: Arc<dyn Formatter> = match format {
101        Format::Human => {
102            let output_stream = std::io::stderr().into();
103            let formatter = OutputStreamFormatter::new(
104                output_stream,
105                config.get("nocolor", "core").as_bool().unwrap_or_default(),
106                config.get("verbose", "core").as_int().unwrap_or_default(),
107            );
108            Arc::new(formatter)
109        }
110        Format::GithubAnnotationNative => {
111            let output_stream = std::io::stderr();
112            let formatter = GithubAnnotationNativeFormatter::new(output_stream);
113            Arc::new(formatter)
114        }
115        Format::Json => {
116            let formatter = JsonFormatter::default();
117            Arc::new(formatter)
118        }
119    };
120
121    Linter::new(config, Some(formatter), None, collect_parse_errors)
122}