Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """This module uprevs a given package's ebuild to the next revision.""" | 7 """This module uprevs a given package's ebuild to the next revision.""" |
| 8 | 8 |
| 9 | 9 |
| 10 import fileinput | 10 import fileinput |
| 11 import gflags | 11 import gflags |
| 12 import os | 12 import os |
| 13 import re | 13 import re |
| 14 import shutil | 14 import shutil |
| 15 import subprocess | 15 import subprocess |
| 16 import sys | 16 import sys |
| 17 | 17 |
| 18 sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) | 18 sys.path.append(os.path.join(os.path.dirname(__file__), 'lib')) |
| 19 from cros_build_lib import Info, RunCommand, Warning, Die | 19 from cros_build_lib import Info, RunCommand, Warning, Die |
| 20 | 20 |
| 21 | 21 |
| 22 gflags.DEFINE_string('board', '', | 22 gflags.DEFINE_string('board', '', |
| 23 'Board for which the package belongs.', short_name='b') | 23 'Board for which the package belongs.', short_name='b') |
| 24 gflags.DEFINE_string('overlays', '', | 24 gflags.DEFINE_string('overlays', '', |
| 25 'Space separated list of overlays to modify.', | 25 'Colon-separated list of overlays to modify.', |
| 26 short_name='o') | 26 short_name='o') |
| 27 gflags.DEFINE_string('packages', '', | 27 gflags.DEFINE_string('packages', '', |
| 28 'Space separated list of packages to mark as stable.', | 28 'Colon-separated list of packages to mark as stable.', |
| 29 short_name='p') | 29 short_name='p') |
| 30 gflags.DEFINE_string('push_options', '', | 30 gflags.DEFINE_string('push_options', '', |
| 31 'Options to use with git-cl push using push command.') | 31 'Options to use with git-cl push using push command.') |
| 32 gflags.DEFINE_string('srcroot', '%s/trunk/src' % os.environ['HOME'], | 32 gflags.DEFINE_string('srcroot', '%s/trunk/src' % os.environ['HOME'], |
| 33 'Path to root src directory.', | 33 'Path to root src directory.', |
| 34 short_name='r') | 34 short_name='r') |
| 35 gflags.DEFINE_string('tracking_branch', 'cros/master', | 35 gflags.DEFINE_string('tracking_branch', 'cros/master', |
| 36 'Used with commit to specify branch to track against.', | 36 'Used with commit to specify branch to track against.', |
| 37 short_name='t') | 37 short_name='t') |
| 38 gflags.DEFINE_boolean('all', False, | 38 gflags.DEFINE_boolean('all', False, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 unmerge_host_cmd = ['sudo', 'emerge', '--unmerge'] | 78 unmerge_host_cmd = ['sudo', 'emerge', '--unmerge'] |
| 79 unmerge_host_cmd.extend(package_array) | 79 unmerge_host_cmd.extend(package_array) |
| 80 RunCommand(unmerge_host_cmd) | 80 RunCommand(unmerge_host_cmd) |
| 81 | 81 |
| 82 RunCommand(['eclean-%s' % board, '-d', 'packages'], redirect_stderr=True) | 82 RunCommand(['eclean-%s' % board, '-d', 'packages'], redirect_stderr=True) |
| 83 RunCommand(['sudo', 'eclean', '-d', 'packages'], redirect_stderr=True) | 83 RunCommand(['sudo', 'eclean', '-d', 'packages'], redirect_stderr=True) |
| 84 | 84 |
| 85 | 85 |
| 86 def _BestEBuild(ebuilds): | 86 def _BestEBuild(ebuilds): |
| 87 """Returns the newest EBuild from a list of EBuild objects.""" | 87 """Returns the newest EBuild from a list of EBuild objects.""" |
| 88 from portage.versions import vercmp | 88 from cros_portage_versions import vercmp |
| 89 winner = ebuilds[0] | 89 winner = ebuilds[0] |
| 90 for ebuild in ebuilds[1:]: | 90 for ebuild in ebuilds[1:]: |
| 91 if vercmp(winner.version, ebuild.version) < 0: | 91 if vercmp(winner.version, ebuild.version) < 0: |
| 92 winner = ebuild | 92 winner = ebuild |
| 93 return winner | 93 return winner |
| 94 | 94 |
| 95 | 95 |
| 96 def _FindUprevCandidates(files): | 96 def _FindUprevCandidates(files): |
| 97 """Return a list of uprev candidates from specified list of files. | 97 """Return a list of uprev candidates from specified list of files. |
| 98 | 98 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 _SimpleRunCommand('git commit -m "%s"' % description) | 238 _SimpleRunCommand('git commit -m "%s"' % description) |
| 239 # Ugh. There has got to be an easier way to push to a tracking branch | 239 # Ugh. There has got to be an easier way to push to a tracking branch |
| 240 _SimpleRunCommand('git config push.default tracking') | 240 _SimpleRunCommand('git config push.default tracking') |
| 241 _SimpleRunCommand('git push') | 241 _SimpleRunCommand('git push') |
| 242 | 242 |
| 243 | 243 |
| 244 def _SimpleRunCommand(command): | 244 def _SimpleRunCommand(command): |
| 245 """Runs a shell command and returns stdout back to caller.""" | 245 """Runs a shell command and returns stdout back to caller.""" |
| 246 _Print(' + %s' % command) | 246 _Print(' + %s' % command) |
| 247 proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) | 247 proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) |
| 248 return proc_handle.communicate()[0] | 248 stdout = proc_handle.communicate()[0] |
| 249 retcode = proc_handle.wait() | |
| 250 if retcode != 0: | |
| 251 raise subprocess.CalledProcessError(retcode, command, output=stdout) | |
| 252 return stdout | |
| 249 | 253 |
| 250 | 254 |
| 251 # ======================= End Global Helper Functions ======================== | 255 # ======================= End Global Helper Functions ======================== |
| 252 | 256 |
| 253 | 257 |
| 254 class _GitBranch(object): | 258 class _GitBranch(object): |
| 255 """Wrapper class for a git branch.""" | 259 """Wrapper class for a git branch.""" |
| 256 | 260 |
| 257 def __init__(self, branch_name): | 261 def __init__(self, branch_name): |
| 258 """Sets up variables but does not create the branch.""" | 262 """Sets up variables but does not create the branch.""" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 | 294 |
| 291 class _EBuild(object): | 295 class _EBuild(object): |
| 292 """Wrapper class for an ebuild.""" | 296 """Wrapper class for an ebuild.""" |
| 293 | 297 |
| 294 def __init__(self, path): | 298 def __init__(self, path): |
| 295 """Initializes all data about an ebuild. | 299 """Initializes all data about an ebuild. |
| 296 | 300 |
| 297 Uses equery to find the ebuild path and sets data about an ebuild for | 301 Uses equery to find the ebuild path and sets data about an ebuild for |
| 298 easy reference. | 302 easy reference. |
| 299 """ | 303 """ |
| 300 from portage.versions import pkgsplit | 304 from cros_portage_versions import pkgsplit |
| 301 self.ebuild_path = path | 305 self.ebuild_path = path |
| 302 (self.ebuild_path_no_revision, | 306 (self.ebuild_path_no_revision, |
| 303 self.ebuild_path_no_version, | 307 self.ebuild_path_no_version, |
| 304 self.current_revision) = self._ParseEBuildPath(self.ebuild_path) | 308 self.current_revision) = self._ParseEBuildPath(self.ebuild_path) |
| 305 _, self.category, pkgpath, filename = path.rsplit('/', 3) | 309 _, self.category, pkgpath, filename = path.rsplit('/', 3) |
| 306 filename_no_suffix = os.path.join(filename.replace('.ebuild', '')) | 310 filename_no_suffix = os.path.join(filename.replace('.ebuild', '')) |
| 307 self.pkgname, version_no_rev, rev = pkgsplit(filename_no_suffix) | 311 self.pkgname, version_no_rev, rev = pkgsplit(filename_no_suffix) |
| 308 self.version = '%s-%s' % (version_no_rev, rev) | 312 self.version = '%s-%s' % (version_no_rev, rev) |
| 309 self.package = '%s/%s' % (self.category, self.pkgname) | 313 self.package = '%s/%s' % (self.category, self.pkgname) |
| 310 self.is_workon = False | 314 self.is_workon = False |
| 311 self.is_stable = False | 315 self.is_stable = False |
| 312 | 316 |
| 313 for line in fileinput.input(path): | 317 for line in fileinput.input(path): |
| 314 if line.startswith('inherit ') and 'cros-workon' in line: | 318 if line.startswith('inherit ') and 'cros-workon' in line: |
| 315 self.is_workon = True | 319 self.is_workon = True |
| 316 elif (line.startswith('KEYWORDS=') and '~' not in line and | 320 elif (line.startswith('KEYWORDS=') and '~' not in line and |
| 317 ('amd64' in line or 'x86' in line or 'arm' in line)): | 321 ('amd64' in line or 'x86' in line or 'arm' in line)): |
| 318 self.is_stable = True | 322 self.is_stable = True |
| 319 fileinput.close() | 323 fileinput.close() |
| 320 | 324 |
| 321 def GetCommitId(self): | 325 def GetCommitId(self): |
| 322 """Get the commit id for this ebuild.""" | 326 """Get the commit id for this ebuild.""" |
| 323 | 327 |
| 324 # Grab and evaluate CROS_WORKON variables from this ebuild. | 328 # Grab and evaluate CROS_WORKON variables from this ebuild. |
| 325 unstable_ebuild = '%s-9999.ebuild' % self.ebuild_path_no_version | 329 unstable_ebuild = '%s-9999.ebuild' % self.ebuild_path_no_version |
| 326 cmd = ('CROS_WORKON_LOCALNAME="%s" CROS_WORKON_PROJECT="%s" ' | 330 cmd = ('export CROS_WORKON_LOCALNAME="%s" CROS_WORKON_PROJECT="%s"; ' |
| 327 'eval $(grep -E "^CROS_WORKON" %s) && ' | 331 'eval $(grep -E "^CROS_WORKON" %s) && ' |
| 328 'echo $CROS_WORKON_PROJECT ' | 332 'echo $CROS_WORKON_PROJECT ' |
| 329 '$CROS_WORKON_LOCALNAME/$CROS_WORKON_SUBDIR' | 333 '$CROS_WORKON_LOCALNAME/$CROS_WORKON_SUBDIR' |
| 330 % (self.pkgname, self.pkgname, unstable_ebuild)) | 334 % (self.pkgname, self.pkgname, unstable_ebuild)) |
| 331 project, subdir = _SimpleRunCommand(cmd).split() | 335 project, subdir = _SimpleRunCommand(cmd).split() |
| 332 | 336 |
| 333 # Calculate srcdir. | 337 # Calculate srcdir. |
| 334 srcroot = gflags.FLAGS.srcroot | 338 srcroot = gflags.FLAGS.srcroot |
| 335 if self.category == 'chromeos-base': | 339 if self.category == 'chromeos-base': |
| 336 dir = 'platform' | 340 dir = 'platform' |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 def main(argv): | 484 def main(argv): |
| 481 try: | 485 try: |
| 482 argv = gflags.FLAGS(argv) | 486 argv = gflags.FLAGS(argv) |
| 483 if len(argv) != 2: | 487 if len(argv) != 2: |
| 484 _PrintUsageAndDie('Must specify a valid command') | 488 _PrintUsageAndDie('Must specify a valid command') |
| 485 else: | 489 else: |
| 486 command = argv[1] | 490 command = argv[1] |
| 487 except gflags.FlagsError, e : | 491 except gflags.FlagsError, e : |
| 488 _PrintUsageAndDie(str(e)) | 492 _PrintUsageAndDie(str(e)) |
| 489 | 493 |
| 490 package_list = gflags.FLAGS.packages.split() | 494 package_list = gflags.FLAGS.packages.split(':') |
| 491 _CheckSaneArguments(package_list, command) | 495 _CheckSaneArguments(package_list, command) |
| 492 if gflags.FLAGS.overlays: | 496 if gflags.FLAGS.overlays: |
| 493 overlays = dict((path, []) for path in gflags.FLAGS.overlays.split()) | 497 overlays = {} |
| 498 for path in gflags.FLAGS.overlays.split(':'): | |
| 499 if not os.path.exists(path): | |
|
sosa
2010/11/12 21:28:40
I guess this should also be isdir
davidjames
2010/11/12 21:37:50
Done.
| |
| 500 Die('Cannot find overlay: %s' % path) | |
| 501 overlays[path] = [] | |
| 494 else: | 502 else: |
| 503 Warning('Missing --overlays argument') | |
| 495 overlays = { | 504 overlays = { |
| 496 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], | 505 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], |
| 497 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] | 506 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] |
| 498 } | 507 } |
| 499 | 508 |
| 500 if command == 'commit': | 509 if command == 'commit': |
| 501 _BuildEBuildDictionary(overlays, gflags.FLAGS.all, package_list) | 510 _BuildEBuildDictionary(overlays, gflags.FLAGS.all, package_list) |
| 502 | 511 |
| 503 for overlay, ebuilds in overlays.items(): | 512 for overlay, ebuilds in overlays.items(): |
| 504 if not os.path.exists(overlay): | 513 if not os.path.exists(overlay): |
| 505 Warning("Skipping %s" % overlay) | 514 Warning("Skipping %s" % overlay) |
| 506 continue | 515 continue |
| 516 | |
| 517 # TODO(davidjames): Currently, all code that interacts with git depends on | |
| 518 # the cwd being set to the overlay directory. We should instead pass in | |
| 519 # this parameter so that we don't need to modify the cwd globally. | |
| 507 os.chdir(overlay) | 520 os.chdir(overlay) |
| 508 | 521 |
| 509 if command == 'clean': | 522 if command == 'clean': |
| 510 _Clean() | 523 _Clean() |
| 511 elif command == 'push': | 524 elif command == 'push': |
| 512 _PushChange() | 525 _PushChange() |
| 513 elif command == 'commit' and ebuilds: | 526 elif command == 'commit' and ebuilds: |
| 514 work_branch = _GitBranch(_STABLE_BRANCH_NAME) | 527 work_branch = _GitBranch(_STABLE_BRANCH_NAME) |
| 515 work_branch.CreateBranch() | 528 work_branch.CreateBranch() |
| 516 if not work_branch.Exists(): | 529 if not work_branch.Exists(): |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 535 raise | 548 raise |
| 536 | 549 |
| 537 if revved_packages: | 550 if revved_packages: |
| 538 _CleanStalePackages(gflags.FLAGS.board, revved_packages) | 551 _CleanStalePackages(gflags.FLAGS.board, revved_packages) |
| 539 else: | 552 else: |
| 540 work_branch.Delete() | 553 work_branch.Delete() |
| 541 | 554 |
| 542 | 555 |
| 543 if __name__ == '__main__': | 556 if __name__ == '__main__': |
| 544 main(sys.argv) | 557 main(sys.argv) |
| OLD | NEW |