Пример #1
0
def _gen_metadata_for_package(distro, pkg_name, pkg, repo, ros_pkg,
                              pkg_rosinstall):
    pkg_metadata_xml = metadata_xml()
    try:
        pkg_xml = ros_pkg.get_package_xml(distro.name)
    except Exception:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_metadata_xml
    pkg_fields = xmltodict.parse(pkg_xml)
    if 'description' in pkg_fields['package']:
        # fill longdescription, if available (defaults to "NONE").
        pkg_metadata_xml.longdescription = pkg_fields['package']['description']
    if 'maintainer' in pkg_fields['package']:
        if isinstance(pkg_fields['package']['maintainer'], list):
            pkg_metadata_xml.upstream_email =\
                pkg_fields['package']['maintainer'][0]['@email']
            pkg_metadata_xml.upstream_name =\
                pkg_fields['package']['maintainer'][0]['#text']
        elif isinstance(pkg_fields['package']['maintainer']['@email'], list):
            pkg_metadata_xml.upstream_email =\
                pkg_fields['package']['maintainer'][0]['@email']
            pkg_metadata_xml.upstream_name =\
                pkg_fields['package']['maintainer'][0]['#text']
        else:
            pkg_metadata_xml.upstream_email =\
                pkg_fields['package']['maintainer']['@email']
            if '#text' in pkg_fields['package']['maintainer']:
                pkg_metadata_xml.upstream_name =\
                    pkg_fields['package']['maintainer']['#text']
            else:
                pkg_metadata_xml.upstream_name = "UNKNOWN"

        pkg_metadata_xml.upstream_bug_url =\
            repo.url.replace("-release", "").replace(".git", "/issues")
    return pkg_metadata_xml
Пример #2
0
def _gen_recipe_for_package(distro, pkg_name, pkg, repo, ros_pkg,
                            pkg_rosinstall, tar_dir, md5_cache, sha256_cache,
                            patches, incs):
    pkg_dep_walker = DependencyWalker(distro)
    pkg_buildtool_deps = pkg_dep_walker.get_depends(pkg_name, "buildtool")
    pkg_build_deps = pkg_dep_walker.get_depends(pkg_name, "build")
    pkg_run_deps = pkg_dep_walker.get_depends(pkg_name, "run")
    src_uri = pkg_rosinstall[0]['tar']['uri']

    pkg_recipe = yoctoRecipe(pkg_name, distro, src_uri, tar_dir, md5_cache,
                             sha256_cache, patches, incs)
    # add run dependencies
    for rdep in pkg_run_deps:
        pkg_recipe.add_depend(rdep)

    # add build dependencies
    for bdep in pkg_build_deps:
        pkg_recipe.add_depend(bdep)

    # add build tool dependencies
    for tdep in pkg_buildtool_deps:
        pkg_recipe.add_depend(tdep)

    # parse throught package xml
    try:
        pkg_xml = ros_pkg.get_package_xml(distro.name)
    except Exception as e:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_recipe
    pkg_fields = PackageMetadata(pkg_xml)
    pkg_recipe.pkg_xml = pkg_xml
    pkg_recipe.license = pkg_fields.upstream_license
    pkg_recipe.description = pkg_fields.description
    pkg_recipe.homepage = pkg_fields.homepage
    return pkg_recipe
Пример #3
0
 def get_dependencies(
         self, internal_depends, external_depends, is_native=False):
     dependencies = set()
     system_dependencies = set()
     union_deps = internal_depends | external_depends
     if len(union_deps) <= 0:
         return dependencies, system_dependencies
     for dep in union_deps:
         if dep in internal_depends:
             recipe = self.convert_to_oe_name(dep, is_native)
             dependencies.add(recipe)
             info('Internal dependency add: ' + recipe)
             continue
         try:
             results = resolve_dep(dep, 'openembedded', self.distro)[0]
             if not results:
                 yoctoRecipe.rosdep_cache[dep] = []
                 continue
             for res in results:
                 recipe = self.convert_to_oe_name(res, is_native)
                 dependencies.add(recipe)
                 system_dependencies.add(self.convert_to_oe_name(res))
                 yoctoRecipe.rosdep_cache[dep].add(res)
                 info('External dependency add: ' + recipe)
         except UnresolvedDependency:
             info('Unresolved dependency: ' + dep)
             if dep in yoctoRecipe.rosdep_cache:
                 cached_deps = yoctoRecipe.rosdep_cache[dep]
                 if cached_deps == set(['null']):
                     system_dependencies.add(dep)
                     recipe = dep + self.get_native_suffix(is_native)
                     dependencies.add(recipe)
                     msg = 'Failed to resolve (cached):'
                     warn('{0} {1}: {2}'.format(msg, dep, recipe))
                 elif cached_deps:
                     system_dependencies |= cached_deps
                     for d in cached_deps:
                         recipe = self.convert_to_oe_name(d, is_native)
                         dependencies.add(recipe)
                         msg = 'Resolved in OpenEmbedded (cached):'
                         info('{0} {1}: {2}'.format(msg, dep, recipe))
                 continue
             oe_query = OpenEmbeddedLayersDB()
             oe_query.query_recipe(self.convert_to_oe_name(dep))
             if oe_query.exists():
                 recipe = self.convert_to_oe_name(oe_query.name, is_native)
                 dependencies.add(recipe)
                 oe_name = self.convert_to_oe_name(oe_query.name)
                 system_dependencies.add(oe_name)
                 yoctoRecipe.rosdep_cache[dep].add(oe_name)
                 info('Resolved in OpenEmbedded: ' + dep + ' as ' +
                      oe_query.name + ' in ' + oe_query.layer +
                      ' as recipe ' + recipe)
             else:
                 recipe = dep + self.get_native_suffix(is_native)
                 dependencies.add(recipe)
                 system_dependencies.add(dep)
                 yoctoRecipe.rosdep_cache[dep].add('null')
                 warn('Failed to resolve fully: ' + dep)
     return dependencies, system_dependencies
Пример #4
0
def _gen_ebuild_for_package(
    distro, pkg_name, pkg, repo, ros_pkg, pkg_rosinstall
):
    pkg_ebuild = Ebuild()

    pkg_ebuild.distro = distro.name
    pkg_ebuild.src_uri = pkg_rosinstall[0]['tar']['uri']
    pkg_names = get_package_names(distro)
    pkg_dep_walker = DependencyWalker(distro)

    pkg_buildtool_deps = pkg_dep_walker.get_depends(pkg_name, "buildtool")
    pkg_build_deps = pkg_dep_walker.get_depends(pkg_name, "build")
    pkg_run_deps = pkg_dep_walker.get_depends(pkg_name, "run")
    pkg_test_deps = pkg_dep_walker.get_depends(pkg_name, "test")

    pkg_keywords = ['x86', 'amd64', 'arm', 'arm64']

    # add run dependencies
    for rdep in pkg_run_deps:
        pkg_ebuild.add_run_depend(rdep, rdep in pkg_names[0])

    # add build dependencies
    for bdep in pkg_build_deps:
        pkg_ebuild.add_build_depend(bdep, bdep in pkg_names[0])

    # add build tool dependencies
    for tdep in pkg_buildtool_deps:
        pkg_ebuild.add_build_depend(tdep, tdep in pkg_names[0])

    # add test dependencies
    for test_dep in pkg_test_deps:
        pkg_ebuild.add_test_depend(test_dep, test_dep in pkg_names[0])

    # add keywords
    for key in pkg_keywords:
        pkg_ebuild.add_keyword(key)

    # parse throught package xml
    try:
        pkg_xml = ros_pkg.get_package_xml(distro.name)
    except Exception:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_ebuild
    pkg = PackageMetadata(pkg_xml)
    pkg_ebuild.upstream_license = pkg.upstream_license
    pkg_ebuild.description = pkg.description
    pkg_ebuild.homepage = pkg.homepage
    pkg_ebuild.build_type = pkg.build_type
    return pkg_ebuild
