Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: cros_mark_as_stable.py

Issue 4019005: Clean package cache for packages you are building. (Closed) Base URL: http://git.chromium.org/git/crosutils.git
Patch Set: Ws Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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', 'x86-generic', 22 gflags.DEFINE_string('board', 'x86-generic',
23 'Board for which the package belongs.', short_name='b') 23 'Board for which the package belongs.', short_name='b')
24 gflags.DEFINE_string('commit_ids', '',
25 """Optional list of commit ids for each package.
26 This list must either be empty or have the same length as
27 the packages list. If not set all rev'd ebuilds will have
28 empty commit id's.""",
29 short_name='i')
30 gflags.DEFINE_string('packages', '', 24 gflags.DEFINE_string('packages', '',
31 'Space separated list of packages to mark as stable.', 25 'Space separated list of packages to mark as stable.',
32 short_name='p') 26 short_name='p')
33 gflags.DEFINE_string('push_options', '', 27 gflags.DEFINE_string('push_options', '',
34 'Options to use with git-cl push using push command.') 28 'Options to use with git-cl push using push command.')
35 gflags.DEFINE_string('srcroot', '%s/trunk/src' % os.environ['HOME'], 29 gflags.DEFINE_string('srcroot', '%s/trunk/src' % os.environ['HOME'],
36 'Path to root src directory.', 30 'Path to root src directory.',
37 short_name='r') 31 short_name='r')
38 gflags.DEFINE_string('tracking_branch', 'cros/master', 32 gflags.DEFINE_string('tracking_branch', 'cros/master',
39 'Used with commit to specify branch to track against.', 33 'Used with commit to specify branch to track against.',
(...skipping 24 matching lines...) Expand all
64 58
65 # ======================= Global Helper Functions ======================== 59 # ======================= Global Helper Functions ========================
66 60
67 61
68 def _Print(message): 62 def _Print(message):
69 """Verbose print function.""" 63 """Verbose print function."""
70 if gflags.FLAGS.verbose: 64 if gflags.FLAGS.verbose:
71 Info(message) 65 Info(message)
72 66
73 67
68 def _CleanStalePackages(board, package_array):
69 """Cleans up stale package info from a previous build."""
70 Info('Cleaning up stale packages %s.' % package_array)
71 unmerge_board_cmd = ['emerge-%s' % board, '--unmerge']
72 unmerge_board_cmd.extend(package_array)
73 RunCommand(unmerge_board_cmd, env=env)
74
75 unmerge_host_cmd = ['sudo', 'emerge', '--unmerge']
76 unmerge_host_cmd.extend(package_array)
77 RunCommand(unmerge_host_cmd, env=env)
78
79 RunCommand(['eclean-%s' % board, '-d', 'packages'], redirect_stderr=True)
80 RunCommand(['sudo', 'eclean', '-d', 'packages'], redirect_stderr=True)
81
82
74 def _BestEBuild(ebuilds): 83 def _BestEBuild(ebuilds):
75 """Returns the newest EBuild from a list of EBuild objects.""" 84 """Returns the newest EBuild from a list of EBuild objects."""
76 from portage.versions import vercmp 85 from portage.versions import vercmp
77 winner = ebuilds[0] 86 winner = ebuilds[0]
78 for ebuild in ebuilds[1:]: 87 for ebuild in ebuilds[1:]:
79 if vercmp(winner.version, ebuild.version) < 0: 88 if vercmp(winner.version, ebuild.version) < 0:
80 winner = ebuild 89 winner = ebuild
81 return winner 90 return winner
82 91
83 92
(...skipping 12 matching lines...) Expand all
96 if ebuild.is_workon: 105 if ebuild.is_workon:
97 workon_dir = True 106 workon_dir = True
98 if ebuild.is_stable: 107 if ebuild.is_stable:
99 stable_ebuilds.append(ebuild) 108 stable_ebuilds.append(ebuild)
100 else: 109 else:
101 unstable_ebuilds.append(ebuild) 110 unstable_ebuilds.append(ebuild)
102 111
103 # If we found a workon ebuild in this directory, apply some sanity checks. 112 # If we found a workon ebuild in this directory, apply some sanity checks.
104 if workon_dir: 113 if workon_dir:
105 if len(unstable_ebuilds) > 1: 114 if len(unstable_ebuilds) > 1:
106 Die('Found multiple unstable ebuilds in %s' % root) 115 Die('Found multiple unstable ebuilds in %s' % os.path.dirname(path))
107 if len(stable_ebuilds) > 1: 116 if len(stable_ebuilds) > 1:
108 stable_ebuilds = [_BestEBuild(stable_ebuilds)] 117 stable_ebuilds = [_BestEBuild(stable_ebuilds)]
109 118
110 # Print a warning if multiple stable ebuilds are found in the same 119 # Print a warning if multiple stable ebuilds are found in the same
111 # directory. Storing multiple stable ebuilds is error-prone because 120 # directory. Storing multiple stable ebuilds is error-prone because
112 # the older ebuilds will not get rev'd. 121 # the older ebuilds will not get rev'd.
113 # 122 #
114 # We make a special exception for x11-drivers/xf86-video-msm for legacy 123 # We make a special exception for x11-drivers/xf86-video-msm for legacy
115 # reasons. 124 # reasons.
116 if stable_ebuilds[0].package != 'x11-drivers/xf86-video-msm': 125 if stable_ebuilds[0].package != 'x11-drivers/xf86-video-msm':
117 Warning('Found multiple stable ebuilds in %s' % root) 126 Warning('Found multiple stable ebuilds in %s' % os.path.dirname(path))
118 127
119 if not unstable_ebuilds: 128 if not unstable_ebuilds:
120 Die('Missing 9999 ebuild in %s' % root) 129 Die('Missing 9999 ebuild in %s' % os.path.dirname(path))
121 if not stable_ebuilds: 130 if not stable_ebuilds:
122 Die('Missing stable ebuild in %s' % root) 131 Die('Missing stable ebuild in %s' % os.path.dirname(path))
123 132
124 if stable_ebuilds: 133 if stable_ebuilds:
125 return stable_ebuilds[0] 134 return stable_ebuilds[0]
126 else: 135 else:
127 return None 136 return None
128 137
129 138
130 def _BuildEBuildDictionary(overlays, all, packages): 139 def _BuildEBuildDictionary(overlays, all, packages):
131 """Build a dictionary of the ebuilds in the specified overlays. 140 """Build a dictionary of the ebuilds in the specified overlays.
132 141
133 overlays: A map which maps overlay directories to arrays of stable EBuilds 142 overlays: A map which maps overlay directories to arrays of stable EBuilds
134 inside said directories. 143 inside said directories.
135 all: Whether to include all ebuilds in the specified directories. If true, 144 all: Whether to include all ebuilds in the specified directories. If true,
136 then we gather all packages in the directories regardless of whether 145 then we gather all packages in the directories regardless of whether
137 they are in our set of packages. 146 they are in our set of packages.
138 packages: A set of the packages we want to gather. 147 packages: A set of the packages we want to gather.
139 """ 148 """
140 for overlay in overlays: 149 for overlay in overlays:
141 for root_dir, dirs, files in os.walk(overlay): 150 for package_dir, dirs, files in os.walk(overlay):
142 # Add stable ebuilds to overlays[overlay]. 151 # Add stable ebuilds to overlays[overlay].
143 paths = [os.path.join(root_dir, path) for path in files] 152 paths = [os.path.join(package_dir, path) for path in files]
144 ebuild = _FindStableEBuilds(paths) 153 ebuild = _FindStableEBuilds(paths)
145 154
146 # If the --all option isn't used, we only want to update packages that 155 # If the --all option isn't used, we only want to update packages that
147 # are in packages. 156 # are in packages.
148 if ebuild and (all or ebuild.package in packages): 157 if ebuild and (all or ebuild.package in packages):
149 overlays[overlay].append(ebuild) 158 overlays[overlay].append(ebuild)
150 159
151 160
152 def _CheckOnStabilizingBranch(): 161 def _CheckOnStabilizingBranch():
153 """Returns true if the git branch is on the stabilizing branch.""" 162 """Returns true if the git branch is on the stabilizing branch."""
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 srcdir = os.path.join(srcroot, 'third_party/kernel/files') 336 srcdir = os.path.join(srcroot, 'third_party/kernel/files')
328 337
329 if not os.path.exists(srcdir): 338 if not os.path.exists(srcdir):
330 Die('Cannot find commit id for %s' % self.ebuild_path) 339 Die('Cannot find commit id for %s' % self.ebuild_path)
331 340
332 # Verify that we're grabbing the commit id from the right project name. 341 # Verify that we're grabbing the commit id from the right project name.
333 # NOTE: chromeos-kernel has the wrong project name, so it fails this 342 # NOTE: chromeos-kernel has the wrong project name, so it fails this
334 # check. 343 # check.
335 # TODO(davidjames): Fix the project name in the chromeos-kernel ebuild. 344 # TODO(davidjames): Fix the project name in the chromeos-kernel ebuild.
336 cmd = 'cd %s && git config --get remote.cros.projectname' % srcdir 345 cmd = 'cd %s && git config --get remote.cros.projectname' % srcdir
337 actual_project =_SimpleRunCommand(cmd).rstrip() 346 actual_project = _SimpleRunCommand(cmd).rstrip()
338 if project not in (actual_project, 'chromeos-kernel'): 347 if project not in (actual_project, 'chromeos-kernel'):
339 Die('Project name mismatch for %s (%s != %s)' % (unstable_ebuild, project, 348 Die('Project name mismatch for %s (%s != %s)' % (unstable_ebuild, project,
340 actual_project)) 349 actual_project))
341 350
342 # Get commit id. 351 # Get commit id.
343 output = _SimpleRunCommand('cd %s && git rev-parse HEAD' % srcdir) 352 output = _SimpleRunCommand('cd %s && git rev-parse HEAD' % srcdir)
344 if not output: 353 if not output:
345 Die('Missing commit id for %s' % self.ebuild_path) 354 Die('Missing commit id for %s' % self.ebuild_path)
346 return output.rstrip() 355 return output.rstrip()
347 356
(...skipping 21 matching lines...) Expand all
369 revision = int(rev_string) 378 revision = int(rev_string)
370 return (ebuild_no_rev, ebuild_no_version, revision) 379 return (ebuild_no_rev, ebuild_no_version, revision)
371 380
372 381
373 class EBuildStableMarker(object): 382 class EBuildStableMarker(object):
374 """Class that revs the ebuild and commits locally or pushes the change.""" 383 """Class that revs the ebuild and commits locally or pushes the change."""
375 384
376 def __init__(self, ebuild): 385 def __init__(self, ebuild):
377 self._ebuild = ebuild 386 self._ebuild = ebuild
378 387
379 def RevEBuild(self, commit_id="", redirect_file=None): 388 def RevEBuild(self, commit_id='', redirect_file=None):
380 """Revs an ebuild given the git commit id. 389 """Revs an ebuild given the git commit id.
381 390
382 By default this class overwrites a new ebuild given the normal 391 By default this class overwrites a new ebuild given the normal
383 ebuild rev'ing logic. However, a user can specify a redirect_file 392 ebuild rev'ing logic. However, a user can specify a redirect_file
384 to redirect the new stable ebuild to another file. 393 to redirect the new stable ebuild to another file.
385 394
386 Args: 395 Args:
387 commit_id: String corresponding to the commit hash of the developer 396 commit_id: String corresponding to the commit hash of the developer
388 package to rev. 397 package to rev.
389 redirect_file: Optional file to write the new ebuild. By default 398 redirect_file: Optional file to write the new ebuild. By default
390 it is written using the standard rev'ing logic. This file must be 399 it is written using the standard rev'ing logic. This file must be
391 opened and closed by the caller. 400 opened and closed by the caller.
392 401
393 Raises: 402 Raises:
394 OSError: Error occurred while creating a new ebuild. 403 OSError: Error occurred while creating a new ebuild.
395 IOError: Error occurred while writing to the new revved ebuild file. 404 IOError: Error occurred while writing to the new revved ebuild file.
405 Returns:
406 True if the revved package is different than the old ebuild.
396 """ 407 """
397 # TODO(sosa): Change to a check. 408 # TODO(sosa): Change to a check.
398 if not self._ebuild: 409 if not self._ebuild:
399 Die('Invalid ebuild given to EBuildStableMarker') 410 Die('Invalid ebuild given to EBuildStableMarker')
400 411
401 new_ebuild_path = '%s-r%d.ebuild' % (self._ebuild.ebuild_path_no_revision, 412 new_ebuild_path = '%s-r%d.ebuild' % (self._ebuild.ebuild_path_no_revision,
402 self._ebuild.current_revision + 1) 413 self._ebuild.current_revision + 1)
403 414
404 _Print('Creating new stable ebuild %s' % new_ebuild_path) 415 _Print('Creating new stable ebuild %s' % new_ebuild_path)
405 workon_ebuild = '%s-9999.ebuild' % self._ebuild.ebuild_path_no_version 416 workon_ebuild = '%s-9999.ebuild' % self._ebuild.ebuild_path_no_version
406 if not os.path.exists(workon_ebuild): 417 if not os.path.exists(workon_ebuild):
407 Die('Missing 9999 ebuild: %s' % workon_ebuild) 418 Die('Missing 9999 ebuild: %s' % workon_ebuild)
408 shutil.copyfile(workon_ebuild, new_ebuild_path) 419 shutil.copyfile(workon_ebuild, new_ebuild_path)
409 420
410 for line in fileinput.input(new_ebuild_path, inplace=1): 421 for line in fileinput.input(new_ebuild_path, inplace=1):
411 # Has to be done here to get changes to sys.stdout from fileinput.input. 422 # Has to be done here to get changes to sys.stdout from fileinput.input.
412 if not redirect_file: 423 if not redirect_file:
413 redirect_file = sys.stdout 424 redirect_file = sys.stdout
414 if line.startswith('KEYWORDS'): 425 if line.startswith('KEYWORDS'):
415 # Actually mark this file as stable by removing ~'s. 426 # Actually mark this file as stable by removing ~'s.
416 redirect_file.write(line.replace("~", "")) 427 redirect_file.write(line.replace('~', ''))
417 elif line.startswith('EAPI'): 428 elif line.startswith('EAPI'):
418 # Always add new commit_id after EAPI definition. 429 # Always add new commit_id after EAPI definition.
419 redirect_file.write(line) 430 redirect_file.write(line)
420 redirect_file.write('CROS_WORKON_COMMIT="%s"\n' % commit_id) 431 redirect_file.write('CROS_WORKON_COMMIT="%s"\n' % commit_id)
421 elif not line.startswith('CROS_WORKON_COMMIT'): 432 elif not line.startswith('CROS_WORKON_COMMIT'):
422 # Skip old CROS_WORKON_COMMIT definition. 433 # Skip old CROS_WORKON_COMMIT definition.
423 redirect_file.write(line) 434 redirect_file.write(line)
424 fileinput.close() 435 fileinput.close()
425 436
426 # If the new ebuild is identical to the old ebuild, return False and
427 # delete our changes.
428 old_ebuild_path = self._ebuild.ebuild_path 437 old_ebuild_path = self._ebuild.ebuild_path
429 diff_cmd = ['diff', '-Bu', old_ebuild_path, new_ebuild_path] 438 diff_cmd = ['diff', '-Bu', old_ebuild_path, new_ebuild_path]
430 if 0 == RunCommand(diff_cmd, exit_code=True, 439 if 0 == RunCommand(diff_cmd, exit_code=True, redirect_stdout=True,
431 print_cmd=gflags.FLAGS.verbose): 440 redirect_stderr=True, print_cmd=gflags.FLAGS.verbose):
432 os.unlink(new_ebuild_path) 441 os.unlink(new_ebuild_path)
433 return False 442 return False
434 else: 443 else:
435 _Print('Adding new stable ebuild to git') 444 _Print('Adding new stable ebuild to git')
436 _SimpleRunCommand('git add %s' % new_ebuild_path) 445 _SimpleRunCommand('git add %s' % new_ebuild_path)
437 446
438 _Print('Removing old ebuild from git') 447 _Print('Removing old ebuild from git')
439 _SimpleRunCommand('git rm %s' % old_ebuild_path) 448 _SimpleRunCommand('git rm %s' % old_ebuild_path)
440 return True 449 return True
441 450
(...skipping 25 matching lines...) Expand all
467 except gflags.FlagsError, e : 476 except gflags.FlagsError, e :
468 _PrintUsageAndDie(str(e)) 477 _PrintUsageAndDie(str(e))
469 478
470 package_list = gflags.FLAGS.packages.split() 479 package_list = gflags.FLAGS.packages.split()
471 _CheckSaneArguments(package_list, command) 480 _CheckSaneArguments(package_list, command)
472 481
473 overlays = { 482 overlays = {
474 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [], 483 '%s/private-overlays/chromeos-overlay' % gflags.FLAGS.srcroot: [],
475 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: [] 484 '%s/third_party/chromiumos-overlay' % gflags.FLAGS.srcroot: []
476 } 485 }
477 all = gflags.FLAGS.all
478 486
479 if command == 'commit': 487 if command == 'commit':
480 _BuildEBuildDictionary(overlays, all, package_list) 488 _BuildEBuildDictionary(overlays, gflags.FLAGS.all, package_list)
481 489
482 for overlay, ebuilds in overlays.items(): 490 for overlay, ebuilds in overlays.items():
483 if not os.path.exists(overlay): 491 if not os.path.exists(overlay): continue
484 continue
485 os.chdir(overlay) 492 os.chdir(overlay)
486 493
487 if command == 'clean': 494 if command == 'clean':
488 _Clean() 495 _Clean()
489 elif command == 'push': 496 elif command == 'push':
490 _PushChange() 497 _PushChange()
491 elif command == 'commit' and ebuilds: 498 elif command == 'commit' and ebuilds:
499 work_branch = _GitBranch(_STABLE_BRANCH_NAME)
500 work_branch.CreateBranch()
501 if not work_branch.Exists():
502 Die('Unable to create stabilizing branch in %s' % overlay)
503
504 # Contains the array of packages we actually revved.
505 revved_packages = []
492 for ebuild in ebuilds: 506 for ebuild in ebuilds:
493 try: 507 try:
494 _Print('Working on %s' % ebuild.package) 508 _Print('Working on %s' % ebuild.package)
495 worker = EBuildStableMarker(ebuild) 509 worker = EBuildStableMarker(ebuild)
496 commit_id = ebuild.GetCommitId() 510 commit_id = ebuild.GetCommitId()
497 if worker.RevEBuild(commit_id): 511 if worker.RevEBuild(commit_id):
498 if not _CheckOnStabilizingBranch():
499 work_branch = _GitBranch(_STABLE_BRANCH_NAME)
500 work_branch.CreateBranch()
501 if not work_branch.Exists():
502 Die('Unable to create stabilizing branch in %s' % overlay)
503 message = _GIT_COMMIT_MESSAGE % (ebuild.package, commit_id) 512 message = _GIT_COMMIT_MESSAGE % (ebuild.package, commit_id)
504 worker.CommitChange(message) 513 worker.CommitChange(message)
514 revved_packages.append(ebuild.package)
515
505 except (OSError, IOError): 516 except (OSError, IOError):
506 Warning('Cannot rev %s\n' % ebuild.package, 517 Warning('Cannot rev %s\n' % ebuild.package,
507 'Note you will have to go into %s ' 518 'Note you will have to go into %s '
508 'and reset the git repo yourself.' % overlay) 519 'and reset the git repo yourself.' % overlay)
509 raise 520 raise
510 521
522 if revved_packages:
523 _CleanStalePackages(gflags.FLAGS.board, revved_packages)
524 else:
525 work_branch.Delete()
526
511 527
512 if __name__ == '__main__': 528 if __name__ == '__main__':
513 main(sys.argv) 529 main(sys.argv)
514
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698