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

Side by Side Diff: native_client_sdk/src/build_tools/sdk_tools/commands/update.py

Issue 11228013: [NaCl SDK] Refactor sdk_update*. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests pass Created 8 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
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import cygtar
6 import download
7 import logging
8 import os
9 from sdk_update_common import Error
10 import sdk_update_common
11 import urlparse
12 import urllib2
13
14
15 RECOMMENDED = 'recommended'
16 SDK_TOOLS = 'sdk_tools'
17 HTTP_CONTENT_LENGTH = 'Content-Length' # HTTP Header field for content length
18
19
20 class UpdateDelegate(object):
21 def BundleDirectoryExists(self, bundle_name):
22 raise NotImplementedError()
23
24 def DownloadToFile(self, url, dest_filename):
25 raise NotImplementedError()
26
27 def ExtractArchive(self, archive, extract_dir, repath_dir):
28 raise NotImplementedError()
29
30
31 class RealUpdateDelegate(UpdateDelegate):
32 def __init__(self, user_data_dir, install_dir):
33 UpdateDelegate.__init__(self)
34 self.user_data_dir = user_data_dir
35 self.install_dir = install_dir
36
37 def BundleDirectoryExists(self, bundle_name):
38 bundle_path = os.path.join(self.install_dir, bundle_name)
39 return os.path.isdir(bundle_path)
40
41 def DownloadToFile(self, url, dest_filename):
42 sdk_update_common.MakeDirs(self.user_data_dir)
43 dest_path = os.path.join(self.user_data_dir, dest_filename)
44 out_stream = None
45 url_stream = None
46 try:
47 out_stream = open(dest_path, 'w')
48 url_stream = download.UrlOpen(url)
49 content_length = int(url_stream.info()[HTTP_CONTENT_LENGTH])
50 progress = download.MakeProgressFunction(content_length)
51 sha1, size = download.DownloadAndComputeHash(url_stream, out_stream,
52 progress)
53 return sha1, size
54 except urllib2.URLError as e:
55 raise Error('Unable to read from URL "%s".\n %s' % (url, e))
56 except IOError as e:
57 raise Error('Unable to write to file "%s".\n %s' % (dest_filename, e))
58 finally:
59 if url_stream:
60 url_stream.close()
61 if out_stream:
62 out_stream.close()
63
64 def ExtractArchive(self, archive, extract_dir, repath_dir):
65 tar_file = None
66 archive_path = os.path.join(self.user_data_dir, archive)
67 extract_path = os.path.join(self.install_dir, extract_dir)
68 repath_path = os.path.join(self.install_dir, repath_dir)
69
70 # Extract to extract_dir, usually "<bundle name>_update".
71 # This way if the extraction fails, we haven't blown away the old bundle
72 # (if it exists).
73 sdk_update_common.RemoveDir(extract_path)
74 sdk_update_common.MakeDirs(extract_path)
75 curpath = os.getcwd()
76 try:
77 try:
78 tar_file = cygtar.CygTar(archive_path, 'r', verbose=True)
79 except Exception as e:
80 raise Error('Can\'t open archive "%s".\n %s' % (archive_path, e))
81
82 try:
83 os.chdir(extract_path)
84 except Exception as e:
85 raise Error('Unable to chdir into "%s".\n %s' % (extract_path, e))
86
87 tar_file.Extract()
88 finally:
89 if tar_file:
90 tar_file.Close()
91 os.chdir(curpath)
92
93 # Rename from the update directory to its real name.
94 sdk_update_common.RenameDir(extract_path, repath_path)
95
96 # Remove the archive.
97 os.remove(archive_path)
98
99
100 def Update(delegate, remote_manifest, local_manifest, bundle_names, force):
101 valid_bundles = set([bundle.name for bundle in remote_manifest.GetBundles()])
102 requested_bundles = _GetRequestedBundlesFromArgs(remote_manifest,
103 bundle_names)
104 invalid_bundles = requested_bundles - valid_bundles
105 if invalid_bundles:
106 logging.warn('Ignoring unknown bundle(s): %s' % (
107 ', '.join(invalid_bundles)))
108 requested_bundles -= invalid_bundles
109
110 if SDK_TOOLS in requested_bundles:
111 logging.warn('Updating sdk_tools happens automatically. '
112 'Ignoring manual update request.')
113 requested_bundles.discard(SDK_TOOLS)
114
115 if requested_bundles:
116 for bundle_name in requested_bundles:
117 logging.info('Trying to update %s' % (bundle_name,))
118 UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
119 bundle_name, force)
120 else:
121 logging.warn('No bundles to update.')
122
123
124 def UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
125 bundle_name, force):
126 bundle = remote_manifest.GetBundle(bundle_name)
127 if _BundleNeedsUpdate(delegate, local_manifest, bundle):
128 _UpdateBundle(delegate, bundle, local_manifest, force)
129 else:
130 print '%s is already up-to-date.' % (bundle.name,)
131
132
133 def _GetRequestedBundlesFromArgs(remote_manifest, requested_bundles):
134 requested_bundles = set(requested_bundles)
135 if RECOMMENDED in requested_bundles:
136 requested_bundles.discard(RECOMMENDED)
137 requested_bundles |= set(_GetRecommendedBundles(remote_manifest))
138
139 return requested_bundles
140
141
142 def _GetRecommendedBundles(remote_manifest):
143 return [bundle for bundle in remote_manifest.GetBundles() if
144 bundle.recommended]
145
146
147 def _BundleNeedsUpdate(delegate, local_manifest, bundle):
148 # Always update the bundle if the directory doesn't exist;
149 # the user may have deleted it.
150 if not delegate.BundleDirectoryExists(bundle.name):
151 return True
152
153 return local_manifest.BundleNeedsUpdate(bundle)
154
155
156 def _UpdateBundle(delegate, bundle, local_manifest, force):
157 archive = bundle.GetHostOSArchive()
158 if not archive:
159 logging.warn('Bundle %s does not exist for this platform.' % (bundle.name,))
160 return
161
162 logging.info('Downloading bundle %s' % (bundle.name,))
163 dest_filename = _GetFilenameFromURL(archive.url)
164 sha1, size = delegate.DownloadToFile(archive.url, dest_filename)
165 _ValidateArchive(archive, sha1, size)
166
167 logging.info('Updating bundle %s to version %s, revision %s' % (
168 bundle.name, bundle.version, bundle.revision))
169 extract_dir = bundle.name + '_update'
170 repath_dir = bundle.get('repath', bundle.name)
171 delegate.ExtractArchive(dest_filename, extract_dir, repath_dir)
172
173 logging.info('Updating local manifest to include bundle %s' % (bundle.name))
174 local_manifest.MergeBundle(bundle)
175
176
177 def _GetFilenameFromURL(url):
178 _, _, path, _, _, _ = urlparse.urlparse(url)
179 return path.split('/')[-1]
180
181
182 def _ValidateArchive(archive, actual_sha1, actual_size):
183 if actual_sha1 != archive.GetChecksum():
184 raise Error('SHA1 checksum mismatch on "%s". Expected %s but got %s' % (
185 archive.name, archive.GetChecksum(), actual_sha1))
186 if actual_size != archive.size:
187 raise Error('Size mismatch on "%s". Expected %s but got %s bytes' % (
188 archive.name, archive.size, actual_size))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698