def test_hash(self): sets = [ ['0.1.1', '==0.1.1', '=0.1.1'], ['', '*'], ] for s in [set([version.Spec(x) for x in l]) for l in sets]: self.assertEqual(1, len(s))
def test_matches(self): for spec, (matching, failing) in self.matches.items(): spec = version.Spec(spec) for v in [version.Version(v) for v in matching]: self.assertTrue(v in spec, "%r should be in %r" % (v, spec)) self.assertTrue(spec.match(v), "%r should match %r" % (v, spec)) for v in [version.Version(v) for v in failing]: self.assertFalse(v in spec, "%r should not be in %r" % (v, spec)) self.assertFalse(spec.match(v), "%r should not match %r" % (v, spec))
def __init__(self, source_type, location, spec): assert (source_type in ('registry', 'github', 'git', 'hg')) self.source_type = source_type self.location = location self.spec = spec try: self.semantic_spec = version.Spec(spec) except ValueError: # for git/github source URLs the spec is allowed to be a branch # name or tag name, as well as a valid semantic version # specification # !!! TODO: also allow hg here if source_type in ('git', 'github'): self.semantic_spec = None else: raise ValueError("Invalid semantic version spec: \"%s\"" % spec)
def parseSourceURL(source_url): ''' Parse the specified version source URL (or version spec), and return an instance of VersionSource ''' parsed = urlsplit(source_url) if '#' in source_url: without_fragment = source_url[:source_url.index('#')] else: without_fragment = source_url try: url_is_spec = version.Spec(source_url) except ValueError: url_is_spec = None if url_is_spec is not None: # if the url is an unadorned version specification (including an empty # string) then the source is the module registry: return VersionSource('registry', '', source_url) elif parsed.netloc.endswith('github.com'): # any URL onto github should be fetched over the github API, even if it # would parse as a valid git URL return VersionSource('github', parsed.path, parsed.fragment) elif parsed.scheme.startswith('git+') or parsed.path.endswith('.git'): # git+anything://anything or anything.git is a git repo: return VersionSource('git', without_fragment, parsed.fragment) elif parsed.scheme.startswith('hg+') or parsed.path.endswith('.hg'): # hg+anything://anything or anything.hg is a hg repo: return VersionSource('hg', without_fragment, parsed.fragment) elif re.match('^[a-z0-9_-]+/[a-z0-9_-]+$', without_fragment, re.I): # something/something#spec = github return VersionSource('github', without_fragment, parsed.fragment) # something/something@spec = github alternate_github_match = re.match( '([a-z0-9_-]+/[a-z0-9_-]+) *@?([~^><=.0-9a-z\*-]*)', source_url, re.I) if alternate_github_match: return VersionSource('github', alternate_github_match.group(0), alternate_github_match.group(1)) raise ValueError("Invalid version source url: \"%s\"" % (source_url))
def parseSourceURL(source_url): ''' Parse the specified version source URL (or version spec), and return an instance of VersionSource ''' name, spec = _getNonRegistryRef(source_url) if spec: return spec try: url_is_spec = version.Spec(source_url) except ValueError: url_is_spec = None if url_is_spec is not None: # if the url is an unadorned version specification (including an empty # string) then the source is the module registry: return VersionSource('registry', '', source_url) raise InvalidVersionSpec("Invalid version specification: \"%s\"" % (source_url))
def parseSourceURL(source_url): ''' Parse the specified version source URL (or version spec), and return an instance of VersionSource ''' import re parsed = urlsplit(source_url) if '#' in source_url: without_fragment = source_url[:source_url.index('#')] else: without_fragment = source_url try: url_is_spec = version.Spec(source_url) except ValueError: url_is_spec = None if url_is_spec is not None: # if the url is an unadorned version specification (including an empty # string) then the source is the module registry: return VersionSource('registry', '', source_url) elif parsed.netloc.endswith('github.com'): # any URL onto github should be fetched over the github API, even if it # would parse as a valid git URL return VersionSource('github', parsed.path, parsed.fragment) elif parsed.scheme.startswith('git+') or parsed.path.endswith('.git'): # git+anything://anything or anything.git is a git repo: return VersionSource('git', without_fragment, parsed.fragment) elif parsed.scheme.startswith('hg+') or parsed.path.endswith('.hg'): # hg+anything://anything or anything.hg is a hg repo: return VersionSource('hg', without_fragment, parsed.fragment) # something/something@spec = github # something/something#spec = github module_name, github_match = _getGithubRef(source_url) if github_match: return github_match raise InvalidVersionSpec("Invalid version specification: \"%s\"" % (source_url))
def semanticSpec(self): return self.semantic_spec or version.Spec('*')
def __init__(self, path, description_filename, installed_linked, schema_filename=None, latest_suitable_version=None, inherit_shrinkwrap=None): # version, , represent versions and specifications, internal from yotta.lib import version # vcs, , represent version controlled directories, internal from yotta.lib import vcs # 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 # warn about invalid yotta versions before schema errors (as new yotta # might introduce new schema) yotta_version_spec = None if self.description and self.description.get('yotta', None): try: yotta_version_spec = version.Spec(self.description['yotta']) except ValueError as e: logger.warning( "could not parse yotta version spec '%s' from %s: it " + "might require a newer version of yotta", self.description['yotta'], self.description['name']) if yotta_version_spec is not None: import yotta yotta_version = version.Version(yotta.__version__) if not yotta_version_spec.match(yotta_version): self.error = "requires yotta version %s (current version is %s). see http://yottadocs.mbed.com for update instructions" % ( str(yotta_version_spec), str(yotta_version)) 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, url, version_spec=''): self.url = url self.spec = version.Spec(version_spec)