def __init__( self, path, description_filename, installed_linked, schema_filename = None, latest_suitable_version = None ): self.path = 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) 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() logger.debug(self.error) raise InvalidDescription("Description invalid %s: %s" % (description_file, e)) 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)
def loadAdditionalConfig(config_path): ''' returns (error, config) ''' error = None config = {} if not config_path: return (error, config) if os.path.isfile(config_path): try: config = ordered_json.load(config_path) except Exception as e: error = "Invalid syntax in file %s: %s" % (config_path, e) else: # try to interpret the argument as literal JSON try: config = ordered_json.loads(config_path) except Exception as e: # if this fails too, guess whether it was intended to be JSON or # not, and display an appropriate error message if '{' in config_path or '}' in config_path: error = "Invalid syntax in literal JSON: %s" % e else: error = "File \"%s\" does not exist" % config_path logger.debug('read additional config: %s', config) return (error, config)
def read(self, filenames): '''' Read a list of files. Their configuration values are merged, with preference to values from files earlier in the list. ''' for fn in filenames: try: self.configs[fn] = ordered_json.load(fn) except IOError: self.configs[fn] = OrderedDict()
def origin(self): ''' Read the .yotta_origin.json file (if present), and return the value of the 'url' property ''' if self.origin_info is None: self.origin_info = {} try: self.origin_info = ordered_json.load(os.path.join(self.path, Origin_Info_Fname)) except IOError: pass return self.origin_info.get('url', None)
def __init__(self, path, description_filename, installed_linked, schema_filename=None, latest_suitable_version=None): self.path = 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) try: self.description = ordered_json.load( os.path.join(path, description_filename)) if self.description: if not 'name' in self.description: raise Exception('missing "name" in module.json') if 'version' in self.description: self.version = version.Version(self.description['version']) else: raise Exception('missing "version" in module.json') except Exception as e: self.description = OrderedDict() self.error = e 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 Exception('Invalid %s' % description_filename) self.vcs = vcs.getVCS(path)
def __init__(self, path, description_filename, installed_linked, latest_suitable_version=None): self.path = 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 try: self.description = ordered_json.load(os.path.join(path, description_filename)) self.version = version.Version(self.description['version']) except Exception, e: self.description = OrderedDict() self.error = e
def tryReadJSON(filename, schemaname): r = None try: with open(filename, 'r') as jsonfile: r = ordered_json.load(filename) have_errors = False if schemaname is not None: with open(schemaname, 'r') as schema_file: schema = json.load(schema_file) validator = jsonschema.Draft4Validator(schema) for error in validator.iter_errors(r): logger.error( '%s is not valid under the schema: %s value %s', filename, u'.'.join([str(x) for x in error.path]), error.message ) except IOError as e: if e.errno != errno.ENOENT: raise return r
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 getDerivedTarget( target_name_and_version, targets_path, application_dir = None, install_missing = True, update_installed = False ): ''' Get the specified target description, optionally ensuring that it (and all dependencies) are installed in targets_path. Returns (DerivedTarget, errors), or (None, errors) if the leaf target could not be found/installed. ''' logger.debug('satisfy target: %s' % target_name_and_version); if ',' in target_name_and_version: name, ver = target_name_and_version.split(',') dspec = pack.DependencySpec(name, ver) else: dspec = pack.DependencySpec(target_name_and_version, "*") leaf_target = None previous_name = dspec.name search_dirs = [targets_path] target_hierarchy = [] errors = [] while True: t = None try: if install_missing: t = access.satisfyVersion( name = dspec.name, version_required = dspec.version_req, available = target_hierarchy, search_paths = search_dirs, working_directory = targets_path, update_installed = ('Update' if update_installed else None), type = 'target' ) else: t = access.satisfyVersionFromSearchPaths( name = dspec.name, version_required = dspec.version_req, search_paths = search_dirs, type = 'target' ) except access_common.Unavailable as e: errors.append(e) if not t: if install_missing: logger.error( 'could not install target %s for %s' % (dspec, previous_name) ) break else: target_hierarchy.append(t) previous_name = dspec.name assert(isinstance(t, Target)) dspec = t.baseTargetSpec() #pylint: disable=no-member if not leaf_target: leaf_target = t if dspec is None: break if leaf_target is None: return (None, errors) # if we have a valid target, try to load the app-specific config data (if # any): app_config = {} if application_dir is not None: app_config_fname = os.path.join(application_dir, App_Config_File) if os.path.exists(app_config_fname): try: app_config = ordered_json.load(app_config_fname) except Exception as e: errors.append(Exception("Invalid application config.json: %s" % (e))) return (DerivedTarget(leaf_target, target_hierarchy[1:], app_config), errors)
def getDerivedTarget(target_name_and_version, targets_path, application_dir=None, install_missing=True, update_installed=False): ''' Get the specified target description, optionally ensuring that it (and all dependencies) are installed in targets_path. Returns (DerivedTarget, errors), or (None, errors) if the leaf target could not be found/installed. ''' logger.debug('satisfy target: %s' % target_name_and_version) if ',' in target_name_and_version: name, ver = target_name_and_version.split(',') dspec = pack.DependencySpec(name, ver) else: dspec = pack.DependencySpec(target_name_and_version, "*") leaf_target = None previous_name = dspec.name search_dirs = [targets_path] target_hierarchy = [] errors = [] while True: t = None try: if install_missing: t = access.satisfyVersion( name=dspec.name, version_required=dspec.version_req, available=target_hierarchy, search_paths=search_dirs, working_directory=targets_path, update_installed=('Update' if update_installed else None), type='target') else: t = access.satisfyVersionFromSearchPaths( name=dspec.name, version_required=dspec.version_req, search_paths=search_dirs, type='target') except access_common.Unavailable as e: errors.append(e) if not t: if install_missing: logger.error('could not install target %s for %s' % (dspec, previous_name)) break else: target_hierarchy.append(t) previous_name = dspec.name assert (isinstance(t, Target)) dspec = t.baseTargetSpec() #pylint: disable=no-member if not leaf_target: leaf_target = t if dspec is None: break if leaf_target is None: return (None, errors) # if we have a valid target, try to load the app-specific config data (if # any): app_config = {} if application_dir is not None: app_config_fname = os.path.join(application_dir, App_Config_File) if os.path.exists(app_config_fname): try: app_config = ordered_json.load(app_config_fname) except Exception as e: errors.append( Exception("Invalid application config.json: %s" % (e))) return (DerivedTarget(leaf_target, target_hierarchy[1:], app_config), errors)