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.""" |
sosa
2010/11/12 19:18:46
Can you add a comment here that this should always
| |
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 27 matching lines...) Expand all Loading... | |
66 """Verbose print function.""" | 66 """Verbose print function.""" |
67 if gflags.FLAGS.verbose: | 67 if gflags.FLAGS.verbose: |
68 Info(message) | 68 Info(message) |
69 | 69 |
70 | 70 |
71 def _CleanStalePackages(board, package_array): | 71 def _CleanStalePackages(board, package_array): |
72 """Cleans up stale package info from a previous build.""" | 72 """Cleans up stale package info from a previous build.""" |
73 Info('Cleaning up stale packages %s.' % package_array) | 73 Info('Cleaning up stale packages %s.' % package_array) |
74 unmerge_board_cmd = ['emerge-%s' % board, '--unmerge'] | 74 unmerge_board_cmd = ['emerge-%s' % board, '--unmerge'] |
75 unmerge_board_cmd.extend(package_array) | 75 unmerge_board_cmd.extend(package_array) |
76 RunCommand(unmerge_board_cmd) | 76 RunCommand(unmerge_board_cmd, enter_chroot=True) |
77 | 77 |
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, enter_chroot=True) |
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 enter_chroot=True) |
84 RunCommand(['sudo', 'eclean', '-d', 'packages'], redirect_stderr=True, | |
85 enter_chroot=True) | |
84 | 86 |
85 | 87 |
86 def _BestEBuild(ebuilds): | 88 def _BestEBuild(ebuilds): |
87 """Returns the newest EBuild from a list of EBuild objects.""" | 89 """Returns the newest EBuild from a list of EBuild objects.""" |
88 from portage.versions import vercmp | 90 from cros_portage_versions import vercmp |
89 winner = ebuilds[0] | 91 winner = ebuilds[0] |
90 for ebuild in ebuilds[1:]: | 92 for ebuild in ebuilds[1:]: |
91 if vercmp(winner.version, ebuild.version) < 0: | 93 if vercmp(winner.version, ebuild.version) < 0: |
92 winner = ebuild | 94 winner = ebuild |
93 return winner | 95 return winner |
94 | 96 |
95 | 97 |
96 def _FindUprevCandidates(files): | 98 def _FindUprevCandidates(files): |
97 """Return a list of uprev candidates from specified list of files. | 99 """Return a list of uprev candidates from specified list of files. |
98 | 100 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 _SimpleRunCommand('git commit -m "%s"' % description) | 240 _SimpleRunCommand('git commit -m "%s"' % description) |
239 # Ugh. There has got to be an easier way to push to a tracking branch | 241 # Ugh. There has got to be an easier way to push to a tracking branch |
240 _SimpleRunCommand('git config push.default tracking') | 242 _SimpleRunCommand('git config push.default tracking') |
241 _SimpleRunCommand('git push') | 243 _SimpleRunCommand('git push') |
242 | 244 |
243 | 245 |
244 def _SimpleRunCommand(command): | 246 def _SimpleRunCommand(command): |
245 """Runs a shell command and returns stdout back to caller.""" | 247 """Runs a shell command and returns stdout back to caller.""" |
246 _Print(' + %s' % command) | 248 _Print(' + %s' % command) |
247 proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) | 249 proc_handle = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) |
248 return proc_handle.communicate()[0] | 250 stdout = proc_handle.communicate()[0] |
251 retcode = proc_handle.wait() | |
252 assert retcode == 0, "Return code %s for command: %s" % (retcode, command) | |
253 return stdout | |
249 | 254 |
250 | 255 |
251 # ======================= End Global Helper Functions ======================== | 256 # ======================= End Global Helper Functions ======================== |
252 | 257 |
253 | 258 |
254 class _GitBranch(object): | 259 class _GitBranch(object): |
255 """Wrapper class for a git branch.""" | 260 """Wrapper class for a git branch.""" |
256 | 261 |
257 def __init__(self, branch_name): | 262 def __init__(self, branch_name): |
258 """Sets up variables but does not create the branch.""" | 263 """Sets up variables but does not create the branch.""" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 | 295 |
291 class _EBuild(object): | 296 class _EBuild(object): |
292 """Wrapper class for an ebuild.""" | 297 """Wrapper class for an ebuild.""" |
293 | 298 |
294 def __init__(self, path): | 299 def __init__(self, path): |
295 """Initializes all data about an ebuild. | 300 """Initializes all data about an ebuild. |
296 | 301 |
297 Uses equery to find the ebuild path and sets data about an ebuild for | 302 Uses equery to find the ebuild path and sets data about an ebuild for |
298 easy reference. | 303 easy reference. |
299 """ | 304 """ |
300 from portage.versions import pkgsplit | 305 from cros_portage_versions import pkgsplit |
301 self.ebuild_path = path | 306 self.ebuild_path = path |
302 (self.ebuild_path_no_revision, | 307 (self.ebuild_path_no_revision, |
303 self.ebuild_path_no_version, | 308 self.ebuild_path_no_version, |
304 self.current_revision) = self._ParseEBuildPath(self.ebuild_path) | 309 self.current_revision) = self._ParseEBuildPath(self.ebuild_path) |
305 _, self.category, pkgpath, filename = path.rsplit('/', 3) | 310 _, self.category, pkgpath, filename = path.rsplit('/', 3) |
306 filename_no_suffix = os.path.join(filename.replace('.ebuild', '')) | 311 filename_no_suffix = os.path.join(filename.replace('.ebuild', '')) |
307 self.pkgname, version_no_rev, rev = pkgsplit(filename_no_suffix) | 312 self.pkgname, version_no_rev, rev = pkgsplit(filename_no_suffix) |
308 self.version = '%s-%s' % (version_no_rev, rev) | 313 self.version = '%s-%s' % (version_no_rev, rev) |
309 self.package = '%s/%s' % (self.category, self.pkgname) | 314 self.package = '%s/%s' % (self.category, self.pkgname) |
310 self.is_workon = False | 315 self.is_workon = False |
311 self.is_stable = False | 316 self.is_stable = False |
312 | 317 |
313 for line in fileinput.input(path): | 318 for line in fileinput.input(path): |
314 if line.startswith('inherit ') and 'cros-workon' in line: | 319 if line.startswith('inherit ') and 'cros-workon' in line: |
315 self.is_workon = True | 320 self.is_workon = True |
316 elif (line.startswith('KEYWORDS=') and '~' not in line and | 321 elif (line.startswith('KEYWORDS=') and '~' not in line and |
317 ('amd64' in line or 'x86' in line or 'arm' in line)): | 322 ('amd64' in line or 'x86' in line or 'arm' in line)): |
318 self.is_stable = True | 323 self.is_stable = True |
319 fileinput.close() | 324 fileinput.close() |
320 | 325 |
321 def GetCommitId(self): | 326 def GetCommitId(self): |
322 """Get the commit id for this ebuild.""" | 327 """Get the commit id for this ebuild.""" |
323 | 328 |
324 # Grab and evaluate CROS_WORKON variables from this ebuild. | 329 # Grab and evaluate CROS_WORKON variables from this ebuild. |
325 unstable_ebuild = '%s-9999.ebuild' % self.ebuild_path_no_version | 330 unstable_ebuild = '%s-9999.ebuild' % self.ebuild_path_no_version |
326 cmd = ('CROS_WORKON_LOCALNAME="%s" CROS_WORKON_PROJECT="%s" ' | 331 cmd = ('export CROS_WORKON_LOCALNAME="%s" CROS_WORKON_PROJECT="%s"; ' |
327 'eval $(grep -E "^CROS_WORKON" %s) && ' | 332 'eval $(grep -E "^CROS_WORKON" %s) && ' |
328 'echo $CROS_WORKON_PROJECT ' | 333 'echo $CROS_WORKON_PROJECT ' |
329 '$CROS_WORKON_LOCALNAME/$CROS_WORKON_SUBDIR' | 334 '$CROS_WORKON_LOCALNAME/$CROS_WORKON_SUBDIR' |
330 % (self.pkgname, self.pkgname, unstable_ebuild)) | 335 % (self.pkgname, self.pkgname, unstable_ebuild)) |
331 project, subdir = _SimpleRunCommand(cmd).split() | 336 project, subdir = _SimpleRunCommand(cmd).split() |
332 | 337 |
333 # Calculate srcdir. | 338 # Calculate srcdir. |
334 srcroot = gflags.FLAGS.srcroot | 339 srcroot = gflags.FLAGS.srcroot |
335 if self.category == 'chromeos-base': | 340 if self.category == 'chromeos-base': |
336 dir = 'platform' | 341 dir = 'platform' |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 def main(argv): | 485 def main(argv): |
481 try: | 486 try: |
482 argv = gflags.FLAGS(argv) | 487 argv = gflags.FLAGS(argv) |
483 if len(argv) != 2: | 488 if len(argv) != 2: |
484 _PrintUsageAndDie('Must specify a valid command') | 489 _PrintUsageAndDie('Must specify a valid command') |
485 else: | 490 else: |
486 command = argv[1] | 491 command = argv[1] |
487 except gflags.FlagsError, e : | 492 except gflags.FlagsError, e : |
488 _PrintUsageAndDie(str(e)) | 493 _PrintUsageAndDie(str(e)) |
489 | 494 |
490 package_list = gflags.FLAGS.packages.split() | 495 package_list = gflags.FLAGS.packages.split(':') |
491 _CheckSaneArguments(package_list, command) | 496 _CheckSaneArguments(package_list, command) |
492 if gflags.FLAGS.overlays: | 497 if gflags.FLAGS.overlays: |
493 overlays = dict((path, []) for path in gflags.FLAGS.overlays.split()) | 498 overlays = {} |
499 for path in gflags.FLAGS.overlays.split(':'): | |
500 if not os.path.exists(path): | |
501 Die('Cannot find overlay: %s' % path) | |
502 overlays[path] = [] | |
494 else: | 503 else: |
504 Warning('Missing --overlays argument') | |
495 overlays = { | 505 overlays = { |
496 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], | 506 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], |
497 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] | 507 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] |
498 } | 508 } |
499 | 509 |
500 if command == 'commit': | 510 if command == 'commit': |
501 _BuildEBuildDictionary(overlays, gflags.FLAGS.all, package_list) | 511 _BuildEBuildDictionary(overlays, gflags.FLAGS.all, package_list) |
502 | 512 |
513 cwd = os.getcwd() | |
503 for overlay, ebuilds in overlays.items(): | 514 for overlay, ebuilds in overlays.items(): |
504 if not os.path.exists(overlay): | 515 if not os.path.exists(overlay): |
505 Warning("Skipping %s" % overlay) | 516 Warning("Skipping %s" % overlay) |
506 continue | 517 continue |
507 os.chdir(overlay) | 518 os.chdir(overlay) |
508 | 519 |
509 if command == 'clean': | 520 if command == 'clean': |
510 _Clean() | 521 _Clean() |
511 elif command == 'push': | 522 elif command == 'push': |
512 _PushChange() | 523 _PushChange() |
(...skipping 14 matching lines...) Expand all Loading... | |
527 message = _GIT_COMMIT_MESSAGE % (ebuild.package, commit_id) | 538 message = _GIT_COMMIT_MESSAGE % (ebuild.package, commit_id) |
528 worker.CommitChange(message) | 539 worker.CommitChange(message) |
529 revved_packages.append(ebuild.package) | 540 revved_packages.append(ebuild.package) |
530 | 541 |
531 except (OSError, IOError): | 542 except (OSError, IOError): |
532 Warning('Cannot rev %s\n' % ebuild.package, | 543 Warning('Cannot rev %s\n' % ebuild.package, |
533 'Note you will have to go into %s ' | 544 'Note you will have to go into %s ' |
534 'and reset the git repo yourself.' % overlay) | 545 'and reset the git repo yourself.' % overlay) |
535 raise | 546 raise |
536 | 547 |
548 os.chdir(cwd) | |
537 if revved_packages: | 549 if revved_packages: |
538 _CleanStalePackages(gflags.FLAGS.board, revved_packages) | 550 _CleanStalePackages(gflags.FLAGS.board, revved_packages) |
539 else: | 551 else: |
540 work_branch.Delete() | 552 work_branch.Delete() |
541 | 553 |
542 | 554 |
543 if __name__ == '__main__': | 555 if __name__ == '__main__': |
544 main(sys.argv) | 556 main(sys.argv) |
OLD | NEW |