Skip to content

Commit a6a55c9

Browse files
Allow declaring cfg groups in rust-project.json, to help sharing common cfgs
1 parent 0daeb5c commit a6a55c9

File tree

5 files changed

+622
-4
lines changed

5 files changed

+622
-4
lines changed

crates/project-model/src/project_json.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl ProjectJson {
9898
crates: data
9999
.crates
100100
.into_iter()
101-
.map(|crate_data| {
101+
.map(|mut crate_data| {
102102
let root_module = absolutize_on_base(crate_data.root_module);
103103
let is_workspace_member = crate_data
104104
.is_workspace_member
@@ -122,6 +122,27 @@ impl ProjectJson {
122122
None => None,
123123
};
124124

125+
crate_data.cfg_groups.sort_unstable();
126+
crate_data.cfg_groups.dedup();
127+
let cfg = crate_data
128+
.cfg_groups
129+
.iter()
130+
.flat_map(|cfg_extend| {
131+
let cfg_group = data.cfg_groups.get(cfg_extend);
132+
match cfg_group {
133+
Some(cfg_group) => cfg_group.0.iter().cloned(),
134+
None => {
135+
tracing::error!(
136+
"Unknown cfg group `{cfg_extend}` in crate `{}`",
137+
crate_data.display_name.as_deref().unwrap_or("<unknown>"),
138+
);
139+
[].iter().cloned()
140+
}
141+
}
142+
})
143+
.chain(crate_data.cfg.0)
144+
.collect();
145+
125146
Crate {
126147
display_name: crate_data
127148
.display_name
@@ -131,7 +152,7 @@ impl ProjectJson {
131152
edition: crate_data.edition.into(),
132153
version: crate_data.version.as_ref().map(ToString::to_string),
133154
deps: crate_data.deps,
134-
cfg: crate_data.cfg,
155+
cfg,
135156
target: crate_data.target,
136157
env: crate_data.env,
137158
proc_macro_dylib_path: crate_data
@@ -306,11 +327,17 @@ pub enum RunnableKind {
306327
pub struct ProjectJsonData {
307328
sysroot: Option<Utf8PathBuf>,
308329
sysroot_src: Option<Utf8PathBuf>,
330+
#[serde(default)]
331+
cfg_groups: FxHashMap<String, CfgList>,
309332
crates: Vec<CrateData>,
310333
#[serde(default)]
311334
runnables: Vec<RunnableData>,
312335
}
313336

337+
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)]
338+
#[serde(transparent)]
339+
struct CfgList(#[serde(with = "cfg_")] Vec<CfgAtom>);
340+
314341
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
315342
struct CrateData {
316343
display_name: Option<String>,
@@ -319,9 +346,11 @@ struct CrateData {
319346
#[serde(default)]
320347
version: Option<semver::Version>,
321348
deps: Vec<Dep>,
349+
// Cannot be a hashset because that would mean an inconsistent order.
350+
#[serde(default)]
351+
cfg_groups: Vec<String>,
322352
#[serde(default)]
323-
#[serde(with = "cfg_")]
324-
cfg: Vec<CfgAtom>,
353+
cfg: CfgList,
325354
target: Option<String>,
326355
#[serde(default)]
327356
env: FxHashMap<String, String>,

crates/project-model/src/tests.rs

+6
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,12 @@ fn rust_project_hello_world_project_model() {
233233
);
234234
}
235235

236+
#[test]
237+
fn rust_project_cfg_groups() {
238+
let (crate_graph, _proc_macros) = load_rust_project("cfg-groups.json");
239+
check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]);
240+
}
241+
236242
#[test]
237243
fn rust_project_is_proc_macro_has_proc_macro_dep() {
238244
let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"sysroot_src": null,
3+
"cfg_groups": {
4+
"group1": ["group1_cfg=\"some_config\"", "group1_other_cfg=\"other_config\""],
5+
"group2": ["group2_cfg=\"yet_another_config\""]
6+
},
7+
"crates": [
8+
{
9+
"display_name": "hello_world",
10+
"root_module": "$ROOT$src/lib.rs",
11+
"edition": "2018",
12+
"cfg_groups": ["group1", "group2"],
13+
"deps": [],
14+
"is_workspace_member": true
15+
},
16+
{
17+
"display_name": "other_crate",
18+
"root_module": "$ROOT$src/lib.rs",
19+
"edition": "2018",
20+
"cfg_groups": ["group2"],
21+
"cfg": ["group2_cfg=\"fourth_config\"", "unrelated_cfg"],
22+
"deps": [],
23+
"is_workspace_member": true
24+
}
25+
]
26+
}

0 commit comments

Comments
 (0)