Skip to content

Commit 3963b85

Browse files
committed
feat(check): allow ignoring specific languages
Still TODO: add this as a config option? But maybe it's fine as just a CLI flag, since it is mostly just a QOL change around the `directories` flag. Plus, someone using the server interactively in an editor will still want diagnostics when opening queries for an ignored language, presumably. Fixes #271
1 parent d227d24 commit 3963b85

3 files changed

Lines changed: 118 additions & 1 deletion

File tree

src/cli/check.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ static LANGUAGE_CACHE: LazyLock<DashMap<String, Arc<LanguageData>>> = LazyLock::
2121

2222
pub async fn check_directories(
2323
directories: &[PathBuf],
24+
ignore: Vec<String>,
2425
config: String,
2526
workspace: Option<PathBuf>,
2627
format: bool,
@@ -51,6 +52,12 @@ pub async fn check_directories(
5152
let absolute_path = path.canonicalize().expect("Path should be valid");
5253
let uri = Url::from_file_path(&absolute_path).expect("Path should be absolute");
5354
let language_name = util::get_language_name(&uri, &options);
55+
if let Some(language_name) = &language_name
56+
&& ignore.contains(language_name)
57+
{
58+
return None;
59+
}
60+
5461
let language_data = language_name.and_then(|name| {
5562
LANGUAGE_CACHE.get(&name).as_deref().cloned().or_else(|| {
5663
util::get_language(&name, &options)

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ enum Commands {
389389
/// Apply fixes to diagnostics that have them.
390390
#[arg(long)]
391391
fix: bool,
392+
393+
/// List of languages to be ignored, e.g. `--ignore c lua ...`.
394+
#[arg(long, short, value_parser, num_args = 1..)]
395+
ignore: Vec<String>,
392396
},
393397
/// Lint the query files in the given directories for errors. This differs from `check` because
394398
/// it does not perform a full semantic analysis (e.g. analyzing for impossible patterns), but
@@ -468,14 +472,15 @@ async fn main() {
468472
}
469473
Some(Commands::Check {
470474
directories,
475+
ignore,
471476
workspace,
472477
config,
473478
format,
474479
fix,
475480
}) => {
476481
let config_str = get_config_str(config);
477482
std::process::exit(
478-
check_directories(&directories, config_str, workspace, format, fix).await,
483+
check_directories(&directories, ignore, config_str, workspace, format, fix).await,
479484
);
480485
}
481486
Some(Commands::Lint {

tests/check.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#[cfg(test)]
2+
mod test {
3+
use regex::Regex;
4+
use rstest::rstest;
5+
use std::{
6+
collections::{BTreeMap, HashMap},
7+
path::Path,
8+
process::Command,
9+
sync::LazyLock,
10+
};
11+
use ts_query_ls::{Options, Predicate, PredicateParameter, SerializableRegex};
12+
13+
static CONFIG: LazyLock<Options> = LazyLock::new(|| Options {
14+
valid_predicates: BTreeMap::from([
15+
(
16+
String::from("pred-name"),
17+
Predicate {
18+
description: String::from("A predicate"),
19+
parameters: vec![PredicateParameter {
20+
description: None,
21+
type_: ts_query_ls::PredicateParameterType::Any,
22+
arity: ts_query_ls::PredicateParameterArity::Variadic,
23+
..Default::default()
24+
}],
25+
},
26+
),
27+
(
28+
String::from("match"),
29+
Predicate {
30+
description: String::from("Check match"),
31+
parameters: vec![PredicateParameter {
32+
description: None,
33+
type_: ts_query_ls::PredicateParameterType::Any,
34+
arity: ts_query_ls::PredicateParameterArity::Variadic,
35+
..Default::default()
36+
}],
37+
},
38+
),
39+
]),
40+
valid_captures: HashMap::from([
41+
(
42+
String::from("after_trailing_whitespace"),
43+
BTreeMap::from([(String::from("capture"), String::from("A capture."))]),
44+
),
45+
(
46+
String::from("before_predicates"),
47+
BTreeMap::from([(String::from("type"), String::from("A type."))]),
48+
),
49+
]),
50+
language_retrieval_patterns: vec![SerializableRegex::from(
51+
Regex::new(r"fixtures/([^/]+)").unwrap(),
52+
)],
53+
..Default::default()
54+
});
55+
56+
#[rstest]
57+
#[case(
58+
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/after_trailing_whitespace.scm"),
59+
Some(["Invalid capture name \"@cap\" (fix available)"].as_slice())
60+
)]
61+
#[case(
62+
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_predicates.scm"),
63+
Some(["Unrecognized predicate \"lua-match\""].as_slice())
64+
)]
65+
#[case(
66+
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_missing.scm"),
67+
Some(["This pattern has no captures, and will not be processed"].as_slice())
68+
)]
69+
#[case(
70+
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/formatting_test_files/before_syntax_error.scm"),
71+
Some(["Invalid syntax"].as_slice())
72+
)]
73+
#[case(
74+
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fixtures/example_test_files/simple.scm"),
75+
None
76+
)]
77+
fn cli_check(#[case] path_str: &str, #[case] warning_messages: Option<&[&str]>) {
78+
// Arrange
79+
let path = Path::new(path_str);
80+
81+
// Act
82+
let output = Command::new(env!("CARGO_BIN_EXE_ts_query_ls"))
83+
.arg("check")
84+
.arg(path)
85+
.arg("--config")
86+
.arg(serde_json::to_string::<Options>(&CONFIG).unwrap())
87+
.arg("--ignore")
88+
.arg("I_DO_NOT_EXIST")
89+
.arg("example_test_files")
90+
.output()
91+
.expect("Failed to wait on ts-query-ls format command");
92+
93+
// Assert
94+
let string_output = String::from_utf8(output.stderr).unwrap();
95+
if let Some(messages) = warning_messages {
96+
for message in messages {
97+
assert!(string_output.contains(message));
98+
}
99+
assert_eq!(output.status.code(), Some(1));
100+
} else {
101+
assert_eq!(string_output, "");
102+
assert_eq!(output.status.code(), Some(0));
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)