Skip to content

Commit fc439ed

Browse files
committed
ci(ast_tools): run "AST Changes" CI task when dependency crates change (#15603)
#15565 made `oxc_ast_tools` depend on local workspace versions of various crates. Add those crates to the watch list for "AST Changes" CI task, so if changes are made in them, `ast_tools` codegen will run to ensure generated code has been updated to reflect those changes. In particular, this will prevent generated code getting out of sync when changes to minifier affect the generated code.
1 parent 74033bd commit fc439ed

File tree

6 files changed

+133
-60
lines changed

6 files changed

+133
-60
lines changed

.github/generated/ast_changes_watch_list.yml

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,66 +12,27 @@ src:
1212
- 'apps/oxlint/src-js/generated/visitor.d.ts'
1313
- 'apps/oxlint/src-js/generated/walk.js'
1414
- 'apps/oxlint/src/generated/raw_transfer_constants.rs'
15-
- 'crates/oxc_allocator/src/generated/assert_layouts.rs'
16-
- 'crates/oxc_allocator/src/generated/fixed_size_constants.rs'
17-
- 'crates/oxc_allocator/src/pool/fixed_size.rs'
18-
- 'crates/oxc_ast/src/ast/comment.rs'
19-
- 'crates/oxc_ast/src/ast/js.rs'
20-
- 'crates/oxc_ast/src/ast/jsx.rs'
21-
- 'crates/oxc_ast/src/ast/literal.rs'
22-
- 'crates/oxc_ast/src/ast/ts.rs'
23-
- 'crates/oxc_ast/src/generated/assert_layouts.rs'
24-
- 'crates/oxc_ast/src/generated/ast_builder.rs'
25-
- 'crates/oxc_ast/src/generated/ast_kind.rs'
26-
- 'crates/oxc_ast/src/generated/derive_clone_in.rs'
27-
- 'crates/oxc_ast/src/generated/derive_content_eq.rs'
28-
- 'crates/oxc_ast/src/generated/derive_dummy.rs'
29-
- 'crates/oxc_ast/src/generated/derive_estree.rs'
30-
- 'crates/oxc_ast/src/generated/derive_get_address.rs'
31-
- 'crates/oxc_ast/src/generated/derive_get_span.rs'
32-
- 'crates/oxc_ast/src/generated/derive_get_span_mut.rs'
33-
- 'crates/oxc_ast/src/generated/derive_take_in.rs'
34-
- 'crates/oxc_ast/src/generated/get_id.rs'
35-
- 'crates/oxc_ast/src/serialize/basic.rs'
36-
- 'crates/oxc_ast/src/serialize/js.rs'
37-
- 'crates/oxc_ast/src/serialize/jsx.rs'
38-
- 'crates/oxc_ast/src/serialize/literal.rs'
39-
- 'crates/oxc_ast/src/serialize/mod.rs'
40-
- 'crates/oxc_ast/src/serialize/ts.rs'
15+
- 'crates/oxc_allocator/src/**'
16+
- 'crates/oxc_ast/src/**'
4117
- 'crates/oxc_ast_macros/src/generated/derived_traits.rs'
4218
- 'crates/oxc_ast_macros/src/generated/structs.rs'
4319
- 'crates/oxc_ast_macros/src/lib.rs'
44-
- 'crates/oxc_ast_visit/src/generated/utf8_to_utf16_converter.rs'
45-
- 'crates/oxc_ast_visit/src/generated/visit.rs'
46-
- 'crates/oxc_ast_visit/src/generated/visit_mut.rs'
20+
- 'crates/oxc_ast_visit/src/**'
21+
- 'crates/oxc_codegen/src/**'
22+
- 'crates/oxc_data_structures/src/**'
4723
- 'crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs'
4824
- 'crates/oxc_formatter/src/ast_nodes/generated/format.rs'
4925
- 'crates/oxc_linter/src/generated/assert_layouts.rs'
5026
- 'crates/oxc_linter/src/lib.rs'
27+
- 'crates/oxc_minifier/src/**'
28+
- 'crates/oxc_parser/src/**'
5129
- 'crates/oxc_regular_expression/src/ast.rs'
5230
- 'crates/oxc_regular_expression/src/generated/assert_layouts.rs'
5331
- 'crates/oxc_regular_expression/src/generated/derive_clone_in.rs'
5432
- 'crates/oxc_regular_expression/src/generated/derive_content_eq.rs'
5533
- 'crates/oxc_regular_expression/src/generated/derive_get_address.rs'
56-
- 'crates/oxc_span/src/generated/assert_layouts.rs'
57-
- 'crates/oxc_span/src/generated/derive_dummy.rs'
58-
- 'crates/oxc_span/src/generated/derive_estree.rs'
59-
- 'crates/oxc_span/src/source_type.rs'
60-
- 'crates/oxc_span/src/span.rs'
61-
- 'crates/oxc_syntax/src/comment_node.rs'
62-
- 'crates/oxc_syntax/src/generated/assert_layouts.rs'
63-
- 'crates/oxc_syntax/src/generated/derive_clone_in.rs'
64-
- 'crates/oxc_syntax/src/generated/derive_content_eq.rs'
65-
- 'crates/oxc_syntax/src/generated/derive_dummy.rs'
66-
- 'crates/oxc_syntax/src/generated/derive_estree.rs'
67-
- 'crates/oxc_syntax/src/lib.rs'
68-
- 'crates/oxc_syntax/src/module_record.rs'
69-
- 'crates/oxc_syntax/src/number.rs'
70-
- 'crates/oxc_syntax/src/operator.rs'
71-
- 'crates/oxc_syntax/src/reference.rs'
72-
- 'crates/oxc_syntax/src/scope.rs'
73-
- 'crates/oxc_syntax/src/serialize.rs'
74-
- 'crates/oxc_syntax/src/symbol.rs'
34+
- 'crates/oxc_span/src/**'
35+
- 'crates/oxc_syntax/src/**'
7536
- 'crates/oxc_traverse/src/generated/scopes_collector.rs'
7637
- 'napi/parser/generated/constants.js'
7738
- 'napi/parser/generated/deserialize/js.js'

Cargo.lock

Lines changed: 61 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ similar-asserts = "1.7.0" # Test diff assertions
225225
smallvec = { version = "1.15.1", features = ["union"] } # Stack-allocated vectors
226226
tempfile = "3.23.0" # Temporary files
227227
tokio = { version = "1.48.0", default-features = false } # Async runtime
228+
toml = { version = "0.9.8" }
228229
tower-lsp-server = "0.22.1" # LSP server framework
229230
tracing-subscriber = "0.3.20" # Tracing implementation
230231
ureq = { version = "3.1.4", default-features = false } # HTTP client

tasks/ast_tools/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ rustc-hash = { workspace = true }
4848
serde = { workspace = true, features = ["derive"] }
4949
serde_json = { workspace = true }
5050
syn = { workspace = true, features = ["clone-impls", "derive", "extra-traits", "full", "parsing", "printing", "proc-macro"] }
51+
toml = { workspace = true }
5152

5253
[features]
5354
default = ["generate-js"]

tasks/ast_tools/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ fn main() {
367367
// Add CI filter file to outputs.
368368
// Skip this step if JS generators are disabled, because not all files are generated.
369369
#[cfg(feature = "generate-js")]
370-
outputs.push(generate_ci_filter(&outputs));
370+
outputs.push(generate_ci_filter(&outputs, &codegen));
371371

372372
// Write outputs to disk
373373
if !options.dry_run {
@@ -383,12 +383,12 @@ fn main() {
383383
/// unless relevant files have changed.
384384
///
385385
/// List includes source files, generated files, and all files in `oxc_ast_tools` itself.
386-
fn generate_ci_filter(outputs: &[RawOutput]) -> RawOutput {
386+
fn generate_ci_filter(outputs: &[RawOutput], codegen: &Codegen) -> RawOutput {
387387
log!("Generate CI filter... ");
388388

389389
let paths =
390390
SOURCE_PATHS.iter().copied().chain(outputs.iter().map(|output| output.path.as_str()));
391-
let output = Output::yaml_watch_list(AST_CHANGES_WATCH_LIST_PATH, paths);
391+
let output = Output::yaml_watch_list(AST_CHANGES_WATCH_LIST_PATH, paths, codegen);
392392

393393
log_success!();
394394

tasks/ast_tools/src/output/yaml.rs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::fmt::Write;
1+
use std::{fmt::Write, fs};
2+
3+
use rustc_hash::FxHashSet;
4+
5+
use crate::Codegen;
26

37
use super::{Output, add_header};
48

@@ -10,11 +14,52 @@ pub fn print_yaml(code: &str, generator_path: &str) -> String {
1014
impl Output {
1115
/// Generate a watch list YAML file.
1216
///
13-
/// The path of the watch list itself, `tasks/ast_tools/src/**`, and the CI workflow file are added to the list.
17+
/// The following are added to the list:
18+
/// * The watch list file itself
19+
/// * `ast_tools` crate
20+
/// * `oxc_*` dependencies of `ast_tools`
21+
/// * CI workflow file
1422
pub fn yaml_watch_list<'s>(
1523
watch_list_path: &'s str,
1624
paths: impl IntoIterator<Item = &'s str>,
25+
codegen: &Codegen,
1726
) -> Self {
27+
let mut paths = paths.into_iter().collect::<Vec<_>>();
28+
29+
// Get `oxc_*` dependencies of `ast_tools`.
30+
// `ast_tools` uses these crates, so generated code may change if these crates are changed.
31+
let cargo_toml = parse_toml("tasks/ast_tools/Cargo.toml", codegen);
32+
let dependency_crates = cargo_toml
33+
.get("dependencies")
34+
.and_then(|v| v.as_table())
35+
.unwrap()
36+
.keys()
37+
.map(String::as_str)
38+
.filter(|krate| {
39+
// Exclude crates which are not in this monorepo e.g. `oxc_index`
40+
krate.starts_with("oxc_") && codegen.root_path().join("crates").join(krate).is_dir()
41+
})
42+
.collect::<FxHashSet<_>>();
43+
44+
// Remove paths from `paths` which are in `src` dir of a dependency crate
45+
// (as `crate/{krate}/src/**` pattern will cover them anyway)
46+
paths.retain(|path| {
47+
if let Some(path) = path.strip_prefix("crates/")
48+
&& let Some((krate, path)) = path.split_once('/')
49+
&& path.starts_with("src/")
50+
{
51+
return !dependency_crates.contains(krate);
52+
}
53+
true
54+
});
55+
56+
// Get paths for dependency crates
57+
let dependency_crate_paths = dependency_crates
58+
.into_iter()
59+
.map(|krate| format!("crates/{krate}/src/**"))
60+
.collect::<Vec<_>>();
61+
62+
// Additional paths
1863
let additional_paths = [
1964
// This watch list file
2065
watch_list_path,
@@ -24,9 +69,13 @@ impl Output {
2469
".github/workflows/ci.yml",
2570
];
2671

27-
let mut paths = paths.into_iter().chain(additional_paths).collect::<Vec<_>>();
72+
// Add additional paths and dependency crate paths to `paths`, and sort
73+
paths.extend(
74+
additional_paths.into_iter().chain(dependency_crate_paths.iter().map(String::as_str)),
75+
);
2876
paths.sort_unstable();
2977

78+
// Generate YAML
3079
let mut code = "src:\n".to_string();
3180
for path in paths {
3281
writeln!(code, " - '{path}'").unwrap();
@@ -35,3 +84,9 @@ impl Output {
3584
Self::Yaml { path: watch_list_path.to_string(), code }
3685
}
3786
}
87+
88+
/// Parse TOML file.
89+
fn parse_toml(path: &str, codegen: &Codegen) -> toml::Table {
90+
let toml_content = fs::read_to_string(codegen.root_path().join(path)).unwrap();
91+
toml::from_str(&toml_content).unwrap()
92+
}

0 commit comments

Comments
 (0)