Browse Source

Merge pull request #853 from tamird/public-api-mac

xtask: allow public-api regen on aarch64-apple-darwin
Tamir Duberstein 1 year ago
parent
commit
1e99ac9323
1 changed files with 56 additions and 20 deletions
  1. 56 20
      xtask/src/public_api.rs

+ 56 - 20
xtask/src/public_api.rs

@@ -6,7 +6,7 @@ use std::{
 };
 
 use anyhow::{bail, Context as _, Result};
-use cargo_metadata::{Metadata, Package};
+use cargo_metadata::{Metadata, Package, Target};
 use clap::Parser;
 use dialoguer::{theme::ColorfulTheme, Confirm};
 use diff::{lines, Result as Diff};
@@ -17,11 +17,15 @@ pub struct Options {
     /// Bless new API changes.
     #[clap(long)]
     pub bless: bool,
+
+    /// Bless new API changes.
+    #[clap(long)]
+    pub target: Option<String>,
 }
 
 pub fn public_api(options: Options, metadata: Metadata) -> Result<()> {
     let toolchain = "nightly";
-    let Options { bless } = options;
+    let Options { bless, target } = options;
 
     if !rustup_toolchain::is_installed(toolchain)? {
         if Confirm::with_theme(&ColorfulTheme::default())
@@ -42,21 +46,40 @@ pub fn public_api(options: Options, metadata: Metadata) -> Result<()> {
 
     let errors: Vec<_> = packages
         .into_iter()
-        .map(|Package { name, publish, .. }| {
-            if matches!(publish, Some(publish) if publish.is_empty()) {
-                Ok(())
-            } else {
-                let diff = check_package_api(&name, toolchain, bless, workspace_root.as_std_path())
-                    .with_context(|| format!("{name} failed to check public API"))?;
-                if diff.is_empty() {
+        .map(
+            |Package {
+                 name,
+                 publish,
+                 targets,
+                 ..
+             }| {
+                if matches!(publish, Some(publish) if publish.is_empty()) {
                     Ok(())
                 } else {
-                    Err(anyhow::anyhow!(
-                        "{name} public API changed; re-run with --bless. diff:\n{diff}"
-                    ))
+                    let target = target.as_ref().and_then(|target| {
+                        let proc_macro = targets.iter().any(|Target { kind, .. }| {
+                            kind.iter().any(|kind| kind == "proc-macro")
+                        });
+                        (!proc_macro).then_some(target)
+                    });
+                    let diff = check_package_api(
+                        &name,
+                        toolchain,
+                        target.cloned(),
+                        bless,
+                        workspace_root.as_std_path(),
+                    )
+                    .with_context(|| format!("{name} failed to check public API"))?;
+                    if diff.is_empty() {
+                        Ok(())
+                    } else {
+                        Err(anyhow::anyhow!(
+                            "{name} public API changed; re-run with --bless. diff:\n{diff}"
+                        ))
+                    }
                 }
-            }
-        })
+            },
+        )
         .filter_map(|result| match result {
             Ok(()) => None,
             Err(err) => Some(err),
@@ -73,6 +96,7 @@ pub fn public_api(options: Options, metadata: Metadata) -> Result<()> {
 fn check_package_api(
     package: &str,
     toolchain: &str,
+    target: Option<String>,
     bless: bool,
     workspace_root: &Path,
 ) -> Result<String> {
@@ -82,16 +106,28 @@ fn check_package_api(
         .join(package)
         .with_extension("txt");
 
-    let rustdoc_json = rustdoc_json::Builder::default()
+    let mut builder = rustdoc_json::Builder::default()
         .toolchain(toolchain)
         .package(package)
-        .all_features(true)
-        .build()
-        .context("rustdoc_json::Builder::build")?;
+        .all_features(true);
+    if let Some(target) = target {
+        builder = builder.target(target);
+    }
+    let rustdoc_json = builder.build().with_context(|| {
+        format!(
+            "rustdoc_json::Builder::default().toolchain({}).package({}).build()",
+            toolchain, package
+        )
+    })?;
 
-    let public_api = public_api::Builder::from_rustdoc_json(rustdoc_json)
+    let public_api = public_api::Builder::from_rustdoc_json(&rustdoc_json)
         .build()
-        .context("public_api::Builder::build")?;
+        .with_context(|| {
+            format!(
+                "public_api::Builder::from_rustdoc_json({})::build()",
+                rustdoc_json.display()
+            )
+        })?;
 
     if bless {
         let mut output =