ast-grep-cli 0.9.2__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/PKG-INFO +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/Cargo.lock +18 -18
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/Cargo.toml +2 -2
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/config.rs +50 -18
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/error.rs +19 -3
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/lib.rs +5 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/new.rs +33 -14
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/print/cloud_print.rs +1 -1
- ast_grep_cli-0.10.0/crates/cli/src/print/colored_print/test.rs +281 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/print/colored_print.rs +97 -215
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/print/interactive_print.rs +43 -4
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/print/json_print.rs +208 -33
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/print/mod.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/run.rs +95 -81
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/scan.rs +42 -62
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/utils.rs +104 -49
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/verify.rs +16 -11
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/Cargo.toml +2 -2
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/deserialize_env.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/referent_rule.rs +3 -3
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/rule.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/rule_config.rs +3 -3
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/Cargo.toml +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/lib.rs +3 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/match_tree.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/node.rs +56 -17
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/replacer/indent.rs +3 -3
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/source.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-dynamic/Cargo.toml +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-dynamic/src/lib.rs +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/Cargo.toml +4 -4
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/parsers.rs +3 -3
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-lsp/Cargo.toml +2 -2
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-lsp/src/lib.rs +2 -2
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/pyproject.toml +1 -1
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/LICENSE +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/README.md +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/bin/ast-grep.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/lang.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/lsp.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/src/main.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/tests/common/mod.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/tests/run_test.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/tests/scan_test.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/crates/cli/tests/verify_test.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/constraints.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/lib.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/maybe.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/relational_rule/mod.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/relational_rule/stop_by.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/rule_collection.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-config/src/transform.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/language.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/matcher/kind.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/matcher/node_match.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/matcher/pattern.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/matcher/text.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/matcher.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/meta_var.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/ops.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/pinned.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/replacer/structural.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/replacer/template.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/replacer.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-core/src/traversal.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/cpp.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/csharp.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/css.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/go.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/json.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/kotlin.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/lib.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/lua.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/python.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/rust.rs +0 -0
- {ast_grep_cli-0.9.2 → ast_grep_cli-0.10.0}/local_dependencies/ast-grep-language/src/scala.rs +0 -0
|
@@ -98,7 +98,7 @@ dependencies = [
|
|
|
98
98
|
|
|
99
99
|
[[package]]
|
|
100
100
|
name = "ast-grep"
|
|
101
|
-
version = "0.
|
|
101
|
+
version = "0.10.0"
|
|
102
102
|
dependencies = [
|
|
103
103
|
"ansi_term",
|
|
104
104
|
"anyhow",
|
|
@@ -126,7 +126,7 @@ dependencies = [
|
|
|
126
126
|
|
|
127
127
|
[[package]]
|
|
128
128
|
name = "ast-grep-config"
|
|
129
|
-
version = "0.
|
|
129
|
+
version = "0.10.0"
|
|
130
130
|
dependencies = [
|
|
131
131
|
"anyhow",
|
|
132
132
|
"ast-grep-core",
|
|
@@ -142,7 +142,7 @@ dependencies = [
|
|
|
142
142
|
|
|
143
143
|
[[package]]
|
|
144
144
|
name = "ast-grep-core"
|
|
145
|
-
version = "0.
|
|
145
|
+
version = "0.10.0"
|
|
146
146
|
dependencies = [
|
|
147
147
|
"bit-set",
|
|
148
148
|
"regex",
|
|
@@ -153,7 +153,7 @@ dependencies = [
|
|
|
153
153
|
|
|
154
154
|
[[package]]
|
|
155
155
|
name = "ast-grep-dynamic"
|
|
156
|
-
version = "0.
|
|
156
|
+
version = "0.10.0"
|
|
157
157
|
dependencies = [
|
|
158
158
|
"ast-grep-core",
|
|
159
159
|
"ignore",
|
|
@@ -165,7 +165,7 @@ dependencies = [
|
|
|
165
165
|
|
|
166
166
|
[[package]]
|
|
167
167
|
name = "ast-grep-language"
|
|
168
|
-
version = "0.
|
|
168
|
+
version = "0.10.0"
|
|
169
169
|
dependencies = [
|
|
170
170
|
"ast-grep-core",
|
|
171
171
|
"ast-grep-tree-sitter-c-sharp",
|
|
@@ -193,7 +193,7 @@ dependencies = [
|
|
|
193
193
|
|
|
194
194
|
[[package]]
|
|
195
195
|
name = "ast-grep-lsp"
|
|
196
|
-
version = "0.
|
|
196
|
+
version = "0.10.0"
|
|
197
197
|
dependencies = [
|
|
198
198
|
"ast-grep-config",
|
|
199
199
|
"ast-grep-core",
|
|
@@ -205,7 +205,7 @@ dependencies = [
|
|
|
205
205
|
|
|
206
206
|
[[package]]
|
|
207
207
|
name = "ast-grep-napi"
|
|
208
|
-
version = "0.
|
|
208
|
+
version = "0.10.0"
|
|
209
209
|
dependencies = [
|
|
210
210
|
"ast-grep-config",
|
|
211
211
|
"ast-grep-core",
|
|
@@ -274,7 +274,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
|
274
274
|
|
|
275
275
|
[[package]]
|
|
276
276
|
name = "benches"
|
|
277
|
-
version = "0.
|
|
277
|
+
version = "0.10.0"
|
|
278
278
|
dependencies = [
|
|
279
279
|
"ast-grep-config",
|
|
280
280
|
"ast-grep-core",
|
|
@@ -747,9 +747,9 @@ dependencies = [
|
|
|
747
747
|
|
|
748
748
|
[[package]]
|
|
749
749
|
name = "globset"
|
|
750
|
-
version = "0.4.
|
|
750
|
+
version = "0.4.12"
|
|
751
751
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
752
|
-
checksum = "
|
|
752
|
+
checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006"
|
|
753
753
|
dependencies = [
|
|
754
754
|
"aho-corasick",
|
|
755
755
|
"bstr",
|
|
@@ -1437,9 +1437,9 @@ dependencies = [
|
|
|
1437
1437
|
|
|
1438
1438
|
[[package]]
|
|
1439
1439
|
name = "serde_json"
|
|
1440
|
-
version = "1.0.
|
|
1440
|
+
version = "1.0.104"
|
|
1441
1441
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1442
|
-
checksum = "
|
|
1442
|
+
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
|
|
1443
1443
|
dependencies = [
|
|
1444
1444
|
"indexmap",
|
|
1445
1445
|
"itoa",
|
|
@@ -1776,9 +1776,9 @@ dependencies = [
|
|
|
1776
1776
|
|
|
1777
1777
|
[[package]]
|
|
1778
1778
|
name = "tree-sitter-c"
|
|
1779
|
-
version = "0.20.
|
|
1779
|
+
version = "0.20.4"
|
|
1780
1780
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1781
|
-
checksum = "
|
|
1781
|
+
checksum = "fa1bb73a4101c88775e4fefcd0543ee25e192034484a5bd45cb99eefb997dca9"
|
|
1782
1782
|
dependencies = [
|
|
1783
1783
|
"cc",
|
|
1784
1784
|
"tree-sitter",
|
|
@@ -1786,9 +1786,9 @@ dependencies = [
|
|
|
1786
1786
|
|
|
1787
1787
|
[[package]]
|
|
1788
1788
|
name = "tree-sitter-cpp"
|
|
1789
|
-
version = "0.20.
|
|
1789
|
+
version = "0.20.2"
|
|
1790
1790
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1791
|
-
checksum = "
|
|
1791
|
+
checksum = "1c88fd925d0333e63ac64e521f5bd79c53019e569ffbbccfeef346a326f459e9"
|
|
1792
1792
|
dependencies = [
|
|
1793
1793
|
"cc",
|
|
1794
1794
|
"tree-sitter",
|
|
@@ -1899,9 +1899,9 @@ dependencies = [
|
|
|
1899
1899
|
|
|
1900
1900
|
[[package]]
|
|
1901
1901
|
name = "tree-sitter-python"
|
|
1902
|
-
version = "0.20.
|
|
1902
|
+
version = "0.20.3"
|
|
1903
1903
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1904
|
-
checksum = "
|
|
1904
|
+
checksum = "f47ebd9cac632764b2f4389b08517bf2ef895431dd163eb562e3d2062cc23a14"
|
|
1905
1905
|
dependencies = [
|
|
1906
1906
|
"cc",
|
|
1907
1907
|
"tree-sitter",
|
|
@@ -8,7 +8,7 @@ default-run = "sg"
|
|
|
8
8
|
readme = "../../README.md"
|
|
9
9
|
license-file = "../../LICENSE"
|
|
10
10
|
|
|
11
|
-
version= "0.
|
|
11
|
+
version= "0.10.0"
|
|
12
12
|
authors= ["Herrington Darkholme <2883231+HerringtonDarkholme@users.noreply.github.com>"]
|
|
13
13
|
edition= "2021"
|
|
14
14
|
# license.workspace = true
|
|
@@ -42,7 +42,7 @@ ignore= { version = "0.4.20" }
|
|
|
42
42
|
inquire = "0.6.2"
|
|
43
43
|
num_cpus = "1.16.0"
|
|
44
44
|
serde= { version = "1.0", features = ["derive"] }
|
|
45
|
-
serde_json = "1.0.
|
|
45
|
+
serde_json = "1.0.104"
|
|
46
46
|
serde_yaml = "0.9.25"
|
|
47
47
|
similar = { version = "2.2.1", features = ["inline"] }
|
|
48
48
|
tokio = { version = "1", features = ["rt-multi-thread", "io-std"] }
|
|
@@ -7,6 +7,7 @@ use ast_grep_config::{
|
|
|
7
7
|
};
|
|
8
8
|
use ast_grep_language::config_file_type;
|
|
9
9
|
use clap::ValueEnum;
|
|
10
|
+
use ignore::overrides::OverrideBuilder;
|
|
10
11
|
use ignore::WalkBuilder;
|
|
11
12
|
use serde::{Deserialize, Serialize};
|
|
12
13
|
use std::collections::HashMap;
|
|
@@ -44,9 +45,7 @@ pub struct AstGrepConfig {
|
|
|
44
45
|
pub util_dirs: Option<Vec<PathBuf>>,
|
|
45
46
|
/// configuration for custom languages
|
|
46
47
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
47
|
-
pub custom_languages: Option<HashMap<String, CustomLang>>,
|
|
48
|
-
// #[serde(skip_serializing_if="Option::is_none")]
|
|
49
|
-
// pub rules: Option<Vec<()>>,
|
|
48
|
+
pub custom_languages: Option<HashMap<String, CustomLang>>,
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
pub fn find_rules(config_path: Option<PathBuf>) -> Result<RuleCollection<SgLang>> {
|
|
@@ -156,7 +155,7 @@ pub struct TestHarness {
|
|
|
156
155
|
pub path_map: HashMap<String, PathBuf>,
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
pub fn find_tests(config_path: Option<PathBuf>) -> Result<TestHarness> {
|
|
158
|
+
pub fn find_tests(config_path: Option<PathBuf>, glob_filter: Option<&str>) -> Result<TestHarness> {
|
|
160
159
|
let config_path =
|
|
161
160
|
find_config_path_with_default(config_path, None).context(EC::ReadConfiguration)?;
|
|
162
161
|
let config_str = read_to_string(&config_path).context(EC::ReadConfiguration)?;
|
|
@@ -173,7 +172,12 @@ pub fn find_tests(config_path: Option<PathBuf>) -> Result<TestHarness> {
|
|
|
173
172
|
test_cases: new_cases,
|
|
174
173
|
snapshots: new_snapshots,
|
|
175
174
|
path_map: new_path_map,
|
|
176
|
-
} = read_test_files(
|
|
175
|
+
} = read_test_files(
|
|
176
|
+
base_dir,
|
|
177
|
+
&test.test_dir,
|
|
178
|
+
test.snapshot_dir.as_deref(),
|
|
179
|
+
glob_filter,
|
|
180
|
+
)?;
|
|
177
181
|
path_map.extend(new_path_map);
|
|
178
182
|
test_cases.extend(new_cases);
|
|
179
183
|
snapshots.extend(new_snapshots);
|
|
@@ -185,22 +189,46 @@ pub fn find_tests(config_path: Option<PathBuf>) -> Result<TestHarness> {
|
|
|
185
189
|
})
|
|
186
190
|
}
|
|
187
191
|
|
|
192
|
+
fn build_test_dir_walker(
|
|
193
|
+
test_path: &Path,
|
|
194
|
+
snapshot_dirname: &Path,
|
|
195
|
+
glob_filter: Option<&str>,
|
|
196
|
+
) -> Result<ignore::Walk> {
|
|
197
|
+
let snapshot_glob = snapshot_dirname.join("*");
|
|
198
|
+
|
|
199
|
+
let glob_override = OverrideBuilder::new(test_path)
|
|
200
|
+
.add(glob_filter.unwrap_or("*"))?
|
|
201
|
+
.add(
|
|
202
|
+
snapshot_glob
|
|
203
|
+
.to_str()
|
|
204
|
+
.expect("snapshot glob should be valid utf-8"),
|
|
205
|
+
)?
|
|
206
|
+
.build()?;
|
|
207
|
+
|
|
208
|
+
let walker = WalkBuilder::new(test_path)
|
|
209
|
+
.types(config_file_type())
|
|
210
|
+
.overrides(glob_override)
|
|
211
|
+
.build();
|
|
212
|
+
|
|
213
|
+
Ok(walker)
|
|
214
|
+
}
|
|
215
|
+
|
|
188
216
|
pub fn read_test_files(
|
|
189
217
|
base_dir: &Path,
|
|
190
|
-
|
|
191
|
-
|
|
218
|
+
test_dirname: &Path,
|
|
219
|
+
snapshot_dirname: Option<&Path>,
|
|
220
|
+
glob_filter: Option<&str>,
|
|
192
221
|
) -> Result<TestHarness> {
|
|
193
222
|
let mut test_cases = vec![];
|
|
194
223
|
let mut snapshots = HashMap::new();
|
|
195
224
|
let mut path_map = HashMap::new();
|
|
196
|
-
let
|
|
197
|
-
let
|
|
198
|
-
let
|
|
199
|
-
let walker =
|
|
200
|
-
.
|
|
201
|
-
.build();
|
|
225
|
+
let test_path = base_dir.join(test_dirname);
|
|
226
|
+
let snapshot_dirname = snapshot_dirname.unwrap_or_else(|| SNAPSHOT_DIR.as_ref());
|
|
227
|
+
let snapshot_path = test_path.join(snapshot_dirname);
|
|
228
|
+
let walker = build_test_dir_walker(&test_path, snapshot_dirname, glob_filter)
|
|
229
|
+
.with_context(|| EC::TestCaseGlobFilter)?;
|
|
202
230
|
for dir in walker {
|
|
203
|
-
let config_file = dir.with_context(|| EC::WalkRuleDir(
|
|
231
|
+
let config_file = dir.with_context(|| EC::WalkRuleDir(test_path.clone()))?;
|
|
204
232
|
// file_type is None only if it is stdin, safe to unwrap here
|
|
205
233
|
if !config_file
|
|
206
234
|
.file_type()
|
|
@@ -211,14 +239,14 @@ pub fn read_test_files(
|
|
|
211
239
|
}
|
|
212
240
|
let path = config_file.path();
|
|
213
241
|
let yaml = read_to_string(path).with_context(|| EC::ReadRule(path.to_path_buf()))?;
|
|
214
|
-
if path.starts_with(&
|
|
242
|
+
if path.starts_with(&snapshot_path) {
|
|
215
243
|
let snapshot: TestSnapshots =
|
|
216
244
|
from_str(&yaml).with_context(|| EC::ParseTest(path.to_path_buf()))?;
|
|
217
245
|
snapshots.insert(snapshot.id.clone(), snapshot);
|
|
218
246
|
} else {
|
|
219
247
|
let test_case: TestCase =
|
|
220
248
|
from_str(&yaml).with_context(|| EC::ParseTest(path.to_path_buf()))?;
|
|
221
|
-
path_map.insert(test_case.id.clone(),
|
|
249
|
+
path_map.insert(test_case.id.clone(), test_path.join(snapshot_dirname));
|
|
222
250
|
test_cases.push(test_case);
|
|
223
251
|
}
|
|
224
252
|
}
|
|
@@ -229,14 +257,17 @@ pub fn read_test_files(
|
|
|
229
257
|
})
|
|
230
258
|
}
|
|
231
259
|
|
|
260
|
+
/// Returns the base_directory where config is and config object.
|
|
232
261
|
pub fn read_config_from_dir<P: AsRef<Path>>(path: P) -> Result<Option<(PathBuf, AstGrepConfig)>> {
|
|
233
|
-
let config_path =
|
|
262
|
+
let mut config_path =
|
|
234
263
|
find_config_path_with_default(None, Some(path.as_ref())).context(EC::ReadConfiguration)?;
|
|
235
264
|
if !config_path.is_file() {
|
|
236
265
|
return Ok(None);
|
|
237
266
|
}
|
|
238
267
|
let config_str = read_to_string(&config_path).context(EC::ReadConfiguration)?;
|
|
239
268
|
let sg_config = from_str(&config_str).context(EC::ParseConfiguration)?;
|
|
269
|
+
// remove sgconfig.yml from the path
|
|
270
|
+
config_path.pop(); // ./sg_config -> ./
|
|
240
271
|
Ok(Some((config_path, sg_config)))
|
|
241
272
|
}
|
|
242
273
|
|
|
@@ -268,12 +299,13 @@ fn find_config_path_with_default(
|
|
|
268
299
|
}
|
|
269
300
|
}
|
|
270
301
|
|
|
302
|
+
/// File types to ignore
|
|
271
303
|
#[derive(Clone, Copy, Deserialize, Serialize, ValueEnum)]
|
|
272
304
|
pub enum IgnoreFile {
|
|
273
305
|
/// Search hidden files and directories. By default, hidden files and directories are skipped.
|
|
274
306
|
Hidden,
|
|
275
307
|
/// Don't respect .ignore files.
|
|
276
|
-
/// This does *not* affect whether
|
|
308
|
+
/// This does *not* affect whether ast-grep will ignore files and directories whose names begin with a dot.
|
|
277
309
|
/// For that, use --no-ignore hidden.
|
|
278
310
|
Dot,
|
|
279
311
|
/// Don't respect ignore files that are manually configured for the repository such as git's '.git/info/exclude'.
|
|
@@ -4,8 +4,6 @@ use anyhow::{Error, Result};
|
|
|
4
4
|
use std::fmt;
|
|
5
5
|
use std::path::PathBuf;
|
|
6
6
|
|
|
7
|
-
use crate::utils::ansi_link;
|
|
8
|
-
|
|
9
7
|
const DOC_SITE_HOST: &str = "https://ast-grep.github.io";
|
|
10
8
|
const PATTERN_GUIDE: Option<&str> = Some("/guide/pattern-syntax.html");
|
|
11
9
|
const CONFIG_GUIDE: Option<&str> = Some("/guide/rule-config.html");
|
|
@@ -43,6 +41,7 @@ pub enum ErrorContext {
|
|
|
43
41
|
WriteFile(PathBuf),
|
|
44
42
|
// Test
|
|
45
43
|
TestFail(String),
|
|
44
|
+
TestCaseGlobFilter,
|
|
46
45
|
// New
|
|
47
46
|
ProjectAlreadyExist,
|
|
48
47
|
ProjectNotExist,
|
|
@@ -63,7 +62,8 @@ impl ErrorContext {
|
|
|
63
62
|
NoTestDirConfigured | NoUtilDirConfigured => 4,
|
|
64
63
|
ReadConfiguration | ReadRule(_) | WalkRuleDir(_) | WriteFile(_) => 5,
|
|
65
64
|
StdInIsNotInteractive => 6,
|
|
66
|
-
ParseTest(_) | ParseRule(_) | ParseConfiguration | GlobPattern | ParsePattern
|
|
65
|
+
ParseTest(_) | ParseRule(_) | ParseConfiguration | GlobPattern | ParsePattern
|
|
66
|
+
| TestCaseGlobFilter => 8,
|
|
67
67
|
ProjectAlreadyExist | FileAlreadyExist(_) => 17,
|
|
68
68
|
InsufficientCLIArgument(_) => 22,
|
|
69
69
|
OpenEditor | StartLanguageServer => 126,
|
|
@@ -181,6 +181,11 @@ impl ErrorMessage {
|
|
|
181
181
|
"You can use ast-grep playground to debug your rules and test cases.",
|
|
182
182
|
PLAYGROUND,
|
|
183
183
|
),
|
|
184
|
+
TestCaseGlobFilter => Self::new(
|
|
185
|
+
"Cannot parse the test case glob pattern.",
|
|
186
|
+
"The pattern provided to filter test cases to run is not a valid glob. Please refer to the doc and fix the error.",
|
|
187
|
+
CLI_USAGE,
|
|
188
|
+
),
|
|
184
189
|
ProjectAlreadyExist => Self::new(
|
|
185
190
|
"ast-grep project already exists.",
|
|
186
191
|
"You are already inside a sub-folder of an ast-grep project. Try finding sgconfig.yml in ancestor directory?",
|
|
@@ -231,6 +236,17 @@ pub fn exit_with_error(error: Error) -> Result<()> {
|
|
|
231
236
|
Err(error)
|
|
232
237
|
}
|
|
233
238
|
|
|
239
|
+
// use raw ansi escape code to render links in terminal. references:
|
|
240
|
+
// https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
|
241
|
+
// https://github.com/zkat/miette/blob/c25676cb1f4266c2607836e6359f15b9cbd8637e/src/handlers/graphical.rs#L186
|
|
242
|
+
fn ansi_link(url: String) -> String {
|
|
243
|
+
format!(
|
|
244
|
+
"\u{1b}]8;;{}\u{1b}\\{}\u{1b}]8;;\u{1b}\\",
|
|
245
|
+
url,
|
|
246
|
+
ansi_term::Color::Cyan.italic().paint(&url)
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
234
250
|
struct ErrorFormat<'a> {
|
|
235
251
|
context: &'a ErrorContext,
|
|
236
252
|
inner: &'a Error,
|
|
@@ -158,6 +158,9 @@ mod test_cli {
|
|
|
158
158
|
ok("run -p test dir1 dir2 dir3"); // multiple paths
|
|
159
159
|
ok("run -p testm -r restm -U"); // update all
|
|
160
160
|
ok("run -p testm -r restm --update-all"); // update all
|
|
161
|
+
ok("run -p test --json compact"); // argument after --json should not be parsed as JsonStyle
|
|
162
|
+
ok("run -p test --json=pretty dir");
|
|
163
|
+
ok("run -p test --json dir"); // arg after --json should not be parsed as JsonStyle
|
|
161
164
|
error("run test");
|
|
162
165
|
error("run --debug-query test"); // missing lang
|
|
163
166
|
error("run -r Test dir");
|
|
@@ -185,6 +188,8 @@ mod test_cli {
|
|
|
185
188
|
error("scan -f gitlab");
|
|
186
189
|
error("scan -f github -i");
|
|
187
190
|
error("scan -f local");
|
|
191
|
+
error("scan --json=dir"); // wrong json flag
|
|
192
|
+
error("scan --json= not-pretty"); // wrong json flag
|
|
188
193
|
}
|
|
189
194
|
|
|
190
195
|
#[test]
|
|
@@ -65,11 +65,10 @@ impl NewArg {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
fn choose_language(&self) -> Result<SgLang> {
|
|
68
|
-
if self.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.unwrap_or_else(|| Err(anyhow::anyhow!(EC::InsufficientCLIArgument("lang"))))
|
|
68
|
+
if let Some(lang) = self.lang {
|
|
69
|
+
Ok(lang)
|
|
70
|
+
} else if self.yes {
|
|
71
|
+
Err(anyhow::anyhow!(EC::InsufficientCLIArgument("lang")))
|
|
73
72
|
} else {
|
|
74
73
|
Ok(inquire::Select::new("Choose rule's language", SgLang::all_langs()).prompt()?)
|
|
75
74
|
}
|
|
@@ -119,12 +118,12 @@ pub fn run_create_new(mut arg: NewArg) -> Result<()> {
|
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
|
|
121
|
+
// base_dir, config
|
|
122
122
|
type FoundConfig = (PathBuf, AstGrepConfig);
|
|
123
123
|
|
|
124
124
|
fn run_create_entity(entity: Entity, arg: NewArg) -> Result<()> {
|
|
125
125
|
// check if we are under a project dir
|
|
126
|
-
if let Some(
|
|
127
|
-
found.0.pop(); // remove sgconfig.yml from the path
|
|
126
|
+
if let Some(found) = read_config_from_dir(&arg.base_dir)? {
|
|
128
127
|
return do_create_entity(entity, found, arg);
|
|
129
128
|
}
|
|
130
129
|
// check if we creating a project
|
|
@@ -148,10 +147,10 @@ fn do_create_entity(entity: Entity, found: FoundConfig, arg: NewArg) -> Result<(
|
|
|
148
147
|
|
|
149
148
|
fn ask_entity_type(arg: NewArg) -> Result<()> {
|
|
150
149
|
// 1. check if we are under a sgconfig.yml
|
|
151
|
-
if let Some(
|
|
150
|
+
if let Some(found) = read_config_from_dir(&arg.base_dir)? {
|
|
152
151
|
// 2. ask users what to create if yes
|
|
153
152
|
let entity = arg.ask_entity_type()?;
|
|
154
|
-
do_create_entity(entity,
|
|
153
|
+
do_create_entity(entity, found, arg)
|
|
155
154
|
} else {
|
|
156
155
|
// 3. ask users to provide project info if no sgconfig found
|
|
157
156
|
print!("No sgconfig.yml found. ");
|
|
@@ -192,7 +191,7 @@ fn default_rule(id: &str, lang: SgLang) -> String {
|
|
|
192
191
|
format!(
|
|
193
192
|
r#"id: {id}
|
|
194
193
|
message: Add your rule message here....
|
|
195
|
-
severity: error # error, warning,
|
|
194
|
+
severity: error # error, warning, info, hint
|
|
196
195
|
language: {lang}
|
|
197
196
|
rule:
|
|
198
197
|
pattern: Your Rule Pattern here...
|
|
@@ -202,8 +201,7 @@ rule:
|
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
fn create_new_rule(found: FoundConfig, arg: NewArg) -> Result<()> {
|
|
205
|
-
let base_dir = found
|
|
206
|
-
let sg_config = found.1;
|
|
204
|
+
let (base_dir, sg_config) = found;
|
|
207
205
|
let name = arg.ask_name("rule")?;
|
|
208
206
|
let rule_dir = if sg_config.rule_dirs.len() > 1 {
|
|
209
207
|
let dirs = sg_config.rule_dirs.iter().map(|p| p.display()).collect();
|
|
@@ -279,8 +277,7 @@ rule:
|
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
fn create_new_util(found: FoundConfig, arg: NewArg) -> Result<()> {
|
|
282
|
-
let base_dir = found
|
|
283
|
-
let sg_config = found.1;
|
|
280
|
+
let (base_dir, sg_config) = found;
|
|
284
281
|
let Some(utils) = sg_config.util_dirs else {
|
|
285
282
|
return Err(anyhow::anyhow!(EC::NoUtilDirConfigured));
|
|
286
283
|
};
|
|
@@ -339,6 +336,19 @@ mod test {
|
|
|
339
336
|
Ok(())
|
|
340
337
|
}
|
|
341
338
|
|
|
339
|
+
fn create_util(temp: &Path) -> Result<()> {
|
|
340
|
+
let arg = NewArg {
|
|
341
|
+
entity: Some(Entity::Util),
|
|
342
|
+
name: Some("test-utils".into()),
|
|
343
|
+
lang: Some(SupportLang::Rust.into()),
|
|
344
|
+
yes: true,
|
|
345
|
+
base_dir: temp.to_path_buf(),
|
|
346
|
+
};
|
|
347
|
+
run_create_new(arg).unwrap();
|
|
348
|
+
assert!(temp.join("utils/test-utils.yml").exists());
|
|
349
|
+
Ok(())
|
|
350
|
+
}
|
|
351
|
+
|
|
342
352
|
#[test]
|
|
343
353
|
fn test_create_new() -> Result<()> {
|
|
344
354
|
let dir = TempDir::new("sgtest")?;
|
|
@@ -347,4 +357,13 @@ mod test {
|
|
|
347
357
|
drop(dir); // drop at the end since temp dir clean up is done in Drop
|
|
348
358
|
Ok(())
|
|
349
359
|
}
|
|
360
|
+
|
|
361
|
+
#[test]
|
|
362
|
+
fn test_create_util() -> Result<()> {
|
|
363
|
+
let dir = TempDir::new("sgtest")?;
|
|
364
|
+
create_project(dir.path())?;
|
|
365
|
+
create_util(dir.path())?;
|
|
366
|
+
drop(dir); // drop at the end since temp dir clean up is done in Drop
|
|
367
|
+
Ok(())
|
|
368
|
+
}
|
|
350
369
|
}
|
|
@@ -5,7 +5,7 @@ use clap::ValueEnum;
|
|
|
5
5
|
|
|
6
6
|
use anyhow::Result;
|
|
7
7
|
use ast_grep_core::{NodeMatch as SgNodeMatch, StrDoc};
|
|
8
|
-
|
|
8
|
+
use codespan_reporting::files::SimpleFile;
|
|
9
9
|
use std::io::{Stdout, Write};
|
|
10
10
|
use std::sync::Mutex;
|
|
11
11
|
|