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

Unified Diff: native_client_sdk/src/build_tools/sdk_tools/command/update.py

Issue 11228013: [NaCl SDK] Refactor sdk_update*. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix build_updater 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 side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/build_tools/sdk_tools/command/update.py
diff --git a/native_client_sdk/src/build_tools/sdk_tools/command/update.py b/native_client_sdk/src/build_tools/sdk_tools/command/update.py
new file mode 100644
index 0000000000000000000000000000000000000000..24389c93737a61c2e656a92d4b4f0a3e78931bf3
--- /dev/null
+++ b/native_client_sdk/src/build_tools/sdk_tools/command/update.py
@@ -0,0 +1,238 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import download
+import logging
+import os
+from sdk_update_common import Error
+import sdk_update_common
+import sys
+import urlparse
+import urllib2
+
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+PARENT_DIR = os.path.dirname(SCRIPT_DIR)
+sys.path.append(PARENT_DIR)
+try:
+ import cygtar
+except ImportError:
+ # Try to find this in the Chromium repo.
+ CHROME_SRC_DIR = os.path.abspath(
+ os.path.join(PARENT_DIR, '..', '..', '..', '..'))
+ sys.path.append(os.path.join(CHROME_SRC_DIR, 'native_client', 'build'))
+ import cygtar
+
+
+RECOMMENDED = 'recommended'
+SDK_TOOLS = 'sdk_tools'
+HTTP_CONTENT_LENGTH = 'Content-Length' # HTTP Header field for content length
+
+
+class UpdateDelegate(object):
+ def BundleDirectoryExists(self, bundle_name):
+ raise NotImplementedError()
+
+ def DownloadToFile(self, url, dest_filename):
+ raise NotImplementedError()
+
+ def ExtractArchive(self, archive, extract_dir, rename_from_dir,
+ rename_to_dir):
+ raise NotImplementedError()
+
+
+class RealUpdateDelegate(UpdateDelegate):
+ def __init__(self, user_data_dir, install_dir):
+ UpdateDelegate.__init__(self)
+ self.user_data_dir = user_data_dir
+ self.install_dir = install_dir
+
+ def BundleDirectoryExists(self, bundle_name):
+ bundle_path = os.path.join(self.install_dir, bundle_name)
+ return os.path.isdir(bundle_path)
+
+ def DownloadToFile(self, url, dest_filename):
+ sdk_update_common.MakeDirs(self.user_data_dir)
+ dest_path = os.path.join(self.user_data_dir, dest_filename)
+ out_stream = None
+ url_stream = None
+ try:
+ out_stream = open(dest_path, 'wb')
+ url_stream = download.UrlOpen(url)
+ content_length = int(url_stream.info()[HTTP_CONTENT_LENGTH])
+ progress = download.MakeProgressFunction(content_length)
+ sha1, size = download.DownloadAndComputeHash(url_stream, out_stream,
+ progress)
+ return sha1, size
+ except urllib2.URLError as e:
+ raise Error('Unable to read from URL "%s".\n %s' % (url, e))
+ except IOError as e:
+ raise Error('Unable to write to file "%s".\n %s' % (dest_filename, e))
+ finally:
+ if url_stream:
+ url_stream.close()
+ if out_stream:
+ out_stream.close()
+
+ def ExtractArchive(self, archive, extract_dir, rename_from_dir,
+ rename_to_dir):
+ tar_file = None
+
+ archive_path = os.path.join(self.user_data_dir, archive)
+ extract_path = os.path.join(self.install_dir, extract_dir)
+ rename_from_path = os.path.join(self.install_dir, rename_from_dir)
+ rename_to_path = os.path.join(self.install_dir, rename_to_dir)
+
+ # Extract to extract_dir, usually "<bundle name>_update".
+ # This way if the extraction fails, we haven't blown away the old bundle
+ # (if it exists).
+ sdk_update_common.RemoveDir(extract_path)
+ sdk_update_common.MakeDirs(extract_path)
+ curpath = os.getcwd()
+ tar_file = None
+
+ try:
+ try:
+ tar_file = cygtar.CygTar(archive_path, 'r', verbose=True)
+ except Exception as e:
+ raise Error('Can\'t open archive "%s".\n %s' % (archive_path, e))
+
+ try:
+ logging.info('Changing the directory to %s' % (extract_path,))
+ os.chdir(extract_path)
+ except Exception as e:
+ raise Error('Unable to chdir into "%s".\n %s' % (extract_path, e))
+
+ logging.info('Extracting to %s' % (extract_path,))
+ tar_file.Extract()
+
+ logging.info('Changing the directory to %s' % (curpath,))
+ os.chdir(curpath)
+
+ logging.info('Renaming %s->%s' % (rename_from_path, rename_to_path))
+ sdk_update_common.RenameDir(rename_from_path, rename_to_path)
+ finally:
+ # Change the directory back so we can remove the update directory.
+ os.chdir(curpath)
+
+ # Clean up the ..._update directory.
+ try:
+ sdk_update_common.RemoveDir(extract_path)
+ except Exception as e:
+ logging.error('Failed to remove directory \"%s\". %s' % (
+ extract_path, e))
+
+ if tar_file:
+ tar_file.Close()
+
+ # Remove the archive.
+ os.remove(archive_path)
+
+
+def Update(delegate, remote_manifest, local_manifest, bundle_names, force):
+ valid_bundles = set([bundle.name for bundle in remote_manifest.GetBundles()])
+ requested_bundles = _GetRequestedBundlesFromArgs(remote_manifest,
+ bundle_names)
+ invalid_bundles = requested_bundles - valid_bundles
+ if invalid_bundles:
+ logging.warn('Ignoring unknown bundle(s): %s' % (
+ ', '.join(invalid_bundles)))
+ requested_bundles -= invalid_bundles
+
+ if SDK_TOOLS in requested_bundles:
+ logging.warn('Updating sdk_tools happens automatically. '
+ 'Ignoring manual update request.')
+ requested_bundles.discard(SDK_TOOLS)
+
+ if requested_bundles:
+ for bundle_name in requested_bundles:
+ logging.info('Trying to update %s' % (bundle_name,))
+ UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
+ bundle_name, force)
+ else:
+ logging.warn('No bundles to update.')
+
+
+def UpdateBundleIfNeeded(delegate, remote_manifest, local_manifest,
+ bundle_name, force):
+ bundle = remote_manifest.GetBundle(bundle_name)
+ if bundle:
+ if _BundleNeedsUpdate(delegate, local_manifest, bundle):
+ _UpdateBundle(delegate, bundle, local_manifest, force)
+ else:
+ print '%s is already up-to-date.' % (bundle.name,)
+ else:
+ logging.error('Bundle %s does not exist.' % (bundle_name,))
+
+
+def _GetRequestedBundlesFromArgs(remote_manifest, requested_bundles):
+ requested_bundles = set(requested_bundles)
+ if RECOMMENDED in requested_bundles:
+ requested_bundles.discard(RECOMMENDED)
+ requested_bundles |= set(_GetRecommendedBundles(remote_manifest))
+
+ return requested_bundles
+
+
+def _GetRecommendedBundles(remote_manifest):
+ return [bundle for bundle in remote_manifest.GetBundles() if
+ bundle.recommended]
+
+
+def _BundleNeedsUpdate(delegate, local_manifest, bundle):
+ # Always update the bundle if the directory doesn't exist;
+ # the user may have deleted it.
+ if not delegate.BundleDirectoryExists(bundle.name):
+ return True
+
+ return local_manifest.BundleNeedsUpdate(bundle)
+
+
+def _UpdateBundle(delegate, bundle, local_manifest, force):
+ archive = bundle.GetHostOSArchive()
+ if not archive:
+ logging.warn('Bundle %s does not exist for this platform.' % (bundle.name,))
+ return
+
+ print 'Downloading bundle %s' % (bundle.name,)
+ dest_filename = _GetFilenameFromURL(archive.url)
+ sha1, size = delegate.DownloadToFile(archive.url, dest_filename)
+ _ValidateArchive(archive, sha1, size)
+
+ print 'Updating bundle %s to version %s, revision %s' % (
+ bundle.name, bundle.version, bundle.revision)
+ extract_dir = bundle.name + '_update'
+
+ repath_dir = bundle.get('repath', None)
+ if repath_dir:
+ # If repath is specified:
+ # The files are extracted to nacl_sdk/<bundle.name>_update/<repath>/...
+ # The destination directory is nacl_sdk/<repath>/...
+ rename_from_dir = os.path.join(extract_dir, repath_dir)
+ rename_to_dir = repath_dir
+ else:
+ # If no repath is specified:
+ # The files are extracted to nacl_sdk/<bundle.name>_update/...
+ # The destination directory is nacl_sdk/<bundle.name>/...
+ rename_from_dir = extract_dir
+ rename_to_dir = bundle.name
+
+ delegate.ExtractArchive(dest_filename, extract_dir, rename_from_dir,
+ rename_to_dir)
+
+ logging.info('Updating local manifest to include bundle %s' % (bundle.name))
+ local_manifest.MergeBundle(bundle)
+
+
+def _GetFilenameFromURL(url):
+ _, _, path, _, _, _ = urlparse.urlparse(url)
+ return path.split('/')[-1]
+
+
+def _ValidateArchive(archive, actual_sha1, actual_size):
+ if actual_sha1 != archive.GetChecksum():
+ raise Error('SHA1 checksum mismatch on "%s". Expected %s but got %s' % (
+ archive.name, archive.GetChecksum(), actual_sha1))
+ if actual_size != archive.size:
+ raise Error('Size mismatch on "%s". Expected %s but got %s bytes' % (
+ archive.name, archive.size, actual_size))
« no previous file with comments | « native_client_sdk/src/build_tools/sdk_tools/command/sources.py ('k') | native_client_sdk/src/build_tools/sdk_tools/config.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698