Exemple #1
0
 def __init__(self):
     self.client = Bintray()
     self.packages = load_packages()
     self.existing_repos = [
         r['repo']['bintray'] for p in self.packages for r in p['recipies']
     ]
     self.missing_packages = []
     self.missing_repos = []
Exemple #2
0
    def transform_packages(self, development=False):
        """"""

        github = get_github_client(3)
        # Used to calculate the resources used
        rate_before = github.rate_limiting
        try:
            with Cache(os.getenv('CACHE_FILE'), notimeout=development):
                # Collect package files
                packages = [os.path.join(self.packages_dir, f)
                            for f in os.listdir(self.packages_dir)
                            if os.path.isfile(os.path.join(self.packages_dir, f))]
                with ThreadPoolExecutor(len(packages)) as executor:
                    # Generate for all packages
                    futures = [executor.submit(transform_package, package) for package in packages]
                    for _ in tqdm(as_completed(futures),
                                  total=len(futures), unit='package', unit_scale=True,
                                  leave=True, position=0, ncols=80):
                        pass

                    # Get results from futures and filter/print errors
                    results = [f.result() for f in futures]
                    errors = [r for r in results if isinstance(r, tuple)]
                    for error in errors:
                        exc = error[1]
                        print('Error in {}: {}\n{}'.format(
                            error[0], str(exc),
                            ''.join(traceback.format_exception(type(exc), exc, exc.__traceback__))))
                    if len(errors) > 0 and not development:
                        print('Errors in {} packages have prevented writing of packages.js'.format(len(errors)))
                        sys.exit(1)
                    elif len(errors) > 0 and development:
                        print('Errors in {} packages prevented them from being generated'.format(len(errors)))

                    # Write new package files
                    data = json.dumps([r for r in results if r is not None], indent=2)
                    with open('packages.json', 'w') as file:
                        file.write(data)
                    with open('packages.js', 'w') as file:
                        file.write('var packages_data = \n')
                        file.write(data)
                        file.write(';')

                    print('All generation steps succeeded and package data written')
        finally:
            # remaining is tuple 0, limit is tuple 1, see https://github.com/PyGithub/PyGithub/commit/ca974699b0ea2a770e6c2dbd162b3d2c0ae9fe89
            rate = github.rate_limiting
            print('Github rate limiting:\n\tRemaining: {}/{}\n\tUsed this call: {}'.format(
                rate[0], rate[1], rate_before[0] - rate[0]))
                # \n\tResets: {} (rate.reset + datetime.timedelta(hours=1)) - datetime.datetime.now()))
                # PyGitHub doesn't implement the rate limit API fully right now
                # see https://github.com/PyGithub/PyGithub/issues/26

            bt = Bintray()
            print('Bintray rate limiting:\n\tUsed this call: {}'.format(bt.rate_used))
Exemple #3
0
class BintrayTransformer(BaseHTTPTransformer):
    def __init__(self):
        super().__init__()
        self.bt = Bintray()
        self.licenses = self.bt.load_licenses()

    def license(self, name):
        return next((l for l in self.licenses if l['name'] == name), None)

    def transform(self, package):
        for recipie in package.recipies:
            if 'repo' in recipie and 'bintray' in recipie.repo:
                bt_package = self.bt.get('/packages/' + recipie.repo.bintray)

                if 'linked_to_repos' in bt_package and bt_package['linked_to_repos'] and 'conan-center' in bt_package['linked_to_repos']:
                    # if the package has been linked to conan-center that repository "replaces" the current one
                    recipie.repo.bintray = 'conan/conan-center/' + recipie.repo.bintray.split('/')[-1]
                    # we don't actually have to download the package information from conan-center because it will be
                    # identical to what we got in the "source" repository

                parts = recipie.repo.bintray.split('/')
                self._set_unless_exists(recipie, 'remote',
                                        'https://api.bintray.com/conan/' + '/'.join(parts[:2]))
                self._set_unless_exists(recipie, 'package', parts[2].split(':')[0])
                if ':' in parts[2]:
                    self._set_unless_exists(recipie, 'user', parts[2].split(':')[1])

                versions = [DotMap(name=v.split(':')[0],
                                   channel=v.split(':')[1],
                                   repo=recipie.repo.bintray,
                                   remote=recipie.remote,
                                   package=recipie.package,
                                   user=recipie.user)
                            for v in bt_package['versions']]
                if 'versions' not in package:
                    package.versions = []
                package.versions.extend(versions)
                package.versions = natsorted(package.versions, key=lambda v: v.name, reverse=True)

                sites = []
                if 'vcs_url' in bt_package and bt_package['vcs_url'] is not None:
                    sites.append(bt_package['vcs_url'])
                if 'website_url' in bt_package and bt_package['website_url'] is not None:
                    sites.append(bt_package['website_url'])
                sites = [s for s in sites if '/conan-' not in s]
                for site in sites:
                    if 'github.com' in site:
                        path = site.split('/')[-2:]
                        if not path[1].startswith('conan') and not path[1].endswith('conan') and path[1]:
                            self._set_unless_exists(package.urls, 'github', '/'.join(path))
                        else:
                            self._set_unless_exists(recipie.urls, 'github', '/'.join(path))
                    else:
                        self._set_unless_exists(package.urls, 'website', site)

                if 'issue_tracker_url' in bt_package and bt_package['issue_tracker_url'] is not None:
                    url = bt_package['issue_tracker_url']
                    if 'github.com/bincrafters/' not in url:
                        self._set_unless_exists(package.urls, 'issues', url)

                if 'desc' in bt_package and bt_package['desc']:
                    desc = bt_package['desc']
                    if 'conan' in desc.lower() and ('package' in desc.lower() or 'recipe' in desc.lower()):
                        pass  # Many descriptions on bintray are in the form "Conan package for..."
                    else:
                        self._set_unless_exists(package, 'description', bt_package['desc'])
                if 'labels' in bt_package:
                    if 'keywords' not in package:
                        package.keywords = []
                    package.keywords.extend(bt_package['labels'])
                if 'licenses' in bt_package:
                    self._set_unless_exists(package, 'licenses',
                                            [self.license(l) for l in bt_package['licenses']])
                if 'name' in bt_package:
                    self._set_unless_exists(package, 'name', bt_package['name'].split(':')[0])

                files = self.bt.get('/packages/' + recipie.repo.bintray + '/files')
                conanfile = next((f for f in files if f['name'] == 'conanfile.py'), None)
                if conanfile is not None:
                    self._set_unless_exists(package.files.conanfile, 'url',
                                            self.bt.download_url('/'.join(parts[:2]),
                                                                 conanfile['path']))
                    self._set_unless_exists(package.files.conanfile, 'content',
                                            self.http.get(package.files.conanfile.url).text)
        return package
