Skip to content
Snippets Groups Projects
repo.py 3.58 KiB
Newer Older
  • Learn to ignore specific revisions
  • Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
    from pathlib import Path
    import json
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
    from subprocess import run, PIPE
    from shlex import split as X
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
    from ocrd_utils import pushd_popd, getLogger
    
    import requests as R
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
    
    LOG = getLogger('kwalitee.repo')
    
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
    
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
    class Repo():
    
    
        def __init__(self, config, url, official=False, compliant_cli=False):
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
            self.url = url
            self.config = config
            self.name = Path(url).name
    
            self.official = official
    
            self.compliant_cli = compliant_cli
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
            self.path = Path(self.config['repodir'], self.name)
    
    
        def __str__(self):
            return '<Repo %s @ %s>' % (self.url, self.path)
    
        def is_cloned(self):
            return self.path.is_dir()
    
        def pull(self):
            with pushd_popd(self.path):
                self._run('git pull origin master')
    
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
        def clone(self):
    
            if self.is_cloned():
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
                LOG.debug("Already cloned: %s" % self.path)
                return
            with pushd_popd(self.config['repodir']):
                LOG.debug("Cloning %s" % self.url)
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
                result = self._run('git clone --depth 1 "%s"' % self.url)
    
    Konstantin Baierer's avatar
    wip
    Konstantin Baierer committed
                LOG.debug("Result: %s" % result)
    
    
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
        def get_git_stats(self):
            ret = {}
    
            LOG.info("  Fetching git info")
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            with pushd_popd(self.path):
                ret['number_of_commits'] = self._run('git rev-list HEAD --count').stdout
                ret['last_commit'] = self._run(r'git log -1 --format=%cd ').stdout
    
                ret['url'] = self._run('git config --get remote.origin.url').stdout
                ret['latest_tag'] = self._run('git describe --abbrev=0 --tags').stdout
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            return ret
    
        def get_file_contents(self):
            ret = {}
    
            LOG.info("  Getting file contents")
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            with pushd_popd(self.path):
                for path in [Path(x) for x in ['ocrd-tool.json', 'Dockerfile', 'README.md', 'setup.py']]:
                    if path.is_file():
                        with path.open() as f:
                            ret[path.name] = f.read()
                    else:
                        ret[path.name] = None
            return ret
    
        def get_python_info(self):
            ret = {}
            with pushd_popd(self.path):
                ret['url'] = self._run('python3 setup.py --url').stdout
                ret['name'] = self._run('python3 setup.py --name').stdout
                ret['author'] = self._run('python3 setup.py --author').stdout
                ret['author-email'] = self._run('python3 setup.py --author-email').stdout
    
            LOG.info("  Fetching pypi info")
            response = R.get('https://pypi.python.org/pypi/%s/json' % ret['name'])
            ret['pypi'] = json.loads(response.text) if response.status_code == 200 else None
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            return ret
    
    
        def to_json(self):
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            desc = {}
            desc['url'] = self.url
    
            desc['official'] = self.official
    
            desc['compliant_cli'] = self.compliant_cli
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
            desc['org_plus_name'] = '/'.join(self.url.split('/')[-2:])
            desc['name'] = self.name
    
            desc['files'] = self.get_file_contents()
            if desc['files']['ocrd-tool.json']:
                desc['ocrd_tool'] = json.loads(desc['files']['ocrd-tool.json'])
                with pushd_popd(self.path):
                    desc['ocrd_tool_validate'] = self._run('ocrd ocrd-tool ocrd-tool.json validate').stdout
            else:
                desc['ocrd_tool'] = ''
                desc['ocrd_tool_validate'] = 'NO ocrd-tool.json'
            desc['git'] = self.get_git_stats()
            if desc['files']['setup.py']:
    
    Konstantin Baierer's avatar
    Konstantin Baierer committed
                desc['python'] = self.get_python_info()
            return desc
    
        def _run(self, cmd, **kwargs):
            result = run(X(cmd), stdout=PIPE, encoding='utf-8', **kwargs)
            if result.stdout:
                result.stdout = result.stdout.strip()
            return result