Example #1
0
def find_projects(basepath, exclude_paths=None, exclude_subspaces=False):
    """
    Crawls the filesystem to find project manifest files and parses them.

    :param basepath: The path to search in, ``str``
    :param exclude_paths: A list of paths which should not be searched, ``list``
    :param exclude_subspaces: The flag is subfolders containing a .alpine file should not be searched, ``bool``
    :returns: A dict mapping relative paths to ``Project`` objects
    ``dict``
    :raises: :exc:RuntimeError` If multiple projects have the same
    name
    """
    projects = {}
    duplicates = {}
    paths = find_project_paths(basepath, exclude_paths, exclude_subspaces)
    for path in paths:
        project = parse_project(os.path.join(basepath, path))
        paths_with_same_name = [path_ for path_, pkg in projects.items() if pkg.name == project.name]
        if paths_with_same_name:
            if project.name not in duplicates:
                duplicates[project.name] = paths_with_same_name
            duplicates[project.name].append(path)
        projects[path] = project
    if duplicates:
        duplicates = ['Multiple projects found with the same name "%s":%s' % (name, ''.join(['\n- %s' % path_ for path_ in paths])) for name, paths in duplicates.items()]
        raise RuntimeError('\n'.join(duplicates))
    return projects
def main(argv=sys.argv[1:]):
    """
    Reads given project_xml and writes extracted variables to outfile.
    """
    parser = argparse.ArgumentParser(description="Read project.xml and write extracted variables to stdout")
    parser.add_argument('project_xml')
    parser.add_argument('outfile')
    args = parser.parse_args(argv)
    project = parse_project(args.project_xml)

    lines = _get_output(project)
    with open(args.outfile, 'w') as ofile:
        ofile.write('\n'.join(lines))
    def test_parse_generated(self):
        maint = self.get_maintainer()
        pack = ProjectTemplate(name='bar',
                               format=1,
                               version='0.0.0',
                               abi='pabi',
                               urls=[Url('foo')],
                               description='pdesc',
                               maintainers=[maint],
                               licenses=['BSD'])
        try:
            rootdir = tempfile.mkdtemp()
            file1 = os.path.join(rootdir, 'CMakeLists.txt')
            file2 = os.path.join(rootdir, PROJECT_MANIFEST_FILENAME)
            create_project_files(rootdir, pack, 'groovy')
            self.assertTrue(os.path.isfile(file1))
            self.assertTrue(os.path.isfile(file2))

            pack_result = parse_project(file2)
            self.assertEqual(pack.name, pack_result.name)
            self.assertEqual(pack.format, pack_result.format)
            self.assertEqual(pack.version, pack_result.version)
            self.assertEqual(pack.abi, pack_result.abi)
            self.assertEqual(pack.description, pack_result.description)
            self.assertEqual(pack.maintainers[0].name, pack_result.maintainers[0].name)
            self.assertEqual(pack.maintainers[0].email, pack_result.maintainers[0].email)
            self.assertEqual(pack.authors, pack_result.authors)
            self.assertEqual(pack.urls[0].url, pack_result.urls[0].url)
            self.assertEqual('website', pack_result.urls[0].type)
            self.assertEqual(pack.licenses, pack_result.licenses)
            self.assertEqual(pack.builddeps, pack_result.builddeps)
            self.assertEqual(pack.buildtooldeps, pack_result.buildtooldeps)
            self.assertEqual(pack.rundeps, pack_result.rundeps)
            self.assertEqual(pack.testdeps, pack_result.testdeps)
            self.assertEqual(pack.conflicts, pack_result.conflicts)
            self.assertEqual(pack.replaces, pack_result.replaces)
            self.assertEqual(pack.exports, pack_result.exports)

            rdict = generate_distutils_setup(project_xml_path=file2)
            self.assertEqual({'name': 'bar',
                              'maintainer': u'John Foo',
                              'maintainer_email': '*****@*****.**',
                              'description': 'pdesc',
                              'license': 'BSD',
                              'version': '0.0.0',
                              'author': '',
                              'url': 'foo'}, rdict)
        finally:
            shutil.rmtree(rootdir)
    def test_parse_generated_multi(self):
        # test with multiple attributes filled
        maint = self.get_maintainer()
        pack = ProjectTemplate(name='bar',
                               format=1,
                               version='0.0.0',
                               abi='pabi',
                               description='pdesc',
                               maintainers=[maint, maint],
                               authors=[maint, maint],
                               licenses=['BSD', 'MIT'],
                               urls=[Url('foo', 'bugtracker'), Url('bar')],
                               builddeps=[Dependency('dep1')],
                               buildtooldeps=[Dependency('dep2'),
                                                      Dependency('dep3')],
                               rundeps=[Dependency('dep4')],
                               testdeps=[Dependency('dep5')],
                               conflicts=[Dependency('dep6')],
                               replaces=[Dependency('dep7'),
                                             Dependency('dep8')],
                               exports=[Export('architecture_independent'),
                                        Export('meta_project')])

        def assertEqualDependencies(deplist1, deplist2):
            if len(deplist1) != len(deplist1):
                return False
            for depx, depy in zip(deplist1, deplist2):
                for attr in ['name', 'lt', 'lte',
                             'eq', 'gte', 'gt']:
                    if getattr(depx, attr) != getattr(depy, attr):
                        return False
            return True

        try:
            rootdir = tempfile.mkdtemp()
            file1 = os.path.join(rootdir, 'CMakeLists.txt')
            file2 = os.path.join(rootdir, PROJECT_MANIFEST_FILENAME)
            create_project_files(rootdir, pack, 'alpine')
            self.assertTrue(os.path.isfile(file1))
            self.assertTrue(os.path.isfile(file2))

            pack_result = parse_project(file2)
            self.assertEqual(pack.name, pack_result.name)
            self.assertEqual(pack.format, pack_result.format)
            self.assertEqual(pack.version, pack_result.version)
            self.assertEqual(pack.abi, pack_result.abi)
            self.assertEqual(pack.description, pack_result.description)
            self.assertEqual(len(pack.maintainers), len(pack_result.maintainers))
            self.assertEqual(len(pack.authors), len(pack_result.authors))
            self.assertEqual(len(pack.urls), len(pack_result.urls))
            self.assertEqual(pack.urls[0].url, pack_result.urls[0].url)
            self.assertEqual(pack.urls[0].type, pack_result.urls[0].type)
            self.assertEqual(pack.licenses, pack_result.licenses)
            self.assertTrue(assertEqualDependencies(pack.builddeps,
                                                    pack_result.builddeps))
            self.assertTrue(assertEqualDependencies(pack.builddeps,
                                                    pack_result.builddeps))
            self.assertTrue(assertEqualDependencies(pack.buildtooldeps,
                                                    pack_result.buildtooldeps))
            self.assertTrue(assertEqualDependencies(pack.rundeps,
                                                    pack_result.rundeps))
            self.assertTrue(assertEqualDependencies(pack.testdeps,
                                                    pack_result.testdeps))
            self.assertTrue(assertEqualDependencies(pack.conflicts,
                                                    pack_result.conflicts))
            self.assertTrue(assertEqualDependencies(pack.replaces,
                                                    pack_result.replaces))
            self.assertEqual(pack.exports[0].tagname, pack_result.exports[0].tagname)
            self.assertEqual(pack.exports[1].tagname, pack_result.exports[1].tagname)

            rdict = generate_distutils_setup(project_xml_path=file2)
            self.assertEqual({'name': 'bar',
                              'maintainer': u'John Foo <*****@*****.**>, John Foo <*****@*****.**>',
                              'description': 'pdesc',
                              'license': 'BSD, MIT',
                              'version': '0.0.0',
                              'author': u'John Foo <*****@*****.**>, John Foo <*****@*****.**>',
                              'url': 'bar'}, rdict)
        finally:
            shutil.rmtree(rootdir)