Пример #5
0
def _gen_ebuild_for_package(distro, pkg_name, pkg, repo, ros_pkg,
                            pkg_rosinstall):
    pkg_ebuild = Ebuild()

    pkg_ebuild.distro = distro.name
    pkg_ebuild.src_uri = pkg_rosinstall[0]['tar']['uri']
    pkg_names = get_package_names(distro)
    pkg_dep_walker = DependencyWalker(distro)

    pkg_buildtool_deps = pkg_dep_walker.get_depends(pkg_name, "buildtool")
    pkg_build_deps = pkg_dep_walker.get_depends(pkg_name, "build")
    pkg_run_deps = pkg_dep_walker.get_depends(pkg_name, "run")

    pkg_keywords = ['x86', 'amd64', 'arm', 'arm64']

    # add run dependencies
    for rdep in pkg_run_deps:
        pkg_ebuild.add_run_depend(rdep, rdep in pkg_names[0])

    # add build dependencies
    for bdep in pkg_build_deps:
        pkg_ebuild.add_build_depend(bdep, bdep in pkg_names[0])

    # add build tool dependencies
    for tdep in pkg_buildtool_deps:
        pkg_ebuild.add_build_depend(tdep, tdep in pkg_names[0])

    # add keywords
    for key in pkg_keywords:
        pkg_ebuild.add_keyword(key)

    # parse throught package xml
    try:
        pkg_xml = ros_pkg.get_package_xml(distro.name)
    except Exception as e:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_ebuild
    pkg_fields = xmltodict.parse(pkg_xml)

    pkg_ebuild.upstream_license = pkg_fields['package']['license']
    pkg_ebuild.description = pkg_fields['package']['description']
    if isinstance(pkg_ebuild.description, str):
        pkg_ebuild.description = pkg_ebuild.description.replace('`', "")
    if len(pkg_ebuild.description) > 80:
        pkg_ebuild.description = pkg_ebuild.description[:80]
    try:
        if 'url' not in pkg_fields['package']:
            warn("no website field for package {}".format(pkg_name))
        elif isinstance(pkg_fields['package']['url'], str):
            pkg_ebuild.homepage = pkg_fields['package']['url']
        elif '@type' in pkg_fields['package']['url']:
            if pkg_fields['package']['url']['@type'] == 'website':
                if '#text' in pkg_fields['package']['url']:
                    pkg_ebuild.homepage = pkg_fields['package']['url']['#text']
        else:
            warn("failed to parse website for package {}".format(pkg_name))
    except TypeError as e:
        warn("failed to parse website package {}: {}".format(pkg_name, e))
    return pkg_ebuild
Пример #6
0
def _gen_metadata_for_package(distro, pkg_name, pkg, repo, ros_pkg,
                              pkg_rosinstall):
    pkg_metadata_xml = metadata_xml()
    try:
        pkg_xml = retry_on_exception(ros_pkg.get_package_xml, distro.name)
    except Exception:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_metadata_xml
    pkg = PackageMetadata(pkg_xml)
    pkg_metadata_xml.upstream_email = pkg.upstream_email
    pkg_metadata_xml.upstream_name = pkg.upstream_name
    pkg_metadata_xml.longdescription = pkg.longdescription
    pkg_metadata_xml.upstream_bug_url =\
        repo.url.replace("-release", "").replace(".git", "/issues")
    return pkg_metadata_xml
Пример #7
0
def _gen_recipe_for_package(distro, pkg_name, pkg, repo, ros_pkg,
                            pkg_rosinstall, tar_dir):
    pkg_dep_walker = DependencyWalker(distro)
    pkg_buildtool_deps = pkg_dep_walker.get_depends(pkg_name, "buildtool")
    pkg_build_deps = pkg_dep_walker.get_depends(pkg_name, "build")
    pkg_run_deps = pkg_dep_walker.get_depends(pkg_name, "run")
    src_uri = pkg_rosinstall[0]['tar']['uri']

    pkg_recipe = yoctoRecipe(pkg_name, distro, src_uri, tar_dir)
    # add run dependencies
    for rdep in pkg_run_deps:
        pkg_recipe.add_depend(rdep)

    # add build dependencies
    for bdep in pkg_build_deps:
        pkg_recipe.add_depend(bdep)

    # add build tool dependencies
    for tdep in pkg_buildtool_deps:
        pkg_recipe.add_depend(tdep)

    # parse throught package xml
    try:
        pkg_xml = ros_pkg.get_package_xml(distro.name)
    except Exception as e:
        warn("fetch metadata for package {}".format(pkg_name))
        return pkg_recipe
    pkg_fields = xmltodict.parse(pkg_xml)

    pkg_recipe.pkg_xml = pkg_xml
    pkg_recipe.license = pkg_fields['package']['license']
    pkg_recipe.description = pkg_fields['package']['description']
    if not isinstance(pkg_recipe.description, str):
        if '#text' in pkg_recipe.description:
            pkg_recipe.description = pkg_recipe.description['#text']
        else:
            pkg_recipe.description = "None"
    pkg_recipe.description = pkg_recipe.description.replace('`', "")
    if len(pkg_recipe.description) > 80:
        pkg_recipe.description = pkg_recipe.description[:80]
    try:
        if 'url' not in pkg_fields['package']:
            warn("no website field for package {}".format(pkg_name))
        elif sys.version_info <= (3, 0):
            pkg_recipe.recipe = pkg_fields['package']['url'].decode()
        elif isinstance(pkg_fields['package']['url'], str):
            pkg_recipe.homepage = pkg_fields['package']['url']
        elif '@type' in pkg_fields['package']['url']:
            if pkg_fields['package']['url']['@type'] == 'website':
                if '#text' in pkg_fields['package']['url']:
                    pkg_recipe.homepage =\
                        pkg_fields['package']['url']['#text']
        else:
            warn("failed to parse website for package {}".format(pkg_name))
    except TypeError as e:
        warn("failed to parse website package {}: {}".format(pkg_name, e))
    return pkg_recipe
