def __init__( self, path, description_filename, installed_linked, schema_filename = None, latest_suitable_version = None, inherit_shrinkwrap = None ): # resolve links at creation time, to minimise path lengths: self.unresolved_path = path self.path = fsutils.realpath(path) self.installed_linked = installed_linked self.vcs = None self.error = None self.latest_suitable_version = latest_suitable_version self.version = None self.description_filename = description_filename self.ignore_list_fname = Ignore_List_Fname self.ignore_patterns = copy.copy(Default_Publish_Ignore) self.origin_info = None description_file = os.path.join(path, description_filename) if os.path.isfile(description_file): try: self.description = ordered_json.load(description_file) if self.description: if not 'name' in self.description: raise Exception('missing "name"') if 'version' in self.description: self.version = version.Version(self.description['version']) else: raise Exception('missing "version"') except Exception as e: self.description = OrderedDict() self.error = "Description invalid %s: %s" % (description_file, e); logger.debug(self.error) raise InvalidDescription(self.error) else: self.error = "No %s file." % description_filename self.description = OrderedDict() try: with open(os.path.join(path, self.ignore_list_fname), 'r') as ignorefile: self.ignore_patterns += self._parseIgnoreFile(ignorefile) except IOError as e: if e.errno != errno.ENOENT: raise if self.description and schema_filename and not self.path in self.schema_errors_displayed: self.schema_errors_displayed.add(self.path) have_errors = False with open(schema_filename, 'r') as schema_file: schema = json.load(schema_file) validator = jsonschema.Draft4Validator(schema) for error in validator.iter_errors(self.description): if not have_errors: logger.warning(u'%s has invalid %s:' % ( os.path.split(self.path.rstrip('/'))[1], description_filename )) have_errors = True logger.warning(u" %s value %s" % (u'.'.join([str(x) for x in error.path]), error.message)) # for now schema validation errors aren't fatal... will be soon # though! #if have_errors: # raise InvalidDescription('Invalid %s' % description_filename) self.inherited_shrinkwrap = None self.shrinkwrap = None # we can only apply shrinkwraps to instances with valid descriptions: # instances do not become valid after being invalid so this is safe # (but it means you cannot trust the shrinkwrap of an invalid # component) # (note that it is unsafe to use the __bool__ operator on self here as # we are not fully constructed) if self.description: if inherit_shrinkwrap is not None: # when inheriting a shrinkwrap, check that this module is # listed in the shrinkwrap, otherwise emit a warning: if next((x for x in inherit_shrinkwrap.get('modules', []) if x['name'] == self.getName()), None) is None: logger.warning("%s missing from shrinkwrap", self.getName()) self.inherited_shrinkwrap = inherit_shrinkwrap self.shrinkwrap = tryReadJSON(os.path.join(path, Shrinkwrap_Fname), Shrinkwrap_Schema) if self.shrinkwrap: logger.warning('dependencies of %s are pegged by yotta-shrinkwrap.json', self.getName()) if self.inherited_shrinkwrap: logger.warning('shrinkwrap in %s overrides inherited shrinkwrap', self.getName()) #logger.info('%s created with inherited_shrinkwrap %s', self.getName(), self.inherited_shrinkwrap) self.vcs = vcs.getVCS(path)
def __init__( self, path, description_filename, installed_linked, schema_filename = None, latest_suitable_version = None ): # resolve links at creation time, to minimise path lengths: self.unresolved_path = path self.path = fsutils.realpath(path) self.installed_linked = installed_linked self.vcs = None self.error = None self.latest_suitable_version = latest_suitable_version self.version = None self.description_filename = description_filename self.ignore_list_fname = Ignore_List_Fname self.ignore_patterns = copy.copy(Default_Publish_Ignore) self.origin_info = None description_file = os.path.join(path, description_filename) if os.path.isfile(description_file): try: self.description = ordered_json.load(description_file) if self.description: if not 'name' in self.description: raise Exception('missing "name"') if 'version' in self.description: self.version = version.Version(self.description['version']) else: raise Exception('missing "version"') except Exception as e: self.description = OrderedDict() self.error = "Description invalid %s: %s" % (description_file, e); logger.debug(self.error) raise InvalidDescription(self.error) else: self.error = "No %s file." % description_filename self.description = OrderedDict() try: with open(os.path.join(path, self.ignore_list_fname), 'r') as ignorefile: self.ignore_patterns += self._parseIgnoreFile(ignorefile) except IOError as e: if e.errno != errno.ENOENT: raise if self.description and schema_filename and not self.path in self.schema_errors_displayed: self.schema_errors_displayed.add(self.path) have_errors = False with open(schema_filename, 'r') as schema_file: schema = json.load(schema_file) validator = jsonschema.Draft4Validator(schema) for error in validator.iter_errors(self.description): if not have_errors: logger.warning(u'%s has invalid %s:' % ( os.path.split(self.path.rstrip('/'))[1], description_filename )) have_errors = True logger.warning(u" %s value %s" % (u'.'.join([str(x) for x in error.path]), error.message)) # for now schema validation errors aren't fatal... will be soon # though! #if have_errors: # raise InvalidDescription('Invalid %s' % description_filename) self.vcs = vcs.getVCS(path)