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

Side by Side Diff: bin/cros_portage_upgrade.py

Issue 6756042: Rename cros_update to cros_portage_upgrade and Updater -> Upgrader. (Closed) Base URL: ssh://gitrw.chromium.org:9222/chromite.git@master
Patch Set: Created 9 years, 8 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 | « bin/cros_portage_upgrade ('k') | bin/cros_update » ('j') | 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/python2.6 1 #!/usr/bin/python2.6
2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Perform various tasks related to updating Portage packages.""" 6 """Perform various tasks related to updating Portage packages."""
7 7
8 import glob 8 import glob
9 import logging 9 import logging
10 import optparse 10 import optparse
11 import os 11 import os
12 import parallel_emerge 12 import parallel_emerge
13 import portage 13 import portage
14 import re 14 import re
15 import shutil 15 import shutil
16 import sys 16 import sys
17 17
18 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) 18 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
19 import chromite.lib.cros_build_lib as cros_lib 19 import chromite.lib.cros_build_lib as cros_lib
20 20
21 21
22 class Updater(object): 22 class Upgrader(object):
23 """A class to perform various tasks related to updating Portage packages.""" 23 """A class to perform various tasks related to updating Portage packages."""
24 24
25 def __init__(self, options, args): 25 def __init__(self, options, args):
26 self._options = options 26 self._options = options
27 self._args = args 27 self._args = args
28 self._stable_repo = os.path.join(self._options.srcroot, 28 self._stable_repo = os.path.join(self._options.srcroot,
29 'third_party', 'portage-stable') 29 'third_party', 'portage-stable')
30 self._upstream_repo = self._options.upstream 30 self._upstream_repo = self._options.upstream
31 if not self._upstream_repo: 31 if not self._upstream_repo:
32 self._upstream_repo = os.path.join(self._options.srcroot, 32 self._upstream_repo = os.path.join(self._options.srcroot,
33 'third_party', 'portage') 33 'third_party', 'portage')
34 34
35 @staticmethod 35 @staticmethod
36 def _GetPreOrderDepGraphPackage(deps_graph, package, pkglist, visited): 36 def _GetPreOrderDepGraphPackage(deps_graph, package, pkglist, visited):
37 """Collect packages from |deps_graph| into |pkglist| in pre-order.""" 37 """Collect packages from |deps_graph| into |pkglist| in pre-order."""
38 if package in visited: 38 if package in visited:
39 return 39 return
40 visited.add(package) 40 visited.add(package)
41 for parent in deps_graph[package]['provides']: 41 for parent in deps_graph[package]['provides']:
42 Updater._GetPreOrderDepGraphPackage(deps_graph, parent, pkglist, visited) 42 Upgrader._GetPreOrderDepGraphPackage(deps_graph, parent, pkglist, visited)
43 pkglist.append(package) 43 pkglist.append(package)
44 44
45 @staticmethod 45 @staticmethod
46 def _GetPreOrderDepGraph(deps_graph): 46 def _GetPreOrderDepGraph(deps_graph):
47 """Return packages from |deps_graph| in pre-order.""" 47 """Return packages from |deps_graph| in pre-order."""
48 pkglist = [] 48 pkglist = []
49 visited = set() 49 visited = set()
50 for package in deps_graph: 50 for package in deps_graph:
51 Updater._GetPreOrderDepGraphPackage(deps_graph, package, pkglist, visited) 51 Upgrader._GetPreOrderDepGraphPackage(deps_graph, package, pkglist,
52 visited)
52 return pkglist 53 return pkglist
53 54
54 @staticmethod 55 @staticmethod
55 def _IsStableEBuild(ebuild_path): 56 def _IsStableEBuild(ebuild_path):
56 """Returns true if |ebuild_path| is a stable ebuild, false otherwise.""" 57 """Returns true if |ebuild_path| is a stable ebuild, false otherwise."""
57 with open(ebuild_path, 'r') as ebuild: 58 with open(ebuild_path, 'r') as ebuild:
58 for line in ebuild: 59 for line in ebuild:
59 if line.startswith('KEYWORDS='): 60 if line.startswith('KEYWORDS='):
60 # TODO(petkov): Support non-x86 targets. 61 # TODO(petkov): Support non-x86 targets.
61 return re.search(r'[ "]x86[ "]', line) 62 return re.search(r'[ "]x86[ "]', line)
(...skipping 12 matching lines...) Expand all
74 (ebuild_path, cat) = os.path.split(ebuild_path) 75 (ebuild_path, cat) = os.path.split(ebuild_path)
75 (ebuild_path, overlay) = os.path.split(ebuild_path) 76 (ebuild_path, overlay) = os.path.split(ebuild_path)
76 return (overlay, cat, pn, pv) 77 return (overlay, cat, pn, pv)
77 78
78 def _FindLatestVersion(self, cpv): 79 def _FindLatestVersion(self, cpv):
79 """Returns the latest cpv in |_upstream_repo| if it's newer than |cpv|.""" 80 """Returns the latest cpv in |_upstream_repo| if it's newer than |cpv|."""
80 latest_cpv = cpv 81 latest_cpv = cpv
81 (cat, pn, version, rev) = portage.versions.catpkgsplit(cpv) 82 (cat, pn, version, rev) = portage.versions.catpkgsplit(cpv)
82 pkgpath = os.path.join(self._upstream_repo, cat, pn) 83 pkgpath = os.path.join(self._upstream_repo, cat, pn)
83 for ebuild_path in glob.glob(os.path.join(pkgpath, '%s*.ebuild' % pn)): 84 for ebuild_path in glob.glob(os.path.join(pkgpath, '%s*.ebuild' % pn)):
84 if not Updater._IsStableEBuild(ebuild_path): continue 85 if not Upgrader._IsStableEBuild(ebuild_path): continue
85 (overlay, cat, pn, pv) = self._SplitEBuildPath(ebuild_path) 86 (overlay, cat, pn, pv) = self._SplitEBuildPath(ebuild_path)
86 upstream_cpv = os.path.join(cat, pv) 87 upstream_cpv = os.path.join(cat, pv)
87 if portage.versions.pkgcmp(portage.versions.pkgsplit(upstream_cpv), 88 if portage.versions.pkgcmp(portage.versions.pkgsplit(upstream_cpv),
88 portage.versions.pkgsplit(latest_cpv)) > 0: 89 portage.versions.pkgsplit(latest_cpv)) > 0:
89 latest_cpv = upstream_cpv 90 latest_cpv = upstream_cpv
90 if latest_cpv != cpv: return latest_cpv 91 if latest_cpv != cpv: return latest_cpv
91 return None 92 return None
92 93
93 def _CopyUpstreamPackage(self, info): 94 def _CopyUpstreamPackage(self, info):
94 """Upgrades package described by |info| by copying from usptream. 95 """Upgrades package described by |info| by copying from usptream.
(...skipping 17 matching lines...) Expand all
112 # Copy the whole package except the ebuilds. 113 # Copy the whole package except the ebuilds.
113 shutil.copytree(upstream_pkgdir, pkgdir, 114 shutil.copytree(upstream_pkgdir, pkgdir,
114 ignore=shutil.ignore_patterns('*.ebuild')) 115 ignore=shutil.ignore_patterns('*.ebuild'))
115 # Copy just the ebuild that will be used in the build. 116 # Copy just the ebuild that will be used in the build.
116 shutil.copy2(os.path.join(upstream_pkgdir, 117 shutil.copy2(os.path.join(upstream_pkgdir,
117 latest_cpv.split('/')[1] + '.ebuild'), pkgdir) 118 latest_cpv.split('/')[1] + '.ebuild'), pkgdir)
118 self._RunGit(self._stable_repo, 'add ' + catpkgname) 119 self._RunGit(self._stable_repo, 'add ' + catpkgname)
119 return True 120 return True
120 121
121 def _UpgradePackage(self, info): 122 def _UpgradePackage(self, info):
122 """Updates |info| with latest_cpv and performs an upgrade if necessary.""" 123 """Updates |info| with latest_cpv and performs an upgrade if necessary."""
sosa 2011/03/30 18:38:59 Upgrade?
petkov 2011/03/30 18:49:48 It does _update_ the map structure and then "_upgr
123 cpv = info['cpv'] 124 cpv = info['cpv']
124 # No need to report or try to upgrade chromeos-base packages. 125 # No need to report or try to upgrade chromeos-base packages.
125 if cpv.startswith('chromeos-base/'): return 126 if cpv.startswith('chromeos-base/'): return
126 info['latest_cpv'] = self._FindLatestVersion(cpv) 127 info['latest_cpv'] = self._FindLatestVersion(cpv)
127 info['upgraded'] = self._CopyUpstreamPackage(info) 128 info['upgraded'] = self._CopyUpstreamPackage(info)
128 update = '' 129 upgrade = ''
129 if info['latest_cpv']: update = ' -> %s' % info['latest_cpv'] 130 if info['latest_cpv']: upgrade = ' -> %s' % info['latest_cpv']
130 upgraded = '' 131 upgraded = ''
131 if info['upgraded']: upgraded = ' (UPGRADED)' 132 if info['upgraded']: upgraded = ' (UPGRADED)'
132 print '[%s] %s%s%s' % (info['overlay'], info['cpv'], update, upgraded) 133 print '[%s] %s%s%s' % (info['overlay'], info['cpv'], upgrade, upgraded)
133 134
134 def _UpgradePackages(self, infolist): 135 def _UpgradePackages(self, infolist):
135 """Given a list of cpv info maps, adds the latest_cpv to the infos.""" 136 """Given a list of cpv info maps, adds the latest_cpv to the infos."""
136 dash_q = '' 137 dash_q = ''
137 if not self._options.verbose: dash_q = '-q' 138 if not self._options.verbose: dash_q = '-q'
138 try: 139 try:
139 # TODO(petkov): Currently portage's master branch is stale so we need to 140 # TODO(petkov): Currently portage's master branch is stale so we need to
140 # checkout latest upstream. At some point portage's master branch will be 141 # checkout latest upstream. At some point portage's master branch will be
141 # upstream so there will be no need to chdir/checkout. At that point we 142 # upstream so there will be no need to chdir/checkout. At that point we
142 # can also fuse this loop into the caller and avoid generating a separate 143 # can also fuse this loop into the caller and avoid generating a separate
(...skipping 22 matching lines...) Expand all
165 if not self._options.verbose: 166 if not self._options.verbose:
166 argv.append('--quiet') 167 argv.append('--quiet')
167 if self._options.rdeps: 168 if self._options.rdeps:
168 argv.append('--root-deps=rdeps') 169 argv.append('--root-deps=rdeps')
169 argv.extend(self._args) 170 argv.extend(self._args)
170 171
171 deps = parallel_emerge.DepGraphGenerator() 172 deps = parallel_emerge.DepGraphGenerator()
172 deps.Initialize(argv) 173 deps.Initialize(argv)
173 deps_tree, deps_info = deps.GenDependencyTree({}) 174 deps_tree, deps_info = deps.GenDependencyTree({})
174 deps_graph = deps.GenDependencyGraph(deps_tree, deps_info, {}) 175 deps_graph = deps.GenDependencyGraph(deps_tree, deps_info, {})
175 return Updater._GetPreOrderDepGraph(deps_graph) 176 return Upgrader._GetPreOrderDepGraph(deps_graph)
176 177
177 def _GetInfoListWithOverlays(self, cpvlist): 178 def _GetInfoListWithOverlays(self, cpvlist):
178 """Returns a list of cpv/overlay info maps corresponding to |cpvlist|.""" 179 """Returns a list of cpv/overlay info maps corresponding to |cpvlist|."""
179 infolist = [] 180 infolist = []
180 for cpv in cpvlist: 181 for cpv in cpvlist:
181 # TODO(petkov): Use internal portage utilities to find the overlay instead 182 # TODO(petkov): Use internal portage utilities to find the overlay instead
182 # of equery to improve performance, if possible. 183 # of equery to improve performance, if possible.
183 equery = ['equery-%s' % self._options.board, 'which', cpv] 184 equery = ['equery-%s' % self._options.board, 'which', cpv]
184 ebuild_path = cros_lib.RunCommand(equery, print_cmd=self._options.verbose, 185 ebuild_path = cros_lib.RunCommand(equery, print_cmd=self._options.verbose,
185 redirect_stdout=True).output.strip() 186 redirect_stdout=True).output.strip()
186 (overlay, cat, pn, pv) = self._SplitEBuildPath(ebuild_path) 187 (overlay, cat, pn, pv) = self._SplitEBuildPath(ebuild_path)
187 infolist.append({'cpv': cpv, 'overlay': overlay}) 188 infolist.append({'cpv': cpv, 'overlay': overlay})
188 189
189 return infolist 190 return infolist
190 191
191 def Run(self): 192 def Run(self):
192 """Runs the updater based on the supplied options and arguments. 193 """Runs the upgrader based on the supplied options and arguments.
193 194
194 Currently just lists all package dependencies in pre-order along with 195 Currently just lists all package dependencies in pre-order along with
195 potential upgrades.""" 196 potential upgrades."""
196 cpvlist = self._GetCurrentVersions() 197 cpvlist = self._GetCurrentVersions()
197 infolist = self._GetInfoListWithOverlays(cpvlist) 198 infolist = self._GetInfoListWithOverlays(cpvlist)
198 self._UpgradePackages(infolist) 199 self._UpgradePackages(infolist)
199 200
200 def main(): 201 def main():
201 usage = 'Usage: %prog [options] packages...' 202 usage = 'Usage: %prog [options] packages...'
202 parser = optparse.OptionParser(usage=usage) 203 parser = optparse.OptionParser(usage=usage)
(...skipping 20 matching lines...) Expand all
223 if (options.verbose): logging.basicConfig(level=logging.DEBUG) 224 if (options.verbose): logging.basicConfig(level=logging.DEBUG)
224 225
225 if not options.board: 226 if not options.board:
226 parser.print_help() 227 parser.print_help()
227 cros_lib.Die('board is required') 228 cros_lib.Die('board is required')
228 229
229 if not args: 230 if not args:
230 parser.print_help() 231 parser.print_help()
231 cros_lib.Die('no packages provided') 232 cros_lib.Die('no packages provided')
232 233
233 updater = Updater(options, args) 234 upgrader = Upgrader(options, args)
234 updater.Run() 235 upgrader.Run()
235 236
236 237
237 if __name__ == '__main__': 238 if __name__ == '__main__':
238 main() 239 main()
OLDNEW
« no previous file with comments | « bin/cros_portage_upgrade ('k') | bin/cros_update » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698