Пример #8
0
def regenerate_pkg(overlay, pkg, rosdistro, preserve_existing, srcrev_cache,
                   skip_keys):
    pkg_names = get_package_names(rosdistro)[0]
    if pkg not in pkg_names:
        yoctoRecipe.not_generated_recipes.add(pkg)
        raise RuntimeError("Unknown package '%s' available packages"
                           " in selected distro: %s" %
                           (pkg, get_package_names(rosdistro)))
    try:
        version = get_pkg_version(rosdistro, pkg, is_oe=True)
    except KeyError as ke:
        yoctoRecipe.not_generated_recipes.add(pkg)
        raise ke
    repo_dir = overlay.repo.repo_dir
    component_name = yoctoRecipe.convert_to_oe_name(
        rosdistro.release_packages[pkg].repository_name)
    recipe = yoctoRecipe.convert_to_oe_name(pkg)
    # check for an existing recipe which was removed by clean_ros_recipe_dirs
    prefix = 'meta-ros{0}-{1}/generated-recipes/*/{2}_*.bb'.format(
        yoctoRecipe._get_ros_version(rosdistro.name), rosdistro.name, recipe)
    existing = overlay.repo.git.status('--porcelain', '--', prefix)
    if existing:
        # The git status --porcelain output will look like this:
        # D  meta-ros2-eloquent/generated-recipes/variants/ros-base_0.8.3-1.bb
        # we want just the path with filename
        if len(existing.split('\n')) > 1:
            warn('More than 1 recipe was output by "git status --porcelain '
                 'meta-ros{0}-{1}/generated-recipes/*/{2}_*.bb": "{3}"'.format(
                     yoctoRecipe._get_ros_version(rosdistro.name),
                     rosdistro.name, recipe, existing))
        if existing.split()[0] != 'D':
            err('Unexpected output from "git status --porcelain '
                'meta-ros{0}-{1}/generated-recipes/*/{2}_*.bb": "{3}"'.format(
                    yoctoRecipe._get_ros_version(rosdistro.name),
                    rosdistro.name, recipe, existing))

        existing = existing.split()[1]
    else:
        # If it isn't shown in git status, it could still exist as normal
        # unchanged file when --only option is being used
        import glob
        existing = glob.glob('{0}/{1}'.format(repo_dir, prefix))
        if existing:
            if len(existing) > 1:
                err('More than 1 recipe was output by "git status '
                    '--porcelain '
                    'meta-ros{0}-{1}/generated-recipes/*/{2}_*.bb": "{3}"'.
                    format(yoctoRecipe._get_ros_version(rosdistro.name),
                           rosdistro.name, recipe, existing))
            existing = existing[0]

    previous_version = None
    if preserve_existing and existing:
        ok("recipe for package '%s' up to date, skipping..." % pkg)
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    elif existing:
        overlay.repo.remove_file(existing, True)
        idx_version = existing.rfind('_') + len('_')
        previous_version = existing[idx_version:].rstrip('.bb')
    try:
        current = oe_recipe(rosdistro, pkg, srcrev_cache, skip_keys)
    except InvalidPackage as e:
        err('Invalid package: ' + str(e))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    except Exception as e:
        err('Failed generating recipe for {}! {}'.format(pkg, str(e)))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    try:
        recipe_text = current.recipe_text()
    except NoPkgXml as nopkg:
        err("Could not fetch pkg! {}".format(str(nopkg)))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    except KeyError as ke:
        err("Failed to parse data for package {}! {}".format(pkg, str(ke)))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    make_dir("{0}/meta-ros{1}-{2}/generated-recipes/{3}".format(
        repo_dir, yoctoRecipe._get_ros_version(rosdistro.name), rosdistro.name,
        component_name))
    success_msg = 'Successfully generated recipe for package'
    ok('{0} \'{1}\'.'.format(success_msg, pkg))
    recipe_file_name = '{0}/meta-ros{1}-{2}/generated-recipes/{3}/' \
        '{4}_{5}.bb'.format(
            repo_dir,
            yoctoRecipe._get_ros_version(rosdistro.name),
            rosdistro.name,
            component_name,
            recipe,
            version
        )
    try:
        with open('{0}'.format(recipe_file_name), "w") as recipe_file:
            ok('Writing recipe {0}'.format(recipe_file_name))
            recipe_file.write(recipe_text)
            yoctoRecipe.generated_components.add(component_name)
            yoctoRecipe.generated_recipes[recipe] = (version, component_name)
    except Exception:
        err("Failed to write recipe to disk!")
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, [], None
    return current, previous_version, recipe
Пример #9
0
def main():
    overlay = None
    parser = get_parser('Generate OpenEmbedded recipes for ROS packages',
                        exclude_all=True,
                        require_rosdistro=True,
                        require_dryrun=True)
    parser.add_argument('--tar-archive-dir',
                        help='location to store archived packages',
                        type=str)
    args = parser.parse_args(sys.argv[1:])
    pr_comment = args.pr_comment
    skip_keys = set(args.skip_keys) if args.skip_keys else set()
    if args.pr_only:
        if args.dry_run:
            parser.error('Invalid args! cannot dry-run and file PR')
        if not args.output_repository_path:
            parser.error('Invalid args! no repository specified')
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            msg, title = load_pr()
            prev_overlay.pull_request(msg, title=title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)
    warn('"{0}" distro detected...'.format(args.ros_distro))
    """
    No longer supporting generation for multiple targets, but left the code in
    place to handle them in case it might be needed again in the future.
    """
    selected_targets = [args.ros_distro]
    preserve_existing = args.only
    now = os.getenv('SUPERFLORE_GENERATION_DATETIME',
                    get_utcnow_timestamp_str())
    repo_org = 'ros'
    repo_name = 'meta-ros'
    if args.upstream_repo:
        repo_org, repo_name = url_to_repo_org(args.upstream_repo)
    # open cached tar file if it exists
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output_repository_path is None
        overlay = RosMeta(
            _repo,
            not args.output_repository_path,
            branch=(('superflore/{}'.format(now))
                    if not args.no_branch else None),
            org=repo_org,
            repo=repo_name,
            from_branch=args.upstream_branch,
        )
        if not args.only:
            pr_comment = pr_comment or (
                'Recipes generated by **superflore** for all packages in ROS '
                'distribution {}.\n'.format(selected_targets[0]))
        else:
            pr_comment = pr_comment or (
                'Recipes generated by **superflore** for package(s) {} in ROS '
                'distribution {}.\n'.format(args.only, args.ros_distro))
        # generate installers
        total_installers = dict()
        total_changes = dict()
        if args.tar_archive_dir:
            srcrev_filename = '%s/srcrev_cache.pickle' % args.tar_archive_dir
        else:
            srcrev_filename = None
        with CacheManager(srcrev_filename) as srcrev_cache:
            if args.only:
                distro = get_distro(args.ros_distro)
                for pkg in args.only:
                    if pkg in skip_keys:
                        warn("Package '%s' is in skip-keys list, skipping..." %
                             pkg)
                        continue
                    info("Regenerating package '%s'..." % pkg)
                    try:
                        regenerate_pkg(
                            overlay,
                            pkg,
                            distro,
                            False,  # preserve_existing
                            srcrev_cache,
                            skip_keys=skip_keys,
                        )
                    except KeyError:
                        err("No package to satisfy key '%s' available "
                            "packages in selected distro: %s" %
                            (pkg, get_package_names(distro)))
                        sys.exit(1)
                # Commit changes and file pull request
                title =\
                    '{{{0}}} Selected recipes generated from '\
                    'files/{0}/generated/cache.yaml '\
                    'as of {1}\n'.format(
                            args.ros_distro,
                            now)
                regen_dict = dict()
                regen_dict[args.ros_distro] = args.only
                delta = "Regenerated: '%s'\n" % args.only
                overlay.add_generated_files(args.ros_distro)
                commit_msg = '\n'.join([
                    get_pr_text(
                        title + '\n' +
                        pr_comment.replace('**superflore**', 'superflore'),
                        markup=''), delta
                ])
                overlay.commit_changes(args.ros_distro, commit_msg)
                if args.dry_run:
                    save_pr(overlay, args.only, '', pr_comment, title=title)
                    sys.exit(0)
                file_pr(overlay,
                        delta,
                        '',
                        pr_comment,
                        distro=args.ros_distro,
                        title=title)
                ok('Successfully synchronized repositories!')
                sys.exit(0)

            overlay.clean_ros_recipe_dirs(args.ros_distro)
            for adistro in selected_targets:
                yoctoRecipe.reset()
                distro = get_distro(adistro)

                distro_installers, _, distro_changes =\
                    generate_installers(
                        distro,
                        overlay,
                        regenerate_pkg,
                        preserve_existing,
                        srcrev_cache,
                        skip_keys,
                        skip_keys=skip_keys,
                        is_oe=True,
                    )
                total_changes[adistro] = distro_changes
                total_installers[adistro] = distro_installers
                yoctoRecipe.generate_ros_distro_inc(
                    _repo, args.ros_distro,
                    overlay.get_file_revision_logs(
                        'meta-ros{0}-{1}/files/{1}/generated/cache.yaml'.
                        format(yoctoRecipe._get_ros_version(args.ros_distro),
                               args.ros_distro)), distro.release_platforms,
                    skip_keys)
                yoctoRecipe.generate_superflore_datetime_inc(
                    _repo, args.ros_distro, now)
                yoctoRecipe.generate_rosdep_resolve(_repo, args.ros_distro)
                yoctoRecipe.generate_newer_platform_components(
                    _repo, args.ros_distro)
                overlay.add_generated_files(args.ros_distro)

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            summary = overlay.get_change_summary(args.ros_distro)
            if len(summary) == 0:
                info('Exiting...')
                clean_up()
                sys.exit(0)
            else:
                info('But there are some changes in other regenerated files:'
                     '%s' % summary)

        # remove duplicates
        delta = gen_delta_msg(total_changes, markup='')
        # Commit changes and file pull request
        title = '{{{0}}} Sync to files/{0}/generated/'\
            'cache.yaml as of {1}\n'.format(
                args.ros_distro,
                now)
        commit_msg = '\n'.join([
            get_pr_text(title + '\n' +
                        pr_comment.replace('**superflore**', 'superflore'),
                        markup=''), delta
        ])
        overlay.commit_changes(args.ros_distro, commit_msg)
        delta = gen_delta_msg(total_changes)
        if args.dry_run:
            info('Running in dry mode, not filing PR')
            save_pr(
                overlay,
                delta,
                '',
                pr_comment,
                title=title,
            )
            sys.exit(0)
        file_pr(overlay, delta, '', comment=pr_comment, title=title)
        clean_up()
        ok('Successfully synchronized repositories!')
