aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/patch_sync/src/main.rs
diff options
context:
space:
mode:
authorJordan R Abrahams-Whitehead <ajordanr@google.com>2022-03-04 01:01:06 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-03-04 01:01:06 +0000
commit178e686da38f18bbc35b0f1903c93effa94bc6b4 (patch)
treeb0522edde1d3c5356c95eb1ee2eae3e87befa1f3 /llvm_tools/patch_sync/src/main.rs
parent9d023268dcf468f9d4bbd874545c9c230e7549b3 (diff)
parent8a12172a247b7fee03c37d0b5ef5cfe818c8ee4d (diff)
downloadtoolchain-utils-android13-d4-release.tar.gz
Merging 25 commit(s) from Chromium's toolchain-utils am: 9090b1a17b am: c9cb1157f1 am: 8a12172a24t_frc_odp_330442040t_frc_odp_330442000t_frc_ase_330444010android-platform-13.0.0_r1android-13.0.0_r83android-13.0.0_r82android-13.0.0_r81android-13.0.0_r80android-13.0.0_r79android-13.0.0_r78android-13.0.0_r77android-13.0.0_r76android-13.0.0_r75android-13.0.0_r74android-13.0.0_r73android-13.0.0_r72android-13.0.0_r71android-13.0.0_r70android-13.0.0_r69android-13.0.0_r68android-13.0.0_r67android-13.0.0_r66android-13.0.0_r65android-13.0.0_r64android-13.0.0_r63android-13.0.0_r62android-13.0.0_r61android-13.0.0_r60android-13.0.0_r59android-13.0.0_r58android-13.0.0_r57android-13.0.0_r56android-13.0.0_r55android-13.0.0_r54android-13.0.0_r53android-13.0.0_r52android-13.0.0_r51android-13.0.0_r50android-13.0.0_r49android-13.0.0_r48android-13.0.0_r47android-13.0.0_r46android-13.0.0_r45android-13.0.0_r44android-13.0.0_r43android-13.0.0_r42android-13.0.0_r41android-13.0.0_r40android-13.0.0_r39android-13.0.0_r38android-13.0.0_r37android-13.0.0_r36android-13.0.0_r35android-13.0.0_r34android-13.0.0_r33android-13.0.0_r32android-13.0.0_r30android-13.0.0_r29android-13.0.0_r28android-13.0.0_r27android-13.0.0_r24android-13.0.0_r23android-13.0.0_r22android-13.0.0_r21android-13.0.0_r20android-13.0.0_r19android-13.0.0_r18android-13.0.0_r17android-13.0.0_r16aml_go_odp_330912000aml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-qpr3-s9-releaseandroid13-qpr3-s8-releaseandroid13-qpr3-s7-releaseandroid13-qpr3-s6-releaseandroid13-qpr3-s5-releaseandroid13-qpr3-s4-releaseandroid13-qpr3-s3-releaseandroid13-qpr3-s2-releaseandroid13-qpr3-s14-releaseandroid13-qpr3-s13-releaseandroid13-qpr3-s12-releaseandroid13-qpr3-s11-releaseandroid13-qpr3-s10-releaseandroid13-qpr3-s1-releaseandroid13-qpr3-releaseandroid13-qpr3-c-s8-releaseandroid13-qpr3-c-s7-releaseandroid13-qpr3-c-s6-releaseandroid13-qpr3-c-s5-releaseandroid13-qpr3-c-s4-releaseandroid13-qpr3-c-s3-releaseandroid13-qpr3-c-s2-releaseandroid13-qpr3-c-s12-releaseandroid13-qpr3-c-s11-releaseandroid13-qpr3-c-s10-releaseandroid13-qpr3-c-s1-releaseandroid13-qpr2-s9-releaseandroid13-qpr2-s8-releaseandroid13-qpr2-s7-releaseandroid13-qpr2-s6-releaseandroid13-qpr2-s5-releaseandroid13-qpr2-s3-releaseandroid13-qpr2-s2-releaseandroid13-qpr2-s12-releaseandroid13-qpr2-s11-releaseandroid13-qpr2-s10-releaseandroid13-qpr2-s1-releaseandroid13-qpr2-releaseandroid13-qpr2-b-s1-releaseandroid13-qpr1-s8-releaseandroid13-qpr1-s7-releaseandroid13-qpr1-s6-releaseandroid13-qpr1-s5-releaseandroid13-qpr1-s4-releaseandroid13-qpr1-s3-releaseandroid13-qpr1-s2-releaseandroid13-qpr1-s1-releaseandroid13-qpr1-releaseandroid13-platform-releaseandroid13-mainline-go-adservices-releaseandroid13-frc-odp-releaseandroid13-devandroid13-d4-s2-releaseandroid13-d4-s1-releaseandroid13-d4-releaseandroid13-d3-s1-releaseandroid13-d2-release
Original change: https://android-review.googlesource.com/c/platform/external/toolchain-utils/+/2006491 Change-Id: Iec01482f09cfb65d135808f846754e9aedeeca4f
Diffstat (limited to 'llvm_tools/patch_sync/src/main.rs')
-rw-r--r--llvm_tools/patch_sync/src/main.rs253
1 files changed, 206 insertions, 47 deletions
diff --git a/llvm_tools/patch_sync/src/main.rs b/llvm_tools/patch_sync/src/main.rs
index 081ce01a..c244f1c0 100644
--- a/llvm_tools/patch_sync/src/main.rs
+++ b/llvm_tools/patch_sync/src/main.rs
@@ -1,63 +1,110 @@
+mod android_utils;
mod patch_parsing;
mod version_control;
+use std::borrow::ToOwned;
+use std::collections::BTreeSet;
+use std::path::{Path, PathBuf};
+
use anyhow::{Context, Result};
-use std::path::PathBuf;
use structopt::StructOpt;
+use patch_parsing::{filter_patches_by_platform, PatchCollection, PatchDictSchema};
+use version_control::RepoSetupContext;
+
fn main() -> Result<()> {
match Opt::from_args() {
Opt::Show {
cros_checkout_path,
android_checkout_path,
sync,
- } => show_subcmd(cros_checkout_path, android_checkout_path, sync),
+ keep_unmerged,
+ } => show_subcmd(ShowOpt {
+ cros_checkout_path,
+ android_checkout_path,
+ sync,
+ keep_unmerged,
+ }),
Opt::Transpose {
cros_checkout_path,
+ cros_reviewers,
old_cros_ref,
android_checkout_path,
+ android_reviewers,
old_android_ref,
sync,
verbose,
dry_run,
no_commit,
+ wip,
+ disable_cq,
} => transpose_subcmd(TransposeOpt {
cros_checkout_path,
+ cros_reviewers: cros_reviewers
+ .map(|r| r.split(',').map(ToOwned::to_owned).collect())
+ .unwrap_or_default(),
old_cros_ref,
android_checkout_path,
+ android_reviewers: android_reviewers
+ .map(|r| r.split(',').map(ToOwned::to_owned).collect())
+ .unwrap_or_default(),
old_android_ref,
sync,
verbose,
dry_run,
no_commit,
+ wip,
+ disable_cq,
}),
}
}
-fn show_subcmd(
+struct ShowOpt {
cros_checkout_path: PathBuf,
android_checkout_path: PathBuf,
+ keep_unmerged: bool,
sync: bool,
-) -> Result<()> {
- let ctx = version_control::RepoSetupContext {
+}
+
+fn show_subcmd(args: ShowOpt) -> Result<()> {
+ let ShowOpt {
+ cros_checkout_path,
+ android_checkout_path,
+ keep_unmerged,
+ sync,
+ } = args;
+ let ctx = RepoSetupContext {
cros_checkout: cros_checkout_path,
android_checkout: android_checkout_path,
sync_before: sync,
+ wip_mode: true, // Has no effect, as we're not making changes
+ enable_cq: false, // Has no effect, as we're not uploading anything
};
ctx.setup()?;
- let cros_patches_path = ctx.cros_patches_path();
- let android_patches_path = ctx.android_patches_path();
- let cur_cros_collection = patch_parsing::PatchCollection::parse_from_file(&cros_patches_path)
- .context("could not parse cros PATCHES.json")?;
- let cur_android_collection =
- patch_parsing::PatchCollection::parse_from_file(&android_patches_path)
- .context("could not parse android PATCHES.json")?;
+ let make_collection = |platform: &str, patches_fp: &Path| -> Result<PatchCollection> {
+ let parsed_collection = PatchCollection::parse_from_file(patches_fp)
+ .with_context(|| format!("could not parse {} PATCHES.json", platform))?;
+ Ok(if keep_unmerged {
+ parsed_collection
+ } else {
+ filter_patches_by_platform(&parsed_collection, platform).map_patches(|p| {
+ // Need to do this platforms creation as Rust 1.55 cannot use "from".
+ let mut platforms = BTreeSet::new();
+ platforms.insert(platform.to_string());
+ PatchDictSchema {
+ platforms,
+ ..p.clone()
+ }
+ })
+ })
+ };
+ let cur_cros_collection = make_collection("chromiumos", &ctx.cros_patches_path())?;
+ let cur_android_collection = make_collection("android", &ctx.android_patches_path())?;
let merged = cur_cros_collection.union(&cur_android_collection)?;
println!("{}", merged.serialize_patches()?);
Ok(())
}
-#[allow(dead_code)]
struct TransposeOpt {
cros_checkout_path: PathBuf,
old_cros_ref: String,
@@ -67,59 +114,147 @@ struct TransposeOpt {
verbose: bool,
dry_run: bool,
no_commit: bool,
+ cros_reviewers: Vec<String>,
+ android_reviewers: Vec<String>,
+ wip: bool,
+ disable_cq: bool,
}
fn transpose_subcmd(args: TransposeOpt) -> Result<()> {
- let ctx = version_control::RepoSetupContext {
+ let ctx = RepoSetupContext {
cros_checkout: args.cros_checkout_path,
android_checkout: args.android_checkout_path,
sync_before: args.sync,
+ wip_mode: args.wip,
+ enable_cq: !args.disable_cq,
};
ctx.setup()?;
let cros_patches_path = ctx.cros_patches_path();
let android_patches_path = ctx.android_patches_path();
- // Chromium OS Patches ----------------------------------------------------
- let mut cur_cros_collection =
- patch_parsing::PatchCollection::parse_from_file(&cros_patches_path)
- .context("parsing cros PATCHES.json")?;
- let new_cros_patches: patch_parsing::PatchCollection = {
- let cros_old_patches_json = ctx.old_cros_patch_contents(&args.old_cros_ref)?;
- let old_cros_collection = patch_parsing::PatchCollection::parse_from_str(
- cros_patches_path.parent().unwrap().to_path_buf(),
- &cros_old_patches_json,
- )?;
- cur_cros_collection.subtract(&old_cros_collection)?
- };
+ // Get new Patches -------------------------------------------------------
+ let (cur_cros_collection, new_cros_patches) = patch_parsing::new_patches(
+ &cros_patches_path,
+ &ctx.old_cros_patch_contents(&args.old_cros_ref)?,
+ "chromiumos",
+ )
+ .context("finding new patches for chromiumos")?;
+ let (cur_android_collection, new_android_patches) = patch_parsing::new_patches(
+ &android_patches_path,
+ &ctx.old_android_patch_contents(&args.old_android_ref)?,
+ "android",
+ )
+ .context("finding new patches for android")?;
+
+ // Have to ignore patches that are already at the destination, even if
+ // the patches are new.
+ let new_cros_patches = new_cros_patches.subtract(&cur_android_collection)?;
+ let new_android_patches = new_android_patches.subtract(&cur_cros_collection)?;
- // Android Patches -------------------------------------------------------
- let mut cur_android_collection =
- patch_parsing::PatchCollection::parse_from_file(&android_patches_path)
- .context("parsing android PATCHES.json")?;
- let new_android_patches: patch_parsing::PatchCollection = {
- let android_old_patches_json = ctx.old_android_patch_contents(&args.old_android_ref)?;
- let old_android_collection = patch_parsing::PatchCollection::parse_from_str(
- android_patches_path.parent().unwrap().to_path_buf(),
- &android_old_patches_json,
- )?;
- cur_android_collection.subtract(&old_android_collection)?
+ // Need to do an extra filtering step for Android, as AOSP doesn't
+ // want patches outside of the start/end bounds.
+ let android_llvm_version: u64 = {
+ let android_llvm_version_str =
+ android_utils::get_android_llvm_version(&ctx.android_checkout)?;
+ android_llvm_version_str.parse::<u64>().with_context(|| {
+ format!(
+ "converting llvm version to u64: '{}'",
+ android_llvm_version_str
+ )
+ })?
};
+ let new_android_patches = new_android_patches.filter_patches(|p| {
+ match (p.get_start_version(), p.get_end_version()) {
+ (Some(start), Some(end)) => start <= android_llvm_version && android_llvm_version < end,
+ (Some(start), None) => start <= android_llvm_version,
+ (None, Some(end)) => android_llvm_version < end,
+ (None, None) => true,
+ }
+ });
+
+ if args.verbose {
+ display_patches("New patches from Chromium OS", &new_cros_patches);
+ display_patches("New patches from Android", &new_android_patches);
+ }
+
+ if args.dry_run {
+ println!("--dry-run specified; skipping modifications");
+ return Ok(());
+ }
+
+ modify_repos(
+ &ctx,
+ args.no_commit,
+ ModifyOpt {
+ new_cros_patches,
+ cur_cros_collection,
+ cros_reviewers: args.cros_reviewers,
+ new_android_patches,
+ cur_android_collection,
+ android_reviewers: args.android_reviewers,
+ },
+ )
+}
+struct ModifyOpt {
+ new_cros_patches: PatchCollection,
+ cur_cros_collection: PatchCollection,
+ cros_reviewers: Vec<String>,
+ new_android_patches: PatchCollection,
+ cur_android_collection: PatchCollection,
+ android_reviewers: Vec<String>,
+}
+
+fn modify_repos(ctx: &RepoSetupContext, no_commit: bool, opt: ModifyOpt) -> Result<()> {
+ // Cleanup on scope exit.
+ scopeguard::defer! {
+ ctx.cleanup();
+ }
// Transpose Patches -----------------------------------------------------
- new_cros_patches.transpose_write(&mut cur_cros_collection)?;
- new_android_patches.transpose_write(&mut cur_android_collection)?;
+ let mut cur_android_collection = opt.cur_android_collection;
+ let mut cur_cros_collection = opt.cur_cros_collection;
+ if !opt.new_cros_patches.is_empty() {
+ opt.new_cros_patches
+ .transpose_write(&mut cur_android_collection)?;
+ }
+ if !opt.new_android_patches.is_empty() {
+ opt.new_android_patches
+ .transpose_write(&mut cur_cros_collection)?;
+ }
- if !args.no_commit {
+ if no_commit {
+ println!("--no-commit specified; not committing or uploading");
return Ok(());
}
// Commit and upload for review ------------------------------------------
- ctx.cros_repo_upload()
- .context("uploading chromiumos changes")?;
- ctx.android_repo_upload()
- .context("uploading android changes")?;
+ // Note we want to check if the android patches are empty for CrOS, and
+ // vice versa. This is a little counterintuitive.
+ if !opt.new_android_patches.is_empty() {
+ ctx.cros_repo_upload(&opt.cros_reviewers)
+ .context("uploading chromiumos changes")?;
+ }
+ if !opt.new_cros_patches.is_empty() {
+ if let Err(e) = android_utils::sort_android_patches(&ctx.android_checkout) {
+ eprintln!(
+ "Couldn't sort Android patches; continuing. Caused by: {}",
+ e
+ );
+ }
+ ctx.android_repo_upload(&opt.android_reviewers)
+ .context("uploading android changes")?;
+ }
Ok(())
}
+fn display_patches(prelude: &str, collection: &PatchCollection) {
+ println!("{}", prelude);
+ if collection.patches.is_empty() {
+ println!(" [No Patches]");
+ return;
+ }
+ println!("{}", collection);
+}
+
#[derive(Debug, structopt::StructOpt)]
#[structopt(name = "patch_sync", about = "A pipeline for syncing the patch code")]
enum Opt {
@@ -130,6 +265,12 @@ enum Opt {
cros_checkout_path: PathBuf,
#[structopt(parse(from_os_str))]
android_checkout_path: PathBuf,
+
+ /// Keep a patch's platform field even if it's not merged at that platform.
+ #[structopt(long)]
+ keep_unmerged: bool,
+
+ /// Run repo sync before transposing.
#[structopt(short, long)]
sync: bool,
},
@@ -140,6 +281,11 @@ enum Opt {
#[structopt(long = "cros-checkout", parse(from_os_str))]
cros_checkout_path: PathBuf,
+ /// Emails to send review requests to during Chromium OS upload.
+ /// Comma separated.
+ #[structopt(long = "cros-rev")]
+ cros_reviewers: Option<String>,
+
/// Git ref (e.g. hash) for the ChromiumOS overlay to use as the base.
#[structopt(long = "overlay-base-ref")]
old_cros_ref: String,
@@ -148,6 +294,11 @@ enum Opt {
#[structopt(long = "aosp-checkout", parse(from_os_str))]
android_checkout_path: PathBuf,
+ /// Emails to send review requests to during Android upload.
+ /// Comma separated.
+ #[structopt(long = "aosp-rev")]
+ android_reviewers: Option<String>,
+
/// Git ref (e.g. hash) for the llvm_android repo to use as the base.
#[structopt(long = "aosp-base-ref")]
old_android_ref: String,
@@ -161,13 +312,21 @@ enum Opt {
verbose: bool,
/// Do not change any files. Useful in combination with `--verbose`
- /// Implies `--no-commit` and `--no-upload`.
+ /// Implies `--no-commit`.
#[structopt(long)]
dry_run: bool,
- /// Do not commit any changes made.
- /// Implies `--no-upload`.
+ /// Do not commit or upload any changes made.
#[structopt(long)]
no_commit: bool,
+
+ /// Upload and send things for review, but mark as WIP and send no
+ /// emails.
+ #[structopt(long)]
+ wip: bool,
+
+ /// Don't run CQ if set. Only has an effect if uploading.
+ #[structopt(long)]
+ disable_cq: bool,
},
}