def generate_distutils_setup(project_xml_path=os.path.curdir, **kwargs):
    """
    Extract the information relevant for distutils from the package
    manifest. The following keys will be set:

    The "name" and "version" are taken from the eponymous tags.

    A single maintainer will set the keys "maintainer" and
    "maintainer_email" while multiple maintainers are merged into the
    "maintainer" fields (including their emails). Authors are handled
    likewise.

    The first URL of type "website" (or without a type) is used for
    the "url" field.

    The "description" is taken from the eponymous tag if it does not
    exceed 200 characters. If it does "description" contains the
    truncated text while "description_long" contains the complete.

    All licenses are merged into the "license" field.

    :param kwargs: All keyword arguments are passed through. The
    above mentioned keys are verified to be identical if passed as
    a keyword argument

    :returns: return dict populated with parsed fields and passed
    keyword arguments
    :raises: :exc:`InvalidProject`
    :raises: :exc:`IOError`
    """
    project = parse_project(project_xml_path)

    data = {}
    data['name'] = project.name
    data['version'] = project.version

    # either set one author with one email or join all in a single field
    if len(project.authors) == 1 and project.authors[0].email is not None:
        data['author'] = project.authors[0].name
        data['author_email'] = project.authors[0].email
    else:
        data['author'] = ', '.join([('%s <%s>' % (a.name, a.email) if a.email is not None else a.name) for a in project.authors])

    # either set one maintainer with one email or join all in a single field
    if len(project.maintainers) == 1:
        data['maintainer'] = project.maintainers[0].name
        data['maintainer_email'] = project.maintainers[0].email
    else:
        data['maintainer'] = ', '.join(['%s <%s>' % (m.name, m.email) for m in project.maintainers])

    # either set the first URL with the type 'website' or the first URL of any type
    websites = [url.url for url in project.urls if url.type == 'website']
    if websites:
        data['url'] = websites[0]
    elif project.urls:
        data['url'] = project.urls[0].url

    if len(project.description) <= 200:
        data['description'] = project.description
    else:
        data['description'] = project.description[:197] + '...'
        data['long_description'] = project.description

    data['license'] = ', '.join(project.licenses)

    # pass keyword arguments and verify equality if generated and passed in
    for k, v in kwargs.items():
        if k in data:
            if v != data[k]:
                raise InvalidProject('The keyword argument "%s" does not match the information from project.xml: "%s" != "%s"' % (k, v, data[k]))
        else:
            data[k] = v

    return data