Пример #10
0
def generate_installers(
    distro,  # ros distro
    overlay,  # repo instance
    gen_pkg_func,  # function to call for generating
    preserve_existing=True,  # don't regenerate if installer exists
    *args,  # any additional args for gen_pkg_func
    **kwargs  # any additional keyword arguments
):
    distro_name = distro.name
    pkg_names = get_package_names(distro)
    total = float(len(pkg_names[0]))
    borkd_pkgs = dict()
    changes = []
    installers = []
    bad_installers = []
    succeeded = 0
    failed = 0

    info("Generating installers for distro '%s'" % distro_name)
    for i, pkg in enumerate(sorted(pkg_names[0])):
        if 'skip_keys' in kwargs and pkg in kwargs['skip_keys']:
            warn("Package '%s' is in skip-keys list, skipping..." % pkg)
            continue
        version = get_pkg_version(distro, pkg)
        percent = '%.1f' % (100 * (float(i) / total))
        try:
            current, current_info = gen_pkg_func(overlay, pkg, distro,
                                                 preserve_existing, *args)
            if not current and current_info:
                # we are missing dependencies
                failed_msg = "{0}%: Failed to generate".format(percent)
                failed_msg += " installer for package '%s'!" % pkg
                err(failed_msg)
                borkd_pkgs[pkg] = current_info
                failed = failed + 1
                continue
            elif not current and preserve_existing:
                # don't replace the installer
                succeeded = succeeded + 1
                continue
            success_msg = 'Successfully generated installer for package'
            ok('{0}%: {1} \'{2}\'.'.format(percent, success_msg, pkg))
            succeeded = succeeded + 1
            if current_info:
                changes.append('*{0} {1} --> {2}*'.format(
                    pkg, current_info, version))
            else:
                changes.append('*{0} {1}*'.format(pkg, version))
            installers.append(pkg)
        except UnknownBuildType as ub:
            err("{0}%: Unknown Build type '{1}' for package '{2}'".format(
                percent, str(ub), pkg))
            failed = failed + 1
        except KeyError:
            failed_msg = 'Failed to generate installer'
            err("{0}%: {1} for package {2}!".format(percent, failed_msg, pkg))
            bad_installers.append(pkg)
            failed = failed + 1
    results = 'Generated {0} / {1}'.format(succeeded, failed + succeeded)
    results += ' for distro {0}'.format(distro_name)
    info("------ {0} ------\n".format(results))

    if len(borkd_pkgs) > 0:
        warn("Unresolved:")
        for broken in borkd_pkgs.keys():
            warn("{}:".format(broken))
            warn("  {}".format(borkd_pkgs[broken]))

    return installers, borkd_pkgs, changes
