예제 #1
0
    def _validate_markdown(self, ymlfile):
        '''ensure that fields are present in markdown file'''

        try:
            import yaml
        except:
            bot.error(
                'Python yaml is required for testing yml/markdown files.')
            sys.exit(1)

        uid = os.path.basename(ymlfile).strip('.md')

        if os.path.exists(ymlfile):

            self.metadata = read_yaml(ymlfile)

            # Required fields for library
            fields = [
                'github', 'docker', 'web', 'name', 'tags', 'uid', 'maintainer'
            ]

            # Tests for all fields
            for field in fields:
                if field not in self.metadata:
                    print('%s is missing field %s.' % (uid, field))
                    return False
                if self.metadata[field] in ['', None]:
                    return False

            # Uid in file must match filename
            if self.metadata['uid'] != uid:
                print('Mismatch in file %s.md and %s.' %
                      (ymlfile, self.metadata['uid']))
                return False

            # Ensure that urls are from Docker Hub and Github
            if 'github' not in self.metadata['github']:
                return notvalid('%s: not a valid github repository' % name)
            if 'hub.docker.com' not in self.metadata['docker']:
                return notvalid('%s: not a valid github repository' % name)

            # Tags must be in a list
            if not isinstance(self.metadata['tags'], list):
                return notvalid('%s: tags must be a list' % name)

            # Validate that links are correct urls
            for key in ['web', 'github', 'docker']:
                url = self.metadata[key]
                if not validate_url(url):
                    return notvalid('%s is not a valid URL.' % (url))

            # Validate name
            bot.test("        Name: %s" % self.metadata['name'])
            name = self.metadata['name'].replace('/', '-')  # okay to have /
            if not re.match("^[a-z0-9_-]*$", name):
                return notvalid('''invalid characters in %s, only 
                                   lowercase and "-" or "_" allowed.''' % name)

        return True
예제 #2
0
    def validate_url(self, url):

        bot.test('url: %s' % url)
        response = requests.get(url)

        if response.status_code == 404:
            bot.error('%s not found.' % url)
            return False
        return True
예제 #3
0
def clone(url, tmpdir=None, branch='master'):
    '''clone a repository from Github'''
    if tmpdir is None:
        tmpdir = tempfile.mkdtemp()
    name = os.path.basename(url).replace('.git', '')
    dest = '%s/%s-%s' % (tmpdir, name, branch)
    return_code = os.system('git clone -b %s %s %s' % (branch, url, dest))
    if return_code == 0:
        return dest
    bot.error('Error cloning repo.')
    sys.exit(return_code)
예제 #4
0
def mkdir_p(path):
    '''mkdir_p attempts to get the same functionality as mkdir -p
    :param path: the path to create.
    '''
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else:
            bot.error("Error creating path %s, exiting." % path)
            sys.exit(1)
예제 #5
0
    def validate(self, url):
        ''' takes in a Github repository for validation of preview and 
            runtime (and possibly tests passing?
        '''

        # Preview must provide the live URL of the repository
        if not url.startswith('http') or not 'github' in url:
            bot.error('Test of preview must be given a Github repostitory.')
            return False

        if not self._validate_preview(url):
            return False

        return True
예제 #6
0
def copy_directory(src, dest, force=False):
    ''' Copy an entire directory recursively
    '''
    if os.path.exists(dest) and force is True:
        shutil.rmtree(dest)

    try:
        shutil.copytree(src, dest)
    except OSError as e:
        # If the error was caused because the source wasn't a directory
        if e.errno == errno.ENOTDIR:
            shutil.copy(src, dest)
        else:
            bot.error('Directory not copied. Error: %s' % e)
            sys.exit(1)
예제 #7
0
def getenv(variable_key, default=None, required=False, silent=True):
    '''getenv will attempt to get an environment variable. If the variable
    is not found, None is returned.
    :param variable_key: the variable name
    :param required: exit with error if not found
    :param silent: Do not print debugging information for variable
    '''
    variable = os.environ.get(variable_key, default)
    if variable is None and required:
        bot.error("Cannot find environment variable %s, exiting." %
                  variable_key)
        sys.exit(1)

    if not silent:
        if variable is not None:
            bot.verbose2("%s found as %s" % (variable_key, variable))
        else:
            bot.verbose2("%s not defined (None)" % variable_key)

    return variable
예제 #8
0
    def _validate_preview(self, url, clean_up=True):

        bot.test('Container url: %s' % url)
        org, repo = url.split('/')[-2:]
        if repo.endswith('.git'):
            repo = repo.replace('.git', '')
        github_pages = "https://%s.github.io/%s" % (org, repo)

        # Save Github pages for comparison with record
        self.github_pages = github_pages

        bot.test('Github Pages url: %s' % github_pages)

        response = requests.get(github_pages)

        if response.status_code == 404:
            bot.error('''Preview not found at %s. You must publish a static 
                         preview from the gh-pages branch of your repository to
                         add to the library.''' % github_pages)
            return False

        index = response.text
        tmpdir = tempfile.mkdtemp()

        # Github Pages
        ghpages = clone(url, tmpdir, branch='gh-pages')
        contenders = glob('%s/*' % ghpages)

        # master
        master = clone(url, tmpdir, branch='master')

        license = False
        readme = False
        found = False
        tags = False
        valid = True

        # Required to have at least one latest
        manifest = False
        inspect = False

        # Testing Github Pages
        print('Testing Github Pages!')
        for test in contenders:
            print('   %s' % test)
            if os.path.basename(test) == "index.html":
                bot.test('Found index file in repository.')
                found = True
            if os.path.basename(test) == 'tags.json':
                bot.test('Found tags manifest in repository.')
                tags = True
            if os.path.basename(test) == 'manifest-latest.json':
                bot.test('Found latest manifest in repository.')
                manifest = True
            if os.path.basename(test) == 'inspect.json':
                bot.test('Found latest inspection in repository.')
                inspect = True

        contenders = glob('%s/*' % master)

        # Testing Main Repository
        print('Testing Main Repository master branch!')
        for test in contenders:
            print('   %s' % test)
            if "LICENSE" in os.path.basename(test):
                license = True
            if "README" in os.path.basename(test):
                readme = True

        # These are all required!
        if license is False:
            bot.warning("LICENSE file not found, please add a LICENSE")
            valid = False
        if readme is False:
            bot.warning("README file not found, please add a README")
            valid = False
        if tags is False:
            bot.warning("inspect-latest.json not found, required.")
            valid = False

        if manifest is False:
            bot.warning("manifest-latest.json not found, required")
            valid = False

        # Clean up, if desired
        if clean_up is True:
            shutil.rmtree(tmpdir)

        self._print_valid(valid)
        return valid