Skip to content

Commit 39a4024

Browse files
committed
avoid parsing Cargo.toml
• forwards compatability hazard per MaulingMonkey/cargo-vs#5 • metadata has everything we need on modern cargo • minor regression on e.g. cargo 1.47.0: might not generate docs/homepage links
1 parent 26c8cff commit 39a4024

File tree

2 files changed

+19
-101
lines changed

2 files changed

+19
-101
lines changed

src/metadata.rs

+13-95
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,26 @@ pub(crate) type PackageId = String;
1616
/// `{ ... }`
1717
#[derive(Deserialize, Debug)]
1818
pub(crate) struct Root {
19-
#[serde(rename="workspace_root")]
20-
pub workspace: WorkspaceRoot,
19+
pub workspace_root: PathBuf,
2120
pub packages: Vec<PackageRef>,
2221
pub workspace_members: HashSet<PackageId>,
23-
// metadata
22+
pub metadata: Option<Metadata>,
2423
// ...
2524
}
2625

27-
/// cargo metadata<br>
28-
/// `{ "workspace_root": "..." }`
29-
#[derive(Debug)]
30-
pub(crate) struct WorkspaceRoot {
31-
pub dir: PathBuf,
32-
pub toml: Option<WorkspaceToml>,
33-
}
34-
3526
/// cargo metadata<br>
3627
/// `{ "packages": [ ... ] }`
3728
#[derive(Deserialize, Debug)]
3829
pub(crate) struct PackageRef {
39-
#[serde(rename="manifest_path")]
40-
pub manifest: ManifestRef,
41-
pub id: PackageId,
42-
pub name: String,
43-
pub version: String,
44-
pub targets: Vec<PackageTarget>,
45-
// metadata
30+
pub manifest_path: PathBuf,
31+
pub id: PackageId,
32+
pub name: String,
33+
pub version: String,
34+
pub repository: Option<Url>, // present in cargo +1.47.0 metadata
35+
pub documentation: Option<Url>, // MISSING in cargo +1.47.0 metadata, might lead to fewer tasks.json links in older cargo
36+
pub homepage: Option<Url>, // MISSING in cargo +1.47.0 metadata, might lead to fewer tasks.json links in older cargo
37+
pub targets: Vec<PackageTarget>,
38+
pub metadata: Option<Metadata>,
4639
// ...
4740
}
4841

@@ -59,55 +52,10 @@ pub(crate) struct PackageTarget {
5952
//pub test: bool,
6053
}
6154

62-
63-
6455
/// cargo metadata<br>
65-
/// `{ "packages": [ { "manifest_path": "..." } ] }`
66-
#[derive(Debug)]
67-
pub(crate) struct ManifestRef {
68-
pub path: PathBuf,
69-
pub toml: Manifest,
70-
}
71-
72-
73-
74-
/// Cargo.toml<br>
75-
/// (root - might contains `[workspace]`)
76-
#[derive(Deserialize, Debug)]
77-
pub(crate) struct WorkspaceToml {
78-
#[serde(default)]
79-
pub metadata: Metadata,
80-
}
81-
82-
/// Cargo.toml<br>
83-
/// (root - expected to contain `[package]`)
84-
#[derive(Deserialize, Debug)]
85-
pub(crate) struct Manifest {
86-
pub package: Package,
87-
#[serde(default)]
88-
pub metadata: Metadata,
89-
// ...
90-
}
91-
92-
93-
/// Cargo.toml<br>
94-
/// `[package]`
56+
/// `{ "packages": [ { "metadata": {...} } ] }` or<br>
57+
/// `{ "metadata": {...} }` (workspace)
9558
#[derive(Deserialize, Debug)]
96-
pub(crate) struct Package {
97-
pub name: String,
98-
pub version: String,
99-
pub repository: Option<Url>,
100-
pub documentation: Option<Url>,
101-
pub homepage: Option<Url>,
102-
#[serde(default)]
103-
pub metadata: Metadata,
104-
// ...
105-
}
106-
107-
/// Cargo.toml<br>
108-
/// `[package.metadata]` or<br>
109-
/// `[workspace.metadata]`
110-
#[derive(Deserialize, Debug, Default)]
11159
pub(crate) struct Metadata {
11260
pub local_install: Option<de::IgnoredAny>,
11361
#[serde(rename="cargo-vsc")] #[serde(default)] pub cargo_vsc: MetadataCargoVsc,
@@ -140,33 +88,3 @@ impl Root {
14088
serde_json::from_str(&stdout).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))
14189
}
14290
}
143-
144-
impl<'de> Deserialize<'de> for WorkspaceRoot {
145-
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
146-
let dir = PathBuf::deserialize(d)?;
147-
let file = dir.join("Cargo.toml");
148-
let text = match std::fs::read_to_string(&file) {
149-
Ok(text) => text,
150-
Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(Self { dir, toml: None }),
151-
Err(err) => return Err(de::Error::custom(&format!("unable to read {}: {}", file.display(), err))),
152-
};
153-
Ok(Self {
154-
toml: Some(toml::from_str(&text).map_err(|err| de::Error::custom(&format!("unable to parse {}: {}", file.display(), err)))?),
155-
dir,
156-
})
157-
}
158-
}
159-
160-
impl<'de> Deserialize<'de> for ManifestRef {
161-
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
162-
let path = PathBuf::deserialize(d)?;
163-
let text = match std::fs::read_to_string(&path) {
164-
Ok(text) => text,
165-
Err(err) => return Err(de::Error::custom(&format!("unable to read {}: {}", path.display(), err))),
166-
};
167-
Ok(Self {
168-
toml: toml::from_str(&text).map_err(|err| de::Error::custom(&format!("unable to parse {}: {}", path.display(), err)))?,
169-
path,
170-
})
171-
}
172-
}