Пример #11
0
def main():
    os.environ["ROS_OS_OVERRIDE"] = "openembedded"
    overlay = None
    preserve_existing = True
    parser = get_parser('Deploy ROS packages into OpenEmbedded Linux',
                        exclude_all=True)
    parser.add_argument('--tar-archive-dir',
                        help='location to store archived packages',
                        type=str)
    args = parser.parse_args(sys.argv[1:])
    pr_comment = args.pr_comment
    skip_keys = set(args.skip_keys) if args.skip_keys else set()
    selected_targets = None
    if args.pr_only:
        if args.dry_run:
            parser.error('Invalid args! cannot dry-run and file PR')
        if not args.output_repository_path:
            parser.error('Invalid args! no repository specified')
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            msg, title = load_pr()
            prev_overlay.pull_request(msg, title=title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)
    elif args.ros_distro:
        warn('"{0}" distro detected...'.format(args.ros_distro))
        selected_targets = [args.ros_distro]
        preserve_existing = False
    elif args.only:
        parser.error('Invalid args! --only requires specifying --ros-distro')
    if not selected_targets:
        selected_targets = get_distros_by_status('active')
    now = get_utcnow_timestamp_str()
    repo_org = 'ros'
    repo_name = 'meta-ros'
    if args.upstream_repo:
        repo_org, repo_name = url_to_repo_org(args.upstream_repo)
    # open cached tar file if it exists
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output_repository_path is None
        overlay = RosMeta(
            _repo,
            not args.output_repository_path,
            branch='superflore/{}'.format(now),
            org=repo_org,
            repo=repo_name,
            from_branch=args.upstream_branch,
        )
        if not args.only:
            pr_comment = pr_comment or (
                'Recipes generated by **superflore** for all packages in ROS '
                'distribution {}.\n'.format(selected_targets[0]))
        else:
            pr_comment = pr_comment or (
                'Recipes generated by **superflore** for package(s) {} in ROS '
                'distribution {}.\n'.format(args.only, args.ros_distro))
        # generate installers
        total_installers = dict()
        total_changes = dict()
        if args.tar_archive_dir:
            sha256_filename = '%s/sha256_cache.pickle' % args.tar_archive_dir
            md5_filename = '%s/md5_cache.pickle' % args.tar_archive_dir
        else:
            sha256_filename = None
            md5_filename = None
        with TempfileManager(args.tar_archive_dir) as tar_dir,\
            CacheManager(sha256_filename) as sha256_cache,\
            CacheManager(md5_filename) as md5_cache:  # noqa
            if args.only:
                distro = get_distro(args.ros_distro)
                for pkg in args.only:
                    if pkg in skip_keys:
                        warn("Package '%s' is in skip-keys list, skipping..." %
                             pkg)
                        continue
                    info("Regenerating package '%s'..." % pkg)
                    try:
                        regenerate_pkg(
                            overlay,
                            pkg,
                            distro,
                            preserve_existing,
                            tar_dir,
                            md5_cache,
                            sha256_cache,
                            skip_keys=skip_keys,
                        )
                    except KeyError:
                        err("No package to satisfy key '%s'" % pkg)
                        sys.exit(1)
                yoctoRecipe.generate_rosdistro_conf(
                    _repo, args.ros_distro,
                    overlay.get_file_revision_logs(
                        'files/{0}/cache.yaml'.format(args.ros_distro)),
                    distro.release_platforms, skip_keys)
                yoctoRecipe.generate_superflore_datetime_inc(
                    _repo, args.ros_distro, now)
                yoctoRecipe.generate_distro_cache(_repo, args.ros_distro)
                yoctoRecipe.generate_rosdep_resolve(_repo, args.ros_distro)
                yoctoRecipe.generate_newer_platform_components(
                    _repo, args.ros_distro)
                yoctoRecipe.generate_superflore_change_summary(
                    _repo, args.ros_distro, overlay.get_change_summary())
                # Commit changes and file pull request
                title = '{{{0}}} Sync to {0}-cache.yaml as of {1}\n'.format(
                    args.ros_distro, now)
                regen_dict = dict()
                regen_dict[args.ros_distro] = args.only
                delta = "Regenerated: '%s'\n" % args.only
                commit_msg = '\n'.join([
                    get_pr_text(
                        title + '\n' +
                        pr_comment.replace('**superflore**', 'superflore'),
                        markup=''), delta
                ])
                overlay.commit_changes(args.ros_distro, commit_msg)
                if args.dry_run:
                    save_pr(overlay, args.only, '', pr_comment, title=title)
                    sys.exit(0)
                file_pr(overlay,
                        delta,
                        '',
                        pr_comment,
                        distro=args.ros_distro,
                        title=title)
                ok('Successfully synchronized repositories!')
                sys.exit(0)

            for adistro in selected_targets:
                yoctoRecipe.reset()
                distro = get_distro(adistro)
                distro_installers, _, distro_changes =\
                    generate_installers(
                        distro,
                        overlay,
                        regenerate_pkg,
                        preserve_existing,
                        tar_dir,
                        md5_cache,
                        sha256_cache,
                        skip_keys,
                        skip_keys=skip_keys,
                        is_oe=True,
                    )
                total_changes[adistro] = distro_changes
                total_installers[adistro] = distro_installers
                yoctoRecipe.generate_rosdistro_conf(
                    _repo, args.ros_distro,
                    overlay.get_file_revision_logs(
                        'files/{0}/cache.yaml'.format(args.ros_distro)),
                    distro.release_platforms, skip_keys)
                yoctoRecipe.generate_superflore_datetime_inc(
                    _repo, args.ros_distro, now)
                yoctoRecipe.generate_distro_cache(_repo, args.ros_distro)
                yoctoRecipe.generate_rosdep_resolve(_repo, args.ros_distro)
                yoctoRecipe.generate_newer_platform_components(
                    _repo, args.ros_distro)
                yoctoRecipe.generate_superflore_change_summary(
                    _repo, args.ros_distro, overlay.get_change_summary())

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            clean_up()
            sys.exit(0)

        # remove duplicates
        delta = gen_delta_msg(total_changes, markup='')
        # Commit changes and file pull request
        title = '{{{0}}} Sync to {0}-cache.yaml as of {1}\n'.format(
            args.ros_distro, now)
        commit_msg = '\n'.join([
            get_pr_text(title + '\n' +
                        pr_comment.replace('**superflore**', 'superflore'),
                        markup=''), delta
        ])
        overlay.commit_changes(args.ros_distro, commit_msg)
        delta = gen_delta_msg(total_changes)
        if args.dry_run:
            info('Running in dry mode, not filing PR')
            save_pr(
                overlay,
                delta,
                '',
                pr_comment,
                title=title,
            )
            sys.exit(0)
        file_pr(overlay, delta, '', comment=pr_comment, title=title)
        clean_up()
        ok('Successfully synchronized repositories!')
