Example #1
0
 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))
Example #2
0
    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))
Example #3
0
 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)
Example #4
0
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))
Example #5
0
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))
Example #6
0
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))
Example #7
0
 def semanticSpec(self):
     return self.semantic_spec or version.Spec('*')
Example #8
0
    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)
Example #9
0
 def __init__(self, url, version_spec=''):
     self.url = url
     self.spec = version.Spec(version_spec)