src/run.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn run() {
2222
}
2323

2424
fn create_vscode_dir(meta: &metadata::Root) -> io::Result<PathBuf> {
25-
let vscode = meta.workspace.dir.join(".vscode");
25+
let vscode = meta.workspace_root.join(".vscode");
2626
match std::fs::create_dir(&vscode) {
2727
Ok(()) => {
2828
std::fs::write(vscode.join(".gitignore"), "*").map_err(|err| io::Error::new(err.kind(), format!("unable to create .gitignore: {}", err)))?; // XXX: remap err for more context?
@@ -171,10 +171,10 @@ fn create_vscode_tasks_json(Context { meta, vscode, .. }: &Context) -> io::Resul
171171
let path = vscode.join("tasks.json");
172172
let mut o = create_json(&path)?;
173173

174-
let has_any_local_install = meta.workspace.toml.as_ref().map_or(false, |ws| ws.metadata.local_install.is_some());
174+
let has_any_local_install = meta.metadata.as_ref().and_then(|m| m.local_install).is_some();
175175
// TODO: also install for packages: meta.packages.iter().any(|p| meta.workspace_members.contains(&p.id) && p.manifest.toml.metadata.local_install.is_some());
176176

177-
let simple = meta.workspace.toml.as_ref().and_then(|ws| ws.metadata.cargo_vsc.simple).unwrap_or(true);
177+
let simple = meta.metadata.as_ref().and_then(|m| m.cargo_vsc.simple).unwrap_or(true);
178178

179179
writeln!(o, "{{")?;
180180
writeln!(o, " \"version\": \"2.0.0\",")?;
@@ -322,13 +322,13 @@ fn create_vscode_tasks_json(Context { meta, vscode, .. }: &Context) -> io::Resul
322322
}
323323
}
324324

325-
if let Some(repository) = package.manifest.toml.package.repository.as_ref() {
325+
if let Some(repository) = package.repository.as_ref() {
326326
write_open_link(&mut o, &format!("open repository ({})", package.name), &repository, "")?;
327327
}
328-
if let Some(documentation) = package.manifest.toml.package.documentation.as_ref() {
328+
if let Some(documentation) = package.documentation.as_ref() {
329329
write_open_link(&mut o, &format!("open documentation ({})", package.name), &documentation, "")?;
330330
}
331-
if let Some(homepage) = package.manifest.toml.package.homepage.as_ref() {
331+
if let Some(homepage) = package.homepage.as_ref() {
332332
write_open_link(&mut o, &format!("open homepage ({})", package.name), &homepage, "")?;
333333
}
334334
}

0 commit comments

Comments
 (0)