diff options
Diffstat (limited to 'llvm_tools/patch_sync/src/main.rs')
-rw-r--r-- | llvm_tools/patch_sync/src/main.rs | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/llvm_tools/patch_sync/src/main.rs b/llvm_tools/patch_sync/src/main.rs deleted file mode 100644 index c244f1c0..00000000 --- a/llvm_tools/patch_sync/src/main.rs +++ /dev/null @@ -1,332 +0,0 @@ -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 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, - 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, - }), - } -} - -struct ShowOpt { - cros_checkout_path: PathBuf, - android_checkout_path: PathBuf, - keep_unmerged: bool, - sync: bool, -} - -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 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(()) -} - -struct TransposeOpt { - cros_checkout_path: PathBuf, - old_cros_ref: String, - android_checkout_path: PathBuf, - old_android_ref: String, - sync: bool, - 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 = 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(); - - // 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)?; - - // 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 ----------------------------------------------------- - 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 no_commit { - println!("--no-commit specified; not committing or uploading"); - return Ok(()); - } - // Commit and upload for review ------------------------------------------ - // 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 { - /// Show a combined view of the PATCHES.json file, without making any changes. - #[allow(dead_code)] - Show { - #[structopt(parse(from_os_str))] - 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, - }, - /// Transpose patches from two PATCHES.json files - /// to each other. - Transpose { - /// Path to the ChromiumOS source repo checkout. - #[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, - - /// Path to the Android Open Source Project source repo checkout. - #[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, - - /// Run repo sync before transposing. - #[structopt(short, long)] - sync: bool, - - /// Print information to stdout - #[structopt(short, long)] - verbose: bool, - - /// Do not change any files. Useful in combination with `--verbose` - /// Implies `--no-commit`. - #[structopt(long)] - dry_run: bool, - - /// 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, - }, -} |