Index: native_client_sdk/src/build_tools/manifest_util.py |
diff --git a/native_client_sdk/src/build_tools/manifest_util.py b/native_client_sdk/src/build_tools/manifest_util.py |
index 4a479d8f510aadafbae5eb021fba7ef3fa70fb04..1e055d71c22a244bd772a0cca2fa0fa1d497d6f9 100644 |
--- a/native_client_sdk/src/build_tools/manifest_util.py |
+++ b/native_client_sdk/src/build_tools/manifest_util.py |
@@ -5,7 +5,9 @@ |
import copy |
import hashlib |
import json |
+import string |
import sys |
+import urllib2 |
MANIFEST_VERSION = 2 |
@@ -57,8 +59,8 @@ def DictToJSON(pydict): |
def DownloadAndComputeHash(from_stream, to_stream=None, progress_func=None): |
- ''' Download the archive data from from-stream and generate sha1 and |
- size info. |
+ '''Download the archive data from from-stream and generate sha1 and |
+ size info. |
Args: |
from_stream: An input stream that supports read. |
@@ -146,6 +148,20 @@ class Archive(dict): |
if key not in VALID_ARCHIVE_KEYS: |
raise Error('Archive "%s" has invalid attribute "%s"' % (host_os, key)) |
+ def UpdateVitals(self, revision): |
+ """Update the size and checksum information for this archive |
+ based on the content currently at the URL. |
+ |
+ This allows the template mandifest to be maintained without |
+ the need to size and checksums to be present. |
+ """ |
+ template = string.Template(self['url']) |
+ self['url'] = template.substitute({'revision': revision}) |
+ from_stream = urllib2.urlopen(self['url']) |
+ sha1_hash, size = DownloadAndComputeHash(from_stream) |
+ self['size'] = size |
+ self['checksum'] = { 'sha1': sha1_hash } |
+ |
def __getattr__(self, name): |
"""Retrieve values from this dict using attributes. |
@@ -215,6 +231,9 @@ class Bundle(dict): |
else: |
self[k] = v |
+ def __str__(self): |
+ return self.GetDataAsString() |
+ |
def GetDataAsString(self): |
"""Returns the JSON bundle object, pretty-printed""" |
return DictToJSON(self) |
@@ -245,21 +264,21 @@ class Bundle(dict): |
else: |
self[key] = value |
- def Validate(self): |
+ def Validate(self, add_missing_info=False): |
"""Validate the content of the bundle. Raise an Error if an invalid or |
missing field is found. """ |
# Check required fields. |
- if not self.get(NAME_KEY, None): |
+ if not self.get(NAME_KEY): |
raise Error('Bundle has no name') |
- if self.get(REVISION_KEY, None) == None: |
+ if self.get(REVISION_KEY) == None: |
raise Error('Bundle "%s" is missing a revision number' % self[NAME_KEY]) |
- if self.get(VERSION_KEY, None) == None: |
+ if self.get(VERSION_KEY) == None: |
raise Error('Bundle "%s" is missing a version number' % self[NAME_KEY]) |
- if not self.get('description', None): |
+ if not self.get('description'): |
raise Error('Bundle "%s" is missing a description' % self[NAME_KEY]) |
- if not self.get('stability', None): |
+ if not self.get('stability'): |
raise Error('Bundle "%s" is missing stability info' % self[NAME_KEY]) |
- if self.get('recommended', None) == None: |
+ if self.get('recommended') == None: |
raise Error('Bundle "%s" is missing the recommended field' % |
self[NAME_KEY]) |
# Check specific values |
@@ -277,6 +296,8 @@ class Bundle(dict): |
(self[NAME_KEY], key)) |
# Validate the archives |
for archive in self[ARCHIVES_KEY]: |
+ if add_missing_info and 'size' not in archive: |
+ archive.UpdateVitals(self[REVISION_KEY]) |
archive.Validate() |
def GetArchive(self, host_os_name): |
@@ -387,7 +408,7 @@ class SDKManifest(object): |
"bundles": [], |
} |
- def Validate(self): |
+ def Validate(self, add_missing_info=False): |
"""Validate the Manifest file and raises an exception for problems""" |
# Validate the manifest top level |
if self._manifest_data["manifest_version"] > MANIFEST_VERSION: |
@@ -399,7 +420,7 @@ class SDKManifest(object): |
raise Error('Manifest has invalid attribute "%s"' % key) |
# Validate each bundle |
for bundle in self._manifest_data[BUNDLES_KEY]: |
- bundle.Validate() |
+ bundle.Validate(add_missing_info) |
def GetBundle(self, name): |
"""Get a bundle from the array of bundles. |
@@ -457,7 +478,7 @@ class SDKManifest(object): |
(local_bundle[VERSION_KEY], local_bundle[REVISION_KEY]) < |
(bundle[VERSION_KEY], bundle[REVISION_KEY])) |
- def MergeBundle(self, bundle, allow_existing = True): |
+ def MergeBundle(self, bundle, allow_existing=True): |
"""Merge a Bundle into this manifest. |
The new bundle is added if not present, or merged into the existing bundle. |
@@ -483,7 +504,7 @@ class SDKManifest(object): |
manifest: The manifest to merge. |
''' |
for bundle in manifest.GetBundles(): |
- self.MergeBundle(bundle, allow_existing = False) |
+ self.MergeBundle(bundle, allow_existing=False) |
def FilterBundles(self, predicate): |
"""Filter the list of bundles by |predicate|. |
@@ -497,7 +518,7 @@ class SDKManifest(object): |
""" |
self._manifest_data[BUNDLES_KEY] = filter(predicate, self.GetBundles()) |
- def LoadDataFromString(self, json_string): |
+ def LoadDataFromString(self, json_string, add_missing_info=False): |
"""Load a JSON manifest string. Raises an exception if json_string |
is not well-formed JSON. |
@@ -517,7 +538,10 @@ class SDKManifest(object): |
self._manifest_data[key] = bundles |
else: |
self._manifest_data[key] = value |
- self.Validate() |
+ self.Validate(add_missing_info) |
+ |
+ def __str__(self): |
+ return self.GetDataAsString() |
def GetDataAsString(self): |
"""Returns the current JSON manifest object, pretty-printed""" |