crate::ix!();
#[async_trait]
impl<P,H:CrateHandleInterface<P>> RunLinting for Workspace<P,H>
where for<'async_trait> P: From<PathBuf> + AsRef<Path> + Send + Sync + 'async_trait
{
type Report = LintReport;
type Error = LintingError;
async fn run_linting(&self) -> Result<Self::Report, Self::Error> {
let workspace_path = self.as_ref();
let output = tokio::process::Command::new("cargo")
.arg("clippy")
.arg("--all-targets")
.arg("--message-format=short")
.arg("--quiet")
.arg("--")
.arg("-D")
.arg("warnings") .current_dir(workspace_path)
.output()
.await
.map_err(|e| LintingError::CommandError { io: e.into() })?;
let report = LintReport::from(output);
report.maybe_throw()?;
Ok(report) }
}
#[derive(Debug)]
pub struct LintReport {
stdout: String,
stderr: String,
success: bool,
}
impl LintReport {
pub fn stdout(&self) -> &str {
&self.stdout
}
pub fn stderr(&self) -> &str {
&self.stderr
}
pub fn success(&self) -> bool {
self.success
}
}
impl From<std::process::Output> for LintReport {
fn from(output: std::process::Output) -> Self {
Self {
stdout: String::from_utf8_lossy(&output.stdout).to_string(),
stderr: String::from_utf8_lossy(&output.stderr).to_string(),
success: output.status.success(),
}
}
}
impl MaybeThrow for LintReport {
type Error = LintingError;
fn maybe_throw(&self) -> Result<(),Self::Error> {
if !self.success() {
return Err(LintingError::UnknownError {
stderr: Some(self.stderr.clone()),
stdout: Some(self.stdout.clone()),
});
}
Ok(())
}
}