Exemple #4
0
 def __init__(self):
     super().__init__()
     self.bt = Bintray()
     self.licenses = self.bt.load_licenses()
Exemple #5
0
class BintrayFinder:
    """Class to detect, print and generate stubs for Bintray packages"""
    def __init__(self):
        self.client = Bintray()
        self.packages = load_packages()
        self.existing_repos = [
            r['repo']['bintray'] for p in self.packages for r in p['recipies']
        ]
        self.missing_packages = []
        self.missing_repos = []

    def _gather_repos(self) -> Set[BintrayRepoDescriptor]:
        """
        Returns all repositories (tuple of repository owner and repository name) that are currently known
        """
        repos = set()
        for pkg in self.packages:
            for recipie in pkg['recipies']:
                parts = recipie['repo']['bintray'].split('/')
                repos.add(BintrayRepoDescriptor(parts[0], parts[1]))
        repos.add(BintrayRepoDescriptor('conan', 'conan-center'))

        # Github repos that need to be created or located on bintray:
        # https://github.com/syslandscape/syslandscape
        # https://github.com/cajun-code/sfml.conan
        # https://github.com/erikvalkering/smartref
        # https://github.com/malwoden/conan-librsync
        # https://github.com/LighthouseJ/mtn
        # https://github.com/raulbocanegra/utils
        # https://github.com/Aquaveo/xmscore
        # https://github.com/franc0is/conan-jansson
        # https://github.com/srand/stdext-uuid
        # https://github.com/db4/conan-jwasm
        # https://github.com/ulricheck/conan-librealsense
        # https://github.com/iblis-ms/conan_gmock
        # https://github.com/zacklj89/conan-CppMicroServices
        # https://github.com/nickbruun/conan-hayai
        # https://github.com/JavierJF/TabletMode
        # https://github.com/google/fruit
        # https://github.com/StiventoUser/conan-sqlpp11-connector-postgresql
        # https://github.com/wumuzi520/conan-snappy
        # https://github.com/DigitalInBlue/Celero-Conan
        # https://github.com/Trick-17/FMath
        # https://github.com/kwint/conan-gnuplot-iostream
        # https://github.com/luisnuxx/formiga
        # https://github.com/gustavokretzer88/conan-OATH-Toolkit
        # https://github.com/lightningcpp/lightningcpp
        # https://github.com/jasonbot/conan-jansson
        # https://github.com/bfierz/vcl
        # https://github.com/SverreEplov/conan-wt
        # https://github.com/jampio/jkpak
        # https://github.com/StableTec/vulkan
        # https://github.com/tmadden/alia
        # https://github.com/JavierJF/CloseApp
        # https://github.com/e3dskunkworks/conan-celero
        # https://github.com/kheaactua/conan-ffi
        # https://github.com/matlo607/conan-swig
        # https://github.com/Exiv2/exiv2
        # https://github.com/Ubitrack/component_vision_aruco
        # https://github.com/iblis-ms/conan_gbenchmark
        # https://github.com/p47r1ck7541/conan-llvm-60
        # https://github.com/StableCoder/conan-mariadb-connector

        # https://github.com/yackey/AvtecGmock # owner exists
        # https://github.com/yackey/AEF-CI # owner exists
        # https://github.com/spielhuus/avcpp # owner exists
        # https://github.com/nwoetzel/conan-omniorb # owner exists

        for a in [
                'inexorgame/inexor-conan', 'odant/conan', 'vuo/conan',
                'squawkcpp/conan-cpp', 'degoodmanwilson/opensource',
                'objectx/conan', 'franc0is/conan', 'boujee/conan', 'mdf/2out',
                'impsnldavid/public-conan', 'sunxfancy/common', 'jacmoe/Conan',
                'madebr/openrw', 'ogs/conan', 'danimtb/public-conan',
                'kwallner/stable', 'kwallner/testing', 'dobiasd/public-conan',
                'solvingj/public-conan', 'slyrisorg/SlyrisOrg',
                'cliutils/CLI11', 'tuncb/pangea', 'mikayex/conan-packages',
                'kenfred/conan-corner', 'p-groarke/conan-public',
                'jabaa/Conan', 'blosc/Conan', 'sourcedelica/public-conan',
                'sourcedelica/conan', 'rockdreamer/throwing_ptr',
                'qtproject/conan', 'rhard/conan', 'tao-cpp/tao-cpp',
                'bitprim/bitprim', 'yadoms/yadoms', 'enhex/enhex',
                'jilabinc/conan', 'bisect/bisect', 'artalus/conan-public',
                'alekseevx/pft', 'mbedded-ninja/LinuxCanBus',
                'cynarakrewe/CynaraConan', 'jsee23/public',
                'foxostro/PinkTopaz', 'jgsogo/conan-packages',
                'vtpl1/conan-expat', 'vtpl1/conan-ffmpeg', 'ess-dmsc/conan',
                'acdemiralp/makina', 'rwth-vr/conan', 'onyx/conan'
        ]:
            splitted = a.split('/')
            repos.add(BintrayRepoDescriptor(splitted[0], splitted[1]))

        return repos

    def _find_packages(
            self,
            repos: Set[BintrayRepoDescriptor]) -> [BintrayPackageDescriptor]:
        """
        Returns all packages in the known repositories
        """
        pkgs = [
            BintrayPackageDescriptor(repo.repoowner, repo.reponame, p['name'],
                                     p['linked']) for repo in repos
            for p in self.client.get_all('/repos/' + repo.repoowner + '/' +
                                         repo.reponame + '/packages')
        ]

        # replace linked packages by their sources
        for index, pkg in enumerate(pkgs):
            if pkg.linked:
                bt_package = self.client.get('/packages/' + pkg.repoowner +
                                             '/' + pkg.reponame + '/' +
                                             pkg.name)
                pkgs[index] = BintrayPackageDescriptor(bt_package['owner'],
                                                       bt_package['repo'],
                                                       pkg.name, False)

        return list(set(pkgs))

    @classmethod
    def _default_package_filename(cls, pkg: BintrayPackageDescriptor):
        clean_name = pkg.name.split(':')[0].lower().replace('conan-', '')
        clean_name = re.sub(r'^boost_', 'boost.', clean_name)
        clean_name = clean_name.replace('+', '_')
        return os.path.join(packages_directory(), clean_name + '.yaml')

    def _filter_missing_package(
            self, packages: [BintrayPackageDescriptor
                             ]) -> [BintrayPackageDescriptor]:
        """Only return packages for those there is no package file available currently"""
        return [
            p for p in packages
            if not os.path.exists(self._default_package_filename(p))
        ]

    def _filter_missing_repository(
            self, packages: [BintrayPackageDescriptor
                             ]) -> [BintrayPackageDescriptor]:
        """Only return packages that have missing repository descriptors"""
        return [
            p for p in packages if '/'.join(p[:3]) not in self.existing_repos
            and not p.name.startswith('Boost') and p.reponame != 'conan-center'
        ]

    def run(self):
        found = self._find_packages(self._gather_repos())
        self.missing_packages = self._filter_missing_package(found)
        self.missing_repos = sorted(self._filter_missing_repository(found))

    def print(self):
        for pkg in self.missing_packages:
            print('Missing package:', '/'.join(pkg[:3]))
        for pkg in self.missing_repos:
            print('Missing repository:', '/'.join(pkg[:3]))

    def generate_stubs(self):
        for name in self.missing_packages:
            # pkg = self.http.get(self.url + '/' + name).json()
            fname = self._default_package_filename(name)
            logging.getLogger(__name__).info('Generating %s',
                                             os.path.basename(fname))
            with open(fname, 'w') as f:
                yaml.dump(
                    dict(recipies=[
                        dict(repo=dict(bintray=name.repoowner + '/' +
                                       name.reponame + '/' + name.name))
                    ],
                         urls=dict()), f)