blob: 15246e49ba3b5eb10ea73ff9a59c3b0497f2fe26 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Runs CQ dry run after updating the packages."""
from __future__ import print_function
import argparse
import datetime
import json
import os
from assert_not_in_chroot import VerifyOutsideChroot
from failure_modes import FailureModes
from get_llvm_hash import GetLLVMHashAndVersionFromSVNOption
from get_llvm_hash import is_svn_option
from subprocess_helpers import ChrootRunCommand
from subprocess_helpers import ExecCommandAndCaptureOutput
import update_chromeos_llvm_hash
def GetCommandLineArgs():
"""Parses the command line for the command line arguments.
Returns:
The log level to use when retrieving the LLVM hash or google3 LLVM version,
the chroot path to use for executing chroot commands,
a list of a package or packages to update their LLVM next hash,
and the LLVM version to use when retrieving the LLVM hash.
"""
# Default path to the chroot if a path is not specified.
cros_root = os.path.expanduser('~')
cros_root = os.path.join(cros_root, 'chromiumos')
# Create parser and add optional command-line arguments.
parser = argparse.ArgumentParser(
description=
'Runs a tryjob if successfully updated LLVM_NEXT_HASH of packages.')
# Add argument for the absolute path to the file that contains information on
# the previous tested svn version.
parser.add_argument(
'--last_tested',
help='the absolute path to the file that contains the last tested '
'svn version')
# Add argument for other change lists that want to run alongside the tryjob
# which has a change list of updating a package's git hash.
parser.add_argument(
'--extra_change_lists',
type=int,
default=[],
nargs='+',
help='change lists that would like to be run alongside the change list '
'of updating the packages')
# Add argument for a specific chroot path.
parser.add_argument(
'--chroot_path',
default=cros_root,
help='the path to the chroot (default: %(default)s)')
# Add argument to choose between llvm and llvm-next.
parser.add_argument(
'--is_llvm_next',
action='store_true',
help='which llvm hash to update. Update LLVM_NEXT_HASH if specified. '
'Otherwise, update LLVM_HASH')
# Add argument to add reviewers for the created CL.
parser.add_argument(
'--reviewers',
nargs='+',
default=[],
help='The reviewers for the package update changelist')
# Add argument for whether to display command contents to `stdout`.
parser.add_argument(
'--verbose',
action='store_true',
help='display contents of a command to the terminal '
'(default: %(default)s)')
# Add argument for the LLVM version to use.
parser.add_argument(
'--llvm_version',
type=is_svn_option,
required=True,
help='which git hash of LLVM to find '
'{google3, ToT, <svn_version>} '
'(default: finds the git hash of the google3 LLVM '
'version)')
args_output = parser.parse_args()
return args_output
def GetLastTestedSVNVersion(last_tested_file):
"""Gets the lasted tested svn version from the file.
Args:
last_tested_file: The absolute path to the file that contains the last
tested svn version.
Returns:
The last tested svn version or 'None' if the file did not have a last tested
svn version (the file exists, but failed to convert the contents to an
integer) or the file does not exist.
"""
if not last_tested_file:
return None
last_svn_version = None
# Get the last tested svn version if the file exists.
try:
with open(last_tested_file) as file_obj:
# For now, the first line contains the last tested svn version.
return int(file_obj.read().rstrip())
except (IOError, ValueError):
pass
return last_svn_version
def GetCQDependString(dependent_cls):
"""Get CQ dependency string e.g. `Cq-Depend: chromium:MM, chromium:NN`."""
if not dependent_cls:
return None
# Cq-Depend must start a new paragraph prefixed with "Cq-Depend".
return '\nCq-Depend: ' + ', '.join(('chromium:%s' % i) for i in dependent_cls)
def AddReviewers(cl, reviewers, chroot_path):
"""Add reviewers for the created CL."""
gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit')
for reviewer in reviewers:
cmd = [gerrit_abs_path, 'reviewers', str(cl), reviewer]
ExecCommandAndCaptureOutput(cmd)
def StartCQDryRun(cl, dependent_cls, chroot_path):
"""Start CQ dry run for the changelist and dependencies."""
gerrit_abs_path = os.path.join(chroot_path, 'chromite/bin/gerrit')
cl_list = [cl]
cl_list.extend(dependent_cls)
for changes in cl_list:
cq_dry_run_cmd = [gerrit_abs_path, 'label-cq', str(changes), '1']
ExecCommandAndCaptureOutput(cq_dry_run_cmd)
def main():
"""Updates the packages' 'LLVM_NEXT_HASH' and submits tryjobs.
Raises:
AssertionError: The script was run inside the chroot.
"""
VerifyOutsideChroot()
args_output = GetCommandLineArgs()
last_svn_version = GetLastTestedSVNVersion(args_output.last_tested)
update_packages = [
'sys-devel/llvm', 'sys-libs/compiler-rt', 'sys-libs/libcxx',
'sys-libs/libcxxabi', 'sys-libs/llvm-libunwind'
]
patch_metadata_file = 'PATCHES.json'
svn_option = args_output.llvm_version
git_hash, svn_version = GetLLVMHashAndVersionFromSVNOption(svn_option)
# There is no need to run tryjobs when the SVN version matches the last tested
# SVN version.
if last_svn_version == svn_version:
print('svn version (%d) matches the last tested svn version (%d) in %s' %
(svn_version, last_svn_version, args_output.last_tested))
return
llvm_variant = update_chromeos_llvm_hash.LLVMVariant.current
if args_output.is_llvm_next:
llvm_variant = update_chromeos_llvm_hash.LLVMVariant.next
update_chromeos_llvm_hash.verbose = args_output.verbose
extra_commit_msg = GetCQDependString(args_output.extra_change_lists)
change_list = update_chromeos_llvm_hash.UpdatePackages(
update_packages, llvm_variant, git_hash, svn_version,
args_output.chroot_path, patch_metadata_file,
FailureModes.DISABLE_PATCHES, svn_option, extra_commit_msg)
print('Successfully updated packages to %d' % svn_version)
print('Gerrit URL: %s' % change_list.url)
print('Change list number: %d' % change_list.cl_number)
AddReviewers(change_list.cl_number, args_output.reviewers,
args_output.chroot_path)
StartCQDryRun(change_list.cl_number, args_output.extra_change_lists,
args_output.chroot_path)
# Updated the packages and submitted tryjobs successfully, so the file will
# contain 'svn_version' which will now become the last tested svn version.
if args_output.last_tested:
with open(args_output.last_tested, 'w', encoding='utf-8') as file_obj:
file_obj.write(str(svn_version))
if __name__ == '__main__':
main()