-
-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor data generation to be cleaner and more principled. (#1001)
cargo-semver-checks outgrew its previous data generation system. Over the previous 2+ years, this code was slowly turning into spaghetti as we discovered we needed to add ever more functionality and work around ever more issues. It was borderline unmaintainable, and impossible to extend in a meaningful fashion. As part of rust-lang/rust-project-goals#104, we aim to start supporting manifest linting. That would require generating more data -- not just rustdoc JSON but also project metadatasuch as package features and targets. Plumbing that data though the existing data generation spaghetti code was proving infeasible. This PR tackles the lion's share of the spaghetti problem. It introduces a new submodule, `data_generation`, that handles data generation tasks and has its own internal invariants and data structures which are not tied into CLI considerations like "should we use color when printing to the terminal". That will make it easier to extend with project metadata in subsequent PRs. There is still some clean-up work remaining -- this PR is just the start of that work. But here we untangle the biggest mess in the tool, which will let us move more quickly elsewhere.
- Loading branch information
1 parent
68611c4
commit 2615b5d
Showing
28 changed files
with
1,705 additions
and
810 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
use std::collections::BTreeMap; | ||
|
||
use crate::GlobalConfig; | ||
|
||
pub(crate) struct Callbacks<'a> { | ||
config: &'a mut GlobalConfig, | ||
|
||
// (crate_name, version, is_baseline) keys | ||
generate_starts: BTreeMap<(&'a str, &'a str, bool), std::time::Instant>, | ||
parse_starts: BTreeMap<(&'a str, &'a str, bool), std::time::Instant>, | ||
} | ||
|
||
impl<'a> Callbacks<'a> { | ||
pub(crate) fn new(config: &'a mut GlobalConfig) -> Self { | ||
Self { | ||
config, | ||
generate_starts: Default::default(), | ||
parse_starts: Default::default(), | ||
} | ||
} | ||
} | ||
|
||
impl<'a> crate::data_generation::ProgressCallbacks<'a> for Callbacks<'a> { | ||
fn generate_rustdoc_start(&mut self, crate_name: &'a str, version: &'a str, is_baseline: bool) { | ||
let kind = if is_baseline { "baseline" } else { "current" }; | ||
|
||
// Ignore terminal printing failures. | ||
let _ = self.config.shell_status( | ||
"Building", | ||
format_args!("{crate_name} v{version} ({kind})",), | ||
); | ||
|
||
self.generate_starts.insert( | ||
(crate_name, version, is_baseline), | ||
std::time::Instant::now(), | ||
); | ||
} | ||
|
||
fn generate_rustdoc_success( | ||
&mut self, | ||
crate_name: &'a str, | ||
version: &'a str, | ||
is_baseline: bool, | ||
) { | ||
let kind = if is_baseline { "baseline" } else { "current" }; | ||
let start = self | ||
.generate_starts | ||
.remove(&(crate_name, version, is_baseline)) | ||
.expect("success on generation task that never started"); | ||
|
||
// Ignore terminal printing failures. | ||
let _ = self.config.shell_status( | ||
"Built", | ||
format_args!("[{:>8.3}s] ({kind})", start.elapsed().as_secs_f32()), | ||
); | ||
} | ||
|
||
fn parse_rustdoc_start( | ||
&mut self, | ||
cached: bool, | ||
crate_name: &'a str, | ||
version: &'a str, | ||
is_baseline: bool, | ||
) { | ||
let kind = if is_baseline { "baseline" } else { "current" }; | ||
let cached = if cached { ", cached" } else { "" }; | ||
|
||
// Ignore terminal printing failures. | ||
let _ = self.config.shell_status( | ||
"Parsing", | ||
format_args!("{crate_name} v{version} ({kind}{cached})",), | ||
); | ||
|
||
self.parse_starts.insert( | ||
(crate_name, version, is_baseline), | ||
std::time::Instant::now(), | ||
); | ||
} | ||
|
||
fn parse_rustdoc_success( | ||
&mut self, | ||
_cached: bool, | ||
crate_name: &'a str, | ||
version: &'a str, | ||
is_baseline: bool, | ||
) { | ||
let kind = if is_baseline { "baseline" } else { "current" }; | ||
let start = self | ||
.parse_starts | ||
.remove(&(crate_name, version, is_baseline)) | ||
.expect("success on parse task that never started"); | ||
|
||
// Ignore terminal printing failures. | ||
let _ = self.config.shell_status( | ||
"Parsed", | ||
format_args!("[{:>8.3}s] ({kind})", start.elapsed().as_secs_f32()), | ||
); | ||
} | ||
|
||
fn non_fatal_error( | ||
&mut self, | ||
crate_name: &'a str, | ||
version: &'a str, | ||
is_baseline: bool, | ||
error: anyhow::Error, | ||
) { | ||
let kind = if is_baseline { "baseline" } else { "current" }; | ||
|
||
// Ignore terminal printing failures. | ||
let _ = self.config.log_info(|config| { | ||
config.shell_warn(format!( | ||
"encountered non-fatal error while working on crate \ | ||
{crate_name} v{version} ({kind}): {error}", | ||
))?; | ||
Ok(()) | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/// An error that blocks further progress. "Terminal" in the sense of "cannot continue." | ||
#[derive(Debug)] | ||
pub(crate) enum TerminalError { | ||
WithAdvice(anyhow::Error, String), | ||
Other(anyhow::Error), | ||
} | ||
|
||
impl<E: std::error::Error + Send + Sync + 'static> From<E> for TerminalError { | ||
fn from(value: E) -> Self { | ||
Self::Other(value.into()) | ||
} | ||
} | ||
|
||
pub(crate) trait IntoTerminalResult<T> { | ||
fn into_terminal_result(self) -> Result<T, TerminalError>; | ||
} | ||
|
||
impl<T> IntoTerminalResult<T> for Result<T, anyhow::Error> { | ||
fn into_terminal_result(self) -> Result<T, TerminalError> { | ||
self.map_err(TerminalError::Other) | ||
} | ||
} |
Oops, something went wrong.