Пример #12
0
def main():
    global overlay
    global preserve_existing

    parser = argparse.ArgumentParser('Deploy ROS packages into Gentoo Linux')
    parser.add_argument('--ros-distro',
                        help='regenerate packages for the specified distro',
                        type=str)
    parser.add_argument('--all',
                        help='regenerate all packages in all distros',
                        action="store_true")
    parser.add_argument('--dry-run',
                        help='run without filing a PR to remote',
                        action="store_true")
    parser.add_argument('--pr-only',
                        help='ONLY file a PR to remote',
                        action='store_true')
    parser.add_argument('--output-repository-path',
                        help='location of the Git repo',
                        type=str)
    parser.add_argument('--only',
                        nargs='+',
                        help='generate only the specified packages')

    args = parser.parse_args(sys.argv[1:])
    selected_targets = None
    if args.all:
        warn('"All" mode detected... This may take a while!')
        preserve_existing = False
    elif args.ros_distro:
        selected_targets = [args.ros_distro]
        preserve_existing = False
    elif args.dry_run and args.pr_only:
        parser.error('Invalid args! cannot dry-run and file PR')
    elif args.pr_only and not args.output_repository_path:
        parser.error('Invalid args! no repository specified')
    elif args.pr_only:
        try:
            with open('.pr-message.tmp', 'r') as msg_file:
                msg = msg_file.read().rstrip('\n')
            with open('.pr-title.tmp', 'r') as title_file:
                title = title_file.read().rstrip('\n')
        except OSError:
            err('Failed to open PR title/message file!')
            err('Please supply the %s and %s files' %
                ('.pr_message.tmp', '.pr_title.tmp'))
            raise
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            info('PR message:\n"%s"\n' % msg)
            info('PR title:\n"%s"\n' % title)
            prev_overlay.pull_request(msg, title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)
    if not selected_targets:
        selected_targets = active_distros
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output_repository_path is None
        overlay = RosOverlay(_repo, not args.output_repository_path)
        # generate installers
        total_installers = dict()
        total_broken = set()
        total_changes = dict()

        if args.only:
            for pkg in args.only:
                info("Regenerating package '%s'..." % pkg)
                regenerate_pkg(overlay, pkg, get_distro(args.ros_distro),
                               preserve_existing)
            # Commit changes and file pull request
            regen_dict = dict()
            regen_dict[args.ros_distro] = args.only
            overlay.regenerate_manifests(regen_dict)
            overlay.commit_changes(args.ros_distro)
            delta = "Regenerated: '%s'\n" % args.only
            if args.dry_run:
                info('Running in dry mode, not filing PR')
                title_file = open('.pr-title.tmp', 'w')
                title_file.write('rosdistro sync, {0}\n'.format(time.ctime()))
                pr_message_file = open('.pr-message.tmp', 'w')
                pr_message_file.write('%s\n%s\n' % (delta, ''))
                sys.exit(0)
            file_pr(overlay, delta, '')
            clean_up()
            ok('Successfully synchronized repositories!')
            sys.exit(0)

        for distro in selected_targets:
            distro_installers, distro_broken, distro_changes =\
                generate_installers(
                    distro_name=distro,
                    overlay=overlay,
                    gen_pkg_func=regenerate_pkg,
                    preserve_existing=preserve_existing
                )
            for key in distro_broken.keys():
                for pkg in distro_broken[key]:
                    total_broken.add(pkg)

            total_changes[distro] = distro_changes
            total_installers[distro] = distro_installers

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            clean_up()
            sys.exit(0)

        # remove duplicates
        inst_list = total_broken

        delta = "Changes:\n"
        delta += "========\n"

        if 'indigo' in total_changes and len(total_changes['indigo']) > 0:
            delta += "Indigo Changes:\n"
            delta += "---------------\n"

            for d in sorted(total_changes['indigo']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        if 'kinetic' in total_changes and len(total_changes['kinetic']) > 0:
            delta += "Kinetic Changes:\n"
            delta += "----------------\n"

            for d in sorted(total_changes['kinetic']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        if 'lunar' in total_changes and len(total_changes['lunar']) > 0:
            delta += "Lunar Changes:\n"
            delta += "--------------\n"

            for d in sorted(total_changes['lunar']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        missing_deps = ''

        if len(inst_list) > 0:
            missing_deps = "Missing Dependencies:\n"
            missing_deps += "=====================\n"
            for pkg in sorted(inst_list):
                missing_deps += " * [ ] {0}\n".format(pkg)

        # Commit changes and file pull request
        overlay.regenerate_manifests(total_installers)
        overlay.commit_changes(args.ros_distro)

        if args.dry_run:
            info('Running in dry mode, not filing PR')
            title_file = open('.pr-title.tmp', 'w')
            title_file.write('rosdistro sync, {0}\n'.format(time.ctime()))
            pr_message_file = open('.pr-message.tmp', 'w')
            pr_message_file.write('%s\n%s\n' % (delta, missing_deps))
            sys.exit(0)
        file_pr(overlay, delta, missing_deps)

        clean_up()
        ok('Successfully synchronized repositories!')
Пример #13
0
def generate_installers(
    distro_name,  # ros distro name
    overlay,  # repo instance
    gen_pkg_func,  # function to call for generating
    preserve_existing=True,  # don't regenerate if installer exists
    *args  # any aditional args for gen_pkg_func
):
    distro = get_distro(distro_name)
    pkg_names = get_package_names(distro)
    total = float(len(pkg_names[0]))
    borkd_pkgs = dict()
    changes = []
    installers = []
    bad_installers = []
    succeeded = 0
    failed = 0

    info("Generating installers for distro '%s'" % distro_name)
    for i, pkg in enumerate(sorted(pkg_names[0])):
        version = get_pkg_version(distro, pkg)
        percent = '%.1f' % (100 * (float(i) / total))
        try:
            current, bad_deps = gen_pkg_func(overlay, pkg, distro,
                                             preserve_existing, *args)
            if not current and bad_deps:
                # we are missing dependencies
                failed_msg = "{0}%: Failed to generate".format(percent)
                failed_msg += " installer for package '%s'!" % pkg
                err(failed_msg)
                borkd_pkgs[pkg] = bad_deps
                failed = failed + 1
                continue
            elif not current and preserve_existing:
                # don't replace the installer
                succeeded = succeeded + 1
                continue
            success_msg = 'Successfully generated installer for package'
            ok('{0}%: {1} \'{2}\'.'.format(percent, success_msg, pkg))
            succeeded = succeeded + 1
            changes.append('*{0} --> {1}*'.format(pkg, version))
            installers.append(pkg)
        except UnknownLicense as ul:
            err("{0}%: Unknown License '{1}'.".format(percent, str(ul)))
            bad_installers.append(pkg)
            failed = failed + 1
        except KeyError:
            failed_msg = 'Failed to generate installer'
            err("{0}%: {1} for package {2}!".format(percent, failed_msg, pkg))
            bad_installers.append(pkg)
            failed = failed + 1
    results = 'Generated {0} / {1}'.format(succeeded, failed + succeeded)
    results += ' for distro {0}'.format(distro_name)
    info("------ {0} ------\n".format(results))

    if len(borkd_pkgs) > 0:
        warn("Unresolved:")
        for broken in borkd_pkgs.keys():
            warn("{}:".format(broken))
            warn("  {}".format(borkd_pkgs[broken]))

    return installers, borkd_pkgs, changes
Пример #14
0
def main():
    global overlay
    global preserve_existing

    parser = argparse.ArgumentParser('Deploy ROS packages into Yocto Linux')
    parser.add_argument(
        '--ros-distro',
        help='regenerate packages for the specified distro',
        type=str
    )
    parser.add_argument(
        '--all',
        help='regenerate all packages in all distros',
        action="store_true"
    )
    parser.add_argument(
        '--output-repository-path',
        help='location of the Git repo',
        type=str
    )
    parser.add_argument(
        '--tar-archive-dir',
        help='location to store archived packages',
        type=str
    )
    selected_targets = active_distros
    args = parser.parse_args(sys.argv[1:])
    if args.all:
        warn('"All" mode detected... this may take a while!')
        preserve_existing = False
    elif args.ros_distro:
        warn('"{0}" distro detected...'.format(args.ros_distro))
        selected_targets = [args.ros_distro]
        preserve_existing = False
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output-repository_path is None
        overlay = RosMeta(_repo, not args.output_repository_path)
        # generate installers
        total_installers = dict()
        total_broken = set()
        total_changes = dict()

        with TempfileManager(args.tar_archive_dir) as tar_dir:
            for distro in selected_targets:
                distro_installers, distro_broken, distro_changes =\
                    generate_installers(
                        distro,
                        overlay,
                        regenerate_installer,
                        preserve_existing,
                        tar_dir
                    )
                for key in distro_broken.keys():
                    for pkg in distro_broken[key]:
                        total_broken.add(pkg)

                total_changes[distro] = distro_changes
                total_installers[distro] = distro_installers

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            sys.exit(0)

        # remove duplicates
        inst_list = total_broken

        delta = "Changes:\n"
        delta += "========\n"

        if 'indigo' in total_changes and len(total_changes['indigo']) > 0:
            delta += "Indigo Changes:\n"
            delta += "---------------\n"

            for d in sorted(total_changes['indigo']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        if 'kinetic' in total_changes and len(total_changes['kinetic']) > 0:
            delta += "Kinetic Changes:\n"
            delta += "----------------\n"

            for d in sorted(total_changes['kinetic']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        if 'lunar' in total_changes and len(total_changes['lunar']) > 0:
            delta += "Lunar Changes:\n"
            delta += "--------------\n"

            for d in sorted(total_changes['lunar']):
                delta += '* {0}\n'.format(d)
            delta += "\n"

        missing_deps = ''

        if len(inst_list) > 0:
            missing_deps = "Missing Dependencies:\n"
            missing_deps += "=====================\n"
            for pkg in sorted(inst_list):
                missing_deps += " * [ ] {0}\n".format(pkg)

        # Commit changes and file pull request
        overlay.commit_changes(args.ros_distro)
        file_pr(overlay, delta, missing_deps)
        ok('Successfully synchronized repositories!')
Пример #15
0
def main():
    overlay = None
    preserve_existing = True
    parser = get_parser('Deploy ROS packages into Gentoo Linux')
    args = parser.parse_args(sys.argv[1:])
    pr_comment = args.pr_comment
    selected_targets = None
    if args.all:
        warn('"All" mode detected... This may take a while!')
        preserve_existing = False
    elif args.ros_distro:
        selected_targets = [args.ros_distro]
        set_index_for_distro(args.ros_distro)
        preserve_existing = False
    elif args.dry_run and args.pr_only:
        parser.error('Invalid args! cannot dry-run and file PR')
    elif args.pr_only and not args.output_repository_path:
        parser.error('Invalid args! no repository specified')
    elif args.pr_only:
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            msg, title = load_pr()
            prev_overlay.pull_request(msg, title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)
    if not selected_targets:
        selected_targets = active_distros + ros2_distros
    repo_org = 'ros'
    repo_name = 'ros-overlay'
    if args.upstream_repo:
        repo_org, repo_name = url_to_repo_org(args.upstream_repo)
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output_repository_path is None
        overlay = RosOverlay(
            _repo,
            not args.output_repository_path,
            org=repo_org,
            repo=repo_name
        )
        if not preserve_existing and not args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator began regeneration of all'
                ' packages from ROS distro %s from ROS-Overlay commit %s.' % (
                    selected_targets,
                    overlay.repo.get_last_hash()
                )
            )
        elif not args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator ran update from ROS-Overlay ' +
                'commit %s.' % (overlay.repo.get_last_hash())
            )
        # generate installers
        total_installers = dict()
        total_broken = set()
        total_changes = dict()
        if args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator began regeneration of ' +
                'package(s) %s from commit %s.' % (
                    args.only,
                    overlay.repo.get_last_hash()
                )
            )
            for pkg in args.only:
                info("Regenerating package '%s'..." % pkg)
                try:
                    regenerate_pkg(
                        overlay,
                        pkg,
                        get_distro(args.ros_distro),
                        preserve_existing
                    )
                except KeyError:
                    err("No package to satisfy key '%s'" % pkg)
                    sys.exit(1)
            # Commit changes and file pull request
            regen_dict = dict()
            regen_dict[args.ros_distro] = args.only
            overlay.regenerate_manifests(regen_dict)
            overlay.commit_changes(args.ros_distro)
            if args.dry_run:
                save_pr(
                    overlay, args.only, missing_deps=None, comment=pr_comment
                )
                sys.exit(0)
            delta = "Regenerated: '%s'\n" % args.only
            file_pr(overlay, delta, '', pr_comment)
            ok('Successfully synchronized repositories!')
            sys.exit(0)

        for distro in selected_targets:
            set_index_for_distro(distro)
            distro_installers, distro_broken, distro_changes =\
                generate_installers(
                    distro_name=distro,
                    overlay=overlay,
                    gen_pkg_func=regenerate_pkg,
                    preserve_existing=preserve_existing
                )
            for key in distro_broken.keys():
                for pkg in distro_broken[key]:
                    total_broken.add(pkg)

            total_changes[distro] = distro_changes
            total_installers[distro] = distro_installers

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            clean_up()
            sys.exit(0)

        # remove duplicates
        delta = gen_delta_msg(total_changes)
        missing_deps = gen_missing_deps_msg(total_broken)

        # Commit changes and file pull request
        overlay.regenerate_manifests(total_installers)
        overlay.commit_changes(args.ros_distro)

        if args.dry_run:
            info('Running in dry mode, not filing PR')
            save_pr(
                overlay, delta, missing_deps=missing_deps, comment=pr_comment
            )
            sys.exit(0)
        file_pr(overlay, delta, missing_deps, comment=pr_comment)

        clean_up()
        ok('Successfully synchronized repositories!')
Пример #16
0
def main():
    overlay = None
    preserve_existing = True
    parser = get_parser('Deploy ROS packages into Gentoo Linux')
    args = parser.parse_args(sys.argv[1:])
    pr_comment = args.pr_comment
    skip_keys = args.skip_keys or []
    selected_targets = None
    if not args.dry_run:
        if 'SUPERFLORE_GITHUB_TOKEN' not in os.environ:
            raise NoGitHubAuthToken()
    if args.pr_only:
        if args.dry_run:
            parser.error('Invalid args! cannot dry-run and file PR')
        if not args.output_repository_path:
            parser.error('Invalid args! no repository specified')
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            msg, title = load_pr()
            prev_overlay.pull_request(msg, title=title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)
    elif args.all:
        warn('"All" mode detected... This may take a while!')
        preserve_existing = False
    elif args.ros_distro:
        warn('"{0}" distro detected...'.format(args.ros_distro))
        selected_targets = [args.ros_distro]
        preserve_existing = False
    elif args.only:
        parser.error('Invalid args! --only requires specifying --ros-distro')
    if not selected_targets:
        selected_targets = get_distros_by_status('active')
    repo_org = 'ros'
    repo_name = 'ros-overlay'
    if args.upstream_repo:
        repo_org, repo_name = url_to_repo_org(args.upstream_repo)
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output_repository_path is None
        overlay = RosOverlay(
            _repo,
            not args.output_repository_path,
            org=repo_org,
            repo=repo_name,
            from_branch=args.upstream_branch,
            new_branch=(not args.no_branch),
        )
        if not preserve_existing and not args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator began regeneration of all'
                ' packages from ROS distro %s from ROS-Overlay commit %s.' %
                (selected_targets, overlay.repo.get_last_hash()))
        elif not args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator ran update from ROS-Overlay ' +
                'commit %s.' % (overlay.repo.get_last_hash()))
        # generate installers
        total_installers = dict()
        total_broken = set()
        total_changes = dict()
        if args.only:
            pr_comment = pr_comment or (
                'Superflore ebuild generator began regeneration of ' +
                'package(s) %s from commit %s.' %
                (args.only, overlay.repo.get_last_hash()))
            missing_depends = set()
            to_commit = set()
            will_file_pr = False
            for pkg in args.only:
                if pkg in skip_keys:
                    warn("Package '%s' is in skip-keys list, skipping..." %
                         pkg)
                    continue
                info("Regenerating package '%s'..." % pkg)
                try:
                    ebuild, deps, version = regenerate_pkg(
                        overlay, pkg, get_distro(args.ros_distro),
                        preserve_existing)
                    if not ebuild:
                        for dep in deps:
                            missing_depends.add(dep)
                except KeyError:
                    err("No package to satisfy key '%s'" % pkg)
                    continue
                if ebuild:
                    to_commit.add(pkg)
                    will_file_pr = True
            # if no packages succeeded, exit with error
            if not will_file_pr:
                err("No packages generated successfully, exiting.")
                sys.exit(1)
            # Commit changes and file pull request
            regen_dict = dict()
            regen_dict[args.ros_distro] = to_commit
            overlay.regenerate_manifests(regen_dict)
            overlay.commit_changes(args.ros_distro)
            if args.dry_run:
                save_pr(overlay,
                        args.only,
                        missing_deps=gen_missing_deps_msg(missing_depends),
                        comment=pr_comment)
                sys.exit(0)
            delta = "Regenerated: '%s'\n" % args.only
            file_pr(overlay, delta, gen_missing_deps_msg(missing_depends),
                    pr_comment)
            ok('Successfully synchronized repositories!')
            sys.exit(0)

        for distro in selected_targets:
            distro_installers, distro_broken, distro_changes =\
                generate_installers(
                    get_distro(distro),
                    overlay=overlay,
                    gen_pkg_func=regenerate_pkg,
                    preserve_existing=preserve_existing,
                    skip_keys=skip_keys,
                )
            for key in distro_broken.keys():
                for pkg in distro_broken[key]:
                    total_broken.add(pkg)

            total_changes[distro] = distro_changes
            total_installers[distro] = distro_installers

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            clean_up()
            sys.exit(0)

        # remove duplicates
        delta = gen_delta_msg(total_changes)
        missing_deps = gen_missing_deps_msg(total_broken)

        # Commit changes and file pull request
        overlay.regenerate_manifests(total_installers)
        overlay.commit_changes('all' if args.all else args.ros_distro)

        if args.dry_run:
            info('Running in dry mode, not filing PR')
            save_pr(overlay,
                    delta,
                    missing_deps=missing_deps,
                    comment=pr_comment)
            sys.exit(0)
        file_pr(overlay, delta, missing_deps, comment=pr_comment)

        clean_up()
        ok('Successfully synchronized repositories!')
Пример #17
0
def main():
    overlay = None
    preserve_existing = True
    parser = get_parser('Deploy ROS packages into Yocto Linux')
    parser.add_argument(
        '--tar-archive-dir',
        help='location to store archived packages',
        type=str
    )

    args = parser.parse_args(sys.argv[1:])
    pr_comment = args.pr_comment
    selected_targets = None

    if args.all:
        warn('"All" mode detected... this may take a while!')
        preserve_existing = False

    elif args.ros_distro:
        warn('"{0}" distro detected...'.format(args.ros_distro))
        selected_targets = [args.ros_distro]
        preserve_existing = False

    elif args.dry_run and args.pr_only:
        parser.error('Invalid args! cannot dry-run and file PR')

    elif args.pr_only and not args.output_repository_path:
        parser.error('Invalid args! no repository specified')

    elif args.pr_only:
        try:
            prev_overlay = RepoInstance(args.output_repository_path, False)
            msg, title = load_pr()
            prev_overlay.pull_request(msg, title)
            clean_up()
            sys.exit(0)
        except Exception as e:
            err('Failed to file PR!')
            err('reason: {0}'.format(e))
            sys.exit(1)


    if not selected_targets:
        selected_targets = ros1_distros + ros2_distros

    repo_org = 'lgsvl'
    repo_name = 'meta-ros2'

    if args.upstream_repo:
        repo_org, repo_name = url_to_repo_org(args.upstream_repo)

    # open cached tar file if it exists
    with TempfileManager(args.output_repository_path) as _repo:
        if not args.output_repository_path:
            # give our group write permissions to the temp dir
            os.chmod(_repo, 17407)
        # clone if args.output-repository_path is None
        overlay = RosMeta(
            _repo,
            not args.output_repository_path,
            org=repo_org,
            repo=repo_name
        )

        if not args.only:
            pr_comment = pr_comment or (
                'Superflore yocto generator began regeneration of all '
                'packages form ROS distribution(s) %s on Meta-ROS from '
                'commit %s.' % (
                    selected_targets,
                    overlay.repo.get_last_hash()
                )
            )
        else:
            pr_comment = pr_comment or (
                'Superflore yocto generator began regeneration of package(s)'
                ' %s from ROS distro %s from Meta-ROS from commit %s.' % (
                    args.only,
                    args.ros_distro,
                    overlay.repo.get_last_hash()
                )
            )

        # generate installers
        total_installers = dict()
        total_broken = set()
        total_changes = dict()
        if args.tar_archive_dir:
            sha256_filename = '%s/sha256_cache.pickle' % args.tar_archive_dir
            md5_filename = '%s/md5_cache.pickle' % args.tar_archive_dir
        else:
            sha256_filename = None
            md5_filename = None
        with TempfileManager(args.tar_archive_dir) as tar_dir,\
            CacheManager(sha256_filename) as sha256_cache,\
            CacheManager(md5_filename) as md5_cache:  # noqa
            if args.only:
                for pkg in args.only:
                    info("Regenerating package '%s'..." % pkg)
                    try:
                        regenerate_installer(
                            overlay,
                            pkg,
                            get_distro(args.ros_distro),
                            preserve_existing,
                            tar_dir,
                            md5_cache,
                            sha256_cache
                        )
                    except KeyError:
                        err("No package to satisfy key '%s'" % pkg)
                        sys.exit(1)

                # Commit changes and file pull request
                regen_dict = dict()
                regen_dict[args.ros_distro] = args.only
                overlay.commit_changes(args.ros_distro)
                if args.dry_run:
                    save_pr(overlay, args.only, None, pr_comment)
                    sys.exit(0)

                delta = "Regenerated: '%s'\n" % args.only
                file_pr(overlay, delta, '', pr_comment, distro=args.ros_distro)
                ok('Successfully synchronized repositories!')
                sys.exit(0)

            for distro in selected_targets:
                distro_installers, distro_broken, distro_changes =\
                    generate_installers(
                        distro,
                        overlay,
                        regenerate_installer,
                        preserve_existing,
                        tar_dir,
                        md5_cache,
                        sha256_cache
                    )
                for key in distro_broken.keys():
                    for pkg in distro_broken[key]:
                        total_broken.add(pkg)
                total_changes[distro] = distro_changes
                total_installers[distro] = distro_installers

        num_changes = 0
        for distro_name in total_changes:
            num_changes += len(total_changes[distro_name])

        if num_changes == 0:
            info('ROS distro is up to date.')
            info('Exiting...')
            clean_up()
            sys.exit(0)

        # remove duplicates
        delta = gen_delta_msg(total_changes)
        missing_deps = gen_missing_deps_msg(total_broken)

        # Commit changes and file pull request
        overlay.commit_changes(args.ros_distro)

        if args.dry_run:
            info('Running in dry mode, not filing PR')
            save_pr(overlay, delta, missing_deps, pr_comment)
            clean_up()
            sys.exit(0)

        file_pr(overlay, delta, missing_deps, pr_comment)
        clean_up()
        ok('Successfully synchronized repositories!')