Skip to content

Commit

Permalink
Better error reporting when manifests fail to parse. (obi1kenobi#379)
Browse files Browse the repository at this point in the history
* Better error reporting when manifests fail to parse.

* fmt.
  • Loading branch information
obi1kenobi authored Feb 21, 2023
1 parent 863f533 commit 17d33d7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 23 deletions.
19 changes: 9 additions & 10 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,34 @@ impl Manifest {
// Parsing via `cargo_toml::Manifest::from_path()` is preferable to parsing from a string,
// because inspection of surrounding files is sometimes necessary to determine
// the existence of lib targets and ensure proper handling of workspace inheritance.

let parsed = cargo_toml::Manifest::from_path(&path)
.with_context(|| format!("Failed when reading {}", path.display()))?;
.with_context(|| format!("failed when reading {}", path.display()))?;

Ok(Self { path, parsed })
}
}

pub(crate) fn get_package_name(manifest: &Manifest) -> anyhow::Result<&str> {
let package = manifest.parsed.package.as_ref().ok_or_else(|| {
anyhow::format_err!(
"Failed to parse {}: no `package` table",
let package = manifest.parsed.package.as_ref().with_context(|| {
format!(
"failed to parse {}: no `package` table",
manifest.path.display()
)
})?;
Ok(&package.name)
}

pub(crate) fn get_package_version(manifest: &Manifest) -> anyhow::Result<&str> {
let package = manifest.parsed.package.as_ref().ok_or_else(|| {
anyhow::format_err!(
"Failed to parse {}: no `package` table",
let package = manifest.parsed.package.as_ref().with_context(|| {
format!(
"failed to parse {}: no `package` table",
manifest.path.display()
)
})?;
let version = package.version.get().with_context(|| {
format!(
"Failed to retrieve package version from {}",
manifest.path.display(),
"failed to retrieve package version from {}",
manifest.path.display()
)
})?;
Ok(version)
Expand Down
50 changes: 37 additions & 13 deletions src/rustdoc_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};

use anyhow::Context;
use crates_index::Crate;
use itertools::Itertools;

use crate::manifest::Manifest;
use crate::rustdoc_cmd::RustdocCommand;
Expand Down Expand Up @@ -325,7 +326,8 @@ impl RustdocGenerator for RustdocFromFile {
#[derive(Debug)]
pub(crate) struct RustdocFromProjectRoot {
project_root: PathBuf,
lookup: std::collections::HashMap<String, Manifest>,
manifests: std::collections::HashMap<String, Manifest>,
manifest_errors: std::collections::HashMap<PathBuf, anyhow::Error>,
target_root: PathBuf,
}

Expand All @@ -337,20 +339,31 @@ impl RustdocFromProjectRoot {
project_root: &std::path::Path,
target_root: &std::path::Path,
) -> anyhow::Result<Self> {
let mut lookup = std::collections::HashMap::new();
let mut manifests = std::collections::HashMap::new();
let mut manifest_errors = std::collections::HashMap::new();
for result in ignore::Walk::new(project_root) {
let entry = result?;
if entry.file_name() == "Cargo.toml" {
if let Ok(manifest) = crate::manifest::Manifest::parse(entry.into_path()) {
if let Ok(name) = crate::manifest::get_package_name(&manifest) {
lookup.insert(name.to_string(), manifest);
let path = entry.into_path();
match crate::manifest::Manifest::parse(path.clone()) {
Ok(manifest) => match crate::manifest::get_package_name(&manifest) {
Ok(name) => {
manifests.insert(name.to_string(), manifest);
}
Err(e) => {
manifest_errors.insert(path, e);
}
},
Err(e) => {
manifest_errors.insert(path, e);
}
}
}
}
Ok(Self {
project_root: project_root.to_owned(),
lookup,
manifests,
manifest_errors,
target_root: target_root.to_owned(),
})
}
Expand All @@ -363,13 +376,24 @@ impl RustdocGenerator for RustdocFromProjectRoot {
rustdoc_cmd: &RustdocCommand,
crate_data: CrateDataForRustdoc,
) -> anyhow::Result<PathBuf> {
let manifest: &Manifest = self.lookup.get(crate_data.name).with_context(|| {
format!(
"package `{}` not found in {}",
crate_data.name,
self.project_root.display()
)
})?;
let manifest: &Manifest = self
.manifests
.get(crate_data.name)
.with_context(|| {
let errors = self
.manifest_errors
.values()
.map(|error| format!(" {error:#},"))
.join("\n");
format!("possibly due to errors: [\n{errors}\n]")
})
.with_context(|| {
format!(
"package `{}` not found in {}",
crate_data.name,
self.project_root.display(),
)
})?;
generate_rustdoc(
config,
rustdoc_cmd,
Expand Down

0 comments on commit 17d33d7

Please sign in to comment.