Example #1
0
 def generate_superflore_datetime_inc(basepath, dist):
     datetime_dir = '{}/conf/ros-distro/include/{}/'.format(basepath, dist)
     datetime_file_name = 'generated-superflore-datetime.inc'
     datetime_path = '{}{}'.format(datetime_dir, datetime_file_name)
     try:
         make_dir(datetime_dir)
         with open(datetime_path, 'w') as datetime_file:
             datetime_file.write('# {}/{}\n'.format(
                 dist, datetime_file_name))
             datetime_file.write('# Generated by superflore -- DO NOT EDIT')
             datetime_file.write(
                 ' (except ROS_DISTRO_METADATA_VERSION_REVISION)\n#\n')
             datetime_file.write(
                 '# Copyright ' + strftime("%Y", gmtime())
                 + ' Open Source Robotics Foundation\n\n')
             datetime_file.write(
                 '# The start time, in UTC, of the last superflore run that'
                 + ' resulted in a change to the generated files. The date'
                 + ' portion is used as\n# the second version field of '
                 + 'ROS_DISTRO_METADATA_VERSION prior to the first release'
                 + ' of a ROS_DISTRO.\n')
             now = datetime.utcnow().strftime('%Y%m%d%H%M%S')
             datetime_file.write(
                 'ROS_SUPERFLORE_GENERATION_DATETIME = "{}"'.format(now))
             ok('Wrote {0}'.format(datetime_path))
     except OSError as e:
         err('Failed to write SuperFlore datetime {} to disk! {}'.format(
             datetime_path, e))
         raise e
Example #2
0
 def generate_superflore_datetime_inc(basepath, dist, now):
     datetime_dir = '{0}/meta-ros{1}-{2}/conf/ros-distro/include/{2}/' \
         'generated/'.format(
             basepath, yoctoRecipe._get_ros_version(dist), dist)
     datetime_file_name = 'superflore-datetime.inc'
     datetime_path = '{}{}'.format(datetime_dir, datetime_file_name)
     try:
         make_dir(datetime_dir)
         with open(datetime_path, 'w') as datetime_file:
             datetime_file.write('# {}/generated/{}\n'.format(
                 dist, datetime_file_name))
             datetime_file.write('# Generated by superflore -- DO NOT EDIT')
             datetime_file.write(
                 '\n#\n# Copyright Open Source Robotics Foundation\n\n')
             datetime_file.write(
                 '\n# The time, in UTC, associated with the last superflore'
                 +
                 ' run that resulted in a change to the generated files.' +
                 ' The date portion is\n# used as the third version field' +
                 ' of ROS_DISTRO_METADATA_VERSION prior to the first' +
                 ' release of a ROS_DISTRO.\n')
             datetime_file.write(
                 'ROS_SUPERFLORE_GENERATION_DATETIME = "{}"\n'.format(now))
             ok('Wrote {0}'.format(datetime_path))
     except OSError as e:
         err('Failed to write SuperFlore datetime {} to disk! {}'.format(
             datetime_path, e))
         raise e
Example #3
0
def regenerate_pkg(overlay, pkg, distro, preserve_existing=False):
    version = get_pkg_version(distro, pkg)
    ebuild_name =\
        '/ros-{0}/{1}/{1}-{2}.ebuild'.format(distro.name, pkg, version)
    ebuild_name = overlay.repo.repo_dir + ebuild_name
    patch_path = '/ros-{}/{}/files'.format(distro.name, pkg)
    patch_path = overlay.repo.repo_dir + patch_path
    has_patches = os.path.exists(patch_path)
    pkg_names = get_package_names(distro)[0]

    if pkg not in pkg_names:
        raise RuntimeError("Unknown package '%s'" % (pkg))
    # otherwise, remove a (potentially) existing ebuild.
    existing = glob.glob('{0}/ros-{1}/{2}/*.ebuild'.format(
        overlay.repo.repo_dir, distro.name, pkg))
    if preserve_existing and os.path.isfile(ebuild_name):
        ok("ebuild for package '%s' up to date, skipping..." % pkg)
        return None, []
    elif existing:
        overlay.repo.remove_file(existing[0])
        manifest_file = '{0}/ros-{1}/{2}/Manifest'.format(
            overlay.repo.repo_dir, distro.name, pkg)
        overlay.repo.remove_file(manifest_file)
    try:
        current = gentoo_installer(distro, pkg, has_patches)
        current.ebuild.name = pkg
    except Exception as e:
        err('Failed to generate installer for package {}!'.format(pkg))
        raise e
    try:
        ebuild_text = current.ebuild_text()
        metadata_text = current.metadata_text()
    except UnresolvedDependency:
        dep_err = 'Failed to resolve required dependencies for'
        err("{0} package {1}!".format(dep_err, pkg))
        unresolved = current.ebuild.get_unresolved()
        for dep in unresolved:
            err(" unresolved: \"{}\"".format(dep))
        return None, current.ebuild.get_unresolved()
    except KeyError as ke:
        err("Failed to parse data for package {}!".format(pkg))
        raise ke
    make_dir("{}/ros-{}/{}".format(overlay.repo.repo_dir, distro.name, pkg))
    success_msg = 'Successfully generated installer for package'
    ok('{0} \'{1}\'.'.format(success_msg, pkg))

    try:
        ebuild_file = '{0}/ros-{1}/{2}/{2}-{3}.ebuild'.format(
            overlay.repo.repo_dir, distro.name, pkg, version)
        ebuild_file = open(ebuild_file, "w")
        metadata_file = '{0}/ros-{1}/{2}/metadata.xml'.format(
            overlay.repo.repo_dir, distro.name, pkg)
        metadata_file = open(metadata_file, "w")
        ebuild_file.write(ebuild_text)
        metadata_file.write(metadata_text)
    except Exception as e:
        err("Failed to write ebuild/metadata to disk!")
        raise e
    return current, []
Example #4
0
 def test_mkdir(self):
     """Tests the make directory function"""
     with TempfileManager(None) as temp_dir:
         created = '%s/test' % temp_dir
         make_dir(created)
         self.assertTrue(os.path.isdir(created))
         # try and create the directory again, should pass
         make_dir(created)
         self.assertTrue(os.path.isdir(created))
Example #5
0
 def generate_newer_platform_components(basepath, distro):
     newer_sys_comps_dir = '{0}/meta-ros{1}-{2}/files/{2}/' \
                           'generated/'.format(
                               basepath,
                               yoctoRecipe._get_ros_version(distro), distro)
     newer_sys_comps_path = '{0}newer-platform-components.list'.format(
         newer_sys_comps_dir)
     ros_version = yoctoRecipe._get_ros_version(distro)
     str_distro = 'ros' if ros_version == 1 else 'ros{}'.format(ros_version)
     args1_wget = ['wget', '-O', '-', 'http://packages.ros.org/'
                   + str_distro
                   + '/ubuntu/dists/bionic/main/source/Sources.gz']
     args2_gunzip = ['gunzip', '-']
     args3_grep = ['grep', '-E', '^(Package|Version|Build-Depends)']
     args4_awk = ['awk', '$1 ~ /^Package:/ && $2 !~ /^ros-/ '
                  + '{ printf "%s;", $2; getline; '
                  + 'printf "%s;", $2; getline; '
                  + 'gsub(/Build-Depends: /, ""); gsub(/, /, ","); print}']
     args5_sort = ['sort', '-t', ';', '-k', '1,1']
     try:
         make_dir(newer_sys_comps_dir)
         wget = Popen(args1_wget, stdout=PIPE, stderr=DEVNULL)
         gunzip = Popen(args2_gunzip, stdin=wget.stdout,
                        stdout=PIPE, stderr=DEVNULL)
         grep = Popen(args3_grep, stdin=gunzip.stdout,
                      stdout=PIPE, stderr=DEVNULL)
         awk = Popen(args4_awk, stdin=grep.stdout,
                     stdout=PIPE, stderr=DEVNULL)
         sort = Popen(args5_sort, env={'LC_ALL': 'C'},
                      stdin=awk.stdout, stdout=PIPE, stderr=DEVNULL)
         cmds = [wget, gunzip, grep, awk]
         # Allow previous process to receive a SIGPIPE
         # if the next one in the pipeline exits.
         for cmd in cmds:
             cmd.stdout.close()
         # Run the pipeline and collect the output
         txt_output = sort.communicate()[0].decode()
         # Consume the return value of the other processes
         for cmd in cmds:
             cmd.wait()
         cmds.append(sort)
         if any([cmd.returncode for cmd in cmds]):
             errors = ['{}[{}]'.format(cmd.args[0], cmd.returncode)
                       for cmd in cmds]
             raise RuntimeError('Error codes ' + ' '.join(errors))
         with open(newer_sys_comps_path, 'w') as newer_sys_comps_file:
             newer_sys_comps_file.write(
                 '# {}/newer-platform-components.list\n'.format(distro))
             newer_sys_comps_file.write(txt_output)
             ok('Wrote {0}'.format(newer_sys_comps_path))
     except (OSError, RuntimeError) as e:
         err('Failed to write {0} to disk! {1}'.format(
             newer_sys_comps_path, e))
         raise e
Example #6
0
def regenerate_installer(overlay, pkg, distro, preserve_existing, tar_dir):
    make_dir("{0}/recipes-ros-{1}".format(overlay.repo.repo_dir, distro.name))
    version = get_pkg_version(distro, pkg)
    pkg_names = get_package_names(distro)[0]

    if pkg not in pkg_names:
        raise RuntimeError("Unknown package '%s'" % pkg)

    # check for an existing recipe
    existing = glob.glob('{0}/recipes-ros-{1}/{2}/*.bb'.format(
        overlay.repo.repo_dir, distro.name, pkg))

    if preserve_existing and existing:
        ok("recipe for package '%s' up to date, skpping..." % pkg)
        return None, []
    elif existing:
        overlay.repo.remove_file(existing[0])
    try:
        current = oe_installer(distro, pkg, tar_dir)
        current.recipe.name = pkg.replace('_', '-')
    except Exception as e:
        err('Failed to generate installer for package {}!'.format(pkg))
        raise e
    try:
        recipe_text = current.recipe_text()
    except UnresolvedDependency:
        dep_err = 'Failed to resolve required dependencies for'
        err("{0} package {1}!".format(dep_err, pkg))
        unresolved = current.recipe.get_unresolved()
        for dep in unresolved:
            err(" unresolved: \"{}\"".format(dep))
        return None, current.recipe.get_unresolved()
    except NoPkgXml:
        err("Could not fetch pkg!")
        return None, []
    except KeyError as ke:
        err("Failed to parse data for package {}!".format(pkg))
        raise ke
    make_dir("{0}/recipes-ros-{1}/{2}".format(overlay.repo.repo_dir,
                                              distro.name,
                                              pkg.replace('_', '-')))
    success_msg = 'Successfully generated installer for package'
    ok('{0} \'{1}\'.'.format(success_msg, pkg))
    recipe_name = '{0}/recipes-ros-{1}/{2}/{2}_{3}.bb'.format(
        overlay.repo.repo_dir, distro.name, pkg.replace('_', '-'), version)
    try:
        with open('{0}'.format(recipe_name), "w") as recipe_file:
            recipe_file.write(recipe_text)
    except Exception as e:
        err("Failed to write recipe to disk!")
        raise e
    return current, []
Example #7
0
 def generate_superflore_change_summary(basepath, distro, change_summary):
     change_summary_dir = '{0}/files/{1}/'.format(basepath, distro)
     change_summary_path = '{0}superflore-change-summary.txt'.format(
         change_summary_dir)
     try:
         make_dir(change_summary_dir)
         with open(change_summary_path, 'w') as change_summary_file:
             change_summary_file.write(
                 '{}/superflore-change-summary.txt\n'.format(distro))
             change_summary_file.write(change_summary)
             ok('Wrote {0}'.format(change_summary_path))
     except OSError as e:
         err('Failed to write change summary {} to disk! {}'.format(
             change_summary_path, e))
         raise e
Example #8
0
    def generate_distro_cache(basepath, distro, skip_keys=[]):
        distro_cache_dir = '{0}/files/{1}/'.format(basepath, distro)
        distro_cache_path = '{0}cache.yaml'.format(distro_cache_dir)
        try:
            index = get_index(get_index_url())
            yaml_str = get_distribution_cache_string(index, distro)
            make_dir(distro_cache_dir)
            with open(distro_cache_path, 'w') as distro_cache_file:
                distro_cache_file.write('# {}/cache.yaml\n'.format(distro))
                distro_cache_file.write(yaml_str)
                ok('Wrote {0}'.format(distro_cache_path))
        except OSError as e:
            err('Failed to write distro cache {} to disk! {}'.format(
                distro_cache_path, e))
            raise e
        # Generate a diff'able cache file
        distro_cache_diff_path = '{}cache.diffme'.format(distro_cache_dir)
        try:

            def replace_all_patterns(d, text):
                for k, v in d.items():
                    text = re.sub(k, v, text, flags=re.M)
                return text

            replacement_table = {
                r"{([^ }][^ }]*)}": r'[[\1]]',
                r"{": r"{\n",
                r"}": r"\n}",
                r"\[\[": r"{",
                r"\]\]": r"}",
                r", ": r",\n",
                r"^    ": r"-----\n",
                r"<version>[^<]*</version>": r"",
                r"><": r">\n<",
                r"^  ": r"-----\n",
                r"^(source_repo_package_xmls:)": r"-----\n\1",
            }
            with open(distro_cache_diff_path, 'w') as distro_cache_diff_file:
                distro_cache_diff_file.write(
                    '# {}/cache.diffme\n'.format(distro))
                yaml_str = replace_all_patterns(replacement_table, yaml_str)
                distro_cache_diff_file.write(yaml_str)
                ok('Wrote {0}'.format(distro_cache_diff_path))
        except OSError as e:
            err('Failed to write diffme distro cache {} to disk! {}'.format(
                distro_cache_diff_path, e))
            raise e
Example #9
0
 def generate_rosdep_resolve(basepath, distro):
     rosdep_resolve_dir = '{0}/files/{1}/'.format(basepath, distro)
     rosdep_resolve_path = '{0}rosdep-resolve.yaml'.format(
         rosdep_resolve_dir)
     try:
         make_dir(rosdep_resolve_dir)
         with open(rosdep_resolve_path, 'w') as rosdep_resolve_file:
             rosdep_resolve_file.write(
                 '# {}/rosdep-resolve.yaml\n'.format(distro))
             cache_as_dict_of_list = {
                 k: list(v) for k, v in yoctoRecipe.rosdep_cache.items()}
             rosdep_resolve_file.write(yaml.dump(
                 cache_as_dict_of_list, default_flow_style=False))
             ok('Wrote {0}'.format(rosdep_resolve_path))
     except OSError as e:
         err('Failed to write rosdep resolve cache {} to disk! {}'.format(
             rosdep_resolve_path, e))
         raise e
Example #10
0
    def generate_ros_distro_inc(basepath,
                                distro,
                                version,
                                platforms,
                                skip_keys=[]):
        conf_dir = '{0}/meta-ros{1}-{2}/conf/ros-distro/include/{2}/' \
                    'generated/'.format(
                        basepath, yoctoRecipe._get_ros_version(distro), distro)
        conf_file_name = 'superflore-ros-distro.inc'
        conf_path = '{}{}'.format(conf_dir, conf_file_name)
        try:
            make_dir(conf_dir)
            with open(conf_path, 'w') as conf_file:
                conf_file.write('# {}/generated/{}\n'.format(
                    distro, conf_file_name))
                conf_file.write('# Generated by superflore -- DO NOT EDIT')
                conf_file.write(
                    ' (except ROS_DISTRO_METADATA_VERSION_REVISION)\n#\n')
                conf_file.write(
                    '# Copyright Open Source Robotics Foundation\n\n')
                conf_file.write(
                    '# Increment every time meta-ros is released because of ' +
                    'a manually created change, ie, NOT as a result of a ' +
                    'superflore run (which\n# resets it to "0").')
                conf_file.write(
                    '\nROS_DISTRO_METADATA_VERSION_REVISION = "0"\n')
                conf_file.write(
                    '\nROS_SUPERFLORE_PROGRAM_VERSION = "{}"\n'.format(
                        get_superflore_version()))
                conf_file.write('ROS_SUPERFLORE_GENERATION_SCHEME = "2"\n')
                ros_version = yoctoRecipe._get_ros_version(distro)
                conf_file.write(
                    '\nROS_DISTRO_TYPE = "ros{}"\n'.format(ros_version))
                conf_file.write('ROS_VERSION = "{}"\n'.format(ros_version))
                conf_file.write('# DO NOT OVERRIDE ROS_PYTHON_VERSION\n')
                ros_python_version = 3
                if ros_version == 1:
                    ros_python_version = 2
                conf_file.write(
                    'ROS_PYTHON_VERSION = "{}"\n\n'.format(ros_python_version))
                oe_skip_keys = map(
                    lambda skip_key: yoctoRecipe.convert_to_oe_name(skip_key),
                    skip_keys)
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATION_SKIP_LIST', oe_skip_keys) +
                    '\n')
                conf_file.write(
                    '# Superflore was unable to generate recipes for these ' +
                    'packages, eg, because their repositories are not on ' +
                    'GitHub.\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATION_NOT_POSSIBLE',
                        yoctoRecipe.not_generated_recipes) + '\n')
                conf_file.write(
                    '# Number of commits that will be returned by '
                    '"git log meta-ros{0}-{1}/files/{1}/generated/'
                    'cache.yaml" when the\n# generated files are committed. '
                    'This is used for the fourth version field of '
                    'DISTRO_VERSION.\n'.format(
                        yoctoRecipe._get_ros_version(distro), distro))
                version = 1 if not version else len(version.splitlines()) + 1
                conf_file.write(
                    'ROS_NUM_CACHE_YAML_COMMITS = "{}"'.format(version) +
                    '\n\n')
                conf_file.write(
                    '# Iterated values of ' +
                    'ROS_DISTRO-cache.distribution_file.release_platforms.' +
                    '<LINUX-DISTRO>.[ <NAME> ... ] .\n')
                release_platforms = []
                for p in sorted(platforms.items()):
                    for release in p[1]:
                        release_platforms.append(p[0] + '-' + release)
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_DISTRO_RELEASE_PLATFORMS', release_platforms) +
                    '\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_RECIPES',
                        yoctoRecipe.generated_recipes.keys()) + '\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_RECIPE_BASENAMES_WITH_COMPONENT',
                        [(yoctoRecipe.max_component_name - len(component)) *
                         ' ' + component + '/' + recipe + '_' + version
                         for recipe, (version, component) in
                         yoctoRecipe.generated_recipes.items()],
                        key=lambda recipe: recipe.split('/')[1].split('_')[0]))
                conf_file.write(
                    '\n# What\'s built by packagegroup-ros-world. Does not ' +
                    'include packages that appear solely in ' +
                    'ROS_SUPERFLORE_GENERATED_BUILDTOOLS\n# (with a -native' +
                    ' suffix) or ROS_SUPERFLORE_GENERATED_TESTS.\n')
                recipes_set = set(yoctoRecipe.generated_recipes.keys())
                test_deps = set(
                    map(
                        lambda test_dep: yoctoRecipe.convert_to_oe_name(
                            test_dep), yoctoRecipe.generated_test_deps -
                        yoctoRecipe.generated_non_test_deps))
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES',
                        recipes_set - yoctoRecipe.generated_native_recipes -
                        test_deps))
                conf_file.write(
                    '\n# Packages found in the <buildtool_depend> and ' +
                    '<buildtool_export_depend> items, ie, ones for which a ' +
                    '-native is built. Does not\n# include those found in ' +
                    'the ROS_EXEC_DEPENDS values in the recipes of build ' +
                    'tools.\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_BUILDTOOLS_%s' %
                        distro.upper(), yoctoRecipe.generated_native_recipes) +
                    '\n')
                conf_file.write('ROS_SUPERFLORE_GENERATED_BUILDTOOLS_append ='
                                ' " ${ROS_SUPERFLORE_GENERATED_BUILDTOOLS_%s}"'
                                '\n\n' % distro.upper())
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_PLATFORM_PACKAGE_DEPENDENCIES',
                        yoctoRecipe.platform_deps))
                conf_file.write(
                    '\n# Packages found only in <test_depend> items. Does not'
                    + ' include those found only in the ROS_*_DEPENDS of ' +
                    'recipes of tests.\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_TESTS', test_deps) + '\n')
                conf_file.write(
                    yoctoRecipe.generate_multiline_variable(
                        'ROS_SUPERFLORE_GENERATED_RECIPES_FOR_COMPONENTS',
                        yoctoRecipe.generated_components))
                conf_file.write(
                    '\n# Platform packages without a OE-RECIPE@OE-LAYER' +
                    ' mapping in base.yaml, python.yaml, or ruby.yaml. Until' +
                    ' they are added, override\n# the settings in' +
                    ' ros-distro.inc .\n')
                """
                Drop trailing "}" so that "..._foo-native" sorts after
                "..._foo".
                """
                unresolved = [
                    p[0:-1] for p in yoctoRecipe.platform_deps
                    if p.startswith(UNRESOLVED_PLATFORM_PKG_REFERENCE_PREFIX)
                ]
                for p in sorted(unresolved):
                    """
                    PN is last underscore-separated field. NB the trailing '}'
                    has already been removed.
                    """
                    pn = p.split('_')[-1]
                    conf_file.write(UNRESOLVED_PLATFORM_PKG_PREFIX + pn +
                                    ' = "UNRESOLVED-' + pn + '"\n')

                ok('Wrote {0}'.format(conf_path))
        except OSError as e:
            err('Failed to write conf {} to disk! {}'.format(conf_path, e))
            raise e
Example #11
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
Example #12
0
def regenerate_pkg(overlay, pkg, distro, preserve_existing, srcrev_cache,
                   skip_keys):
    pkg_names = get_package_names(distro)[0]
    if pkg not in pkg_names:
        yoctoRecipe.not_generated_recipes.add(pkg)
        raise RuntimeError("Unknown package '%s'" % pkg)
    try:
        version = get_pkg_version(distro, 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(
        distro.release_packages[pkg].repository_name)
    recipe = yoctoRecipe.convert_to_oe_name(pkg)
    # check for an existing recipe
    prefix = '{0}/meta-ros{1}-{2}/generated-recipes/{3}/{4}'.format(
        repo_dir,
        yoctoRecipe._get_ros_version(distro.name),
        distro.name,
        component_name,
        recipe,
    )
    existing = glob.glob('{}_*.bb'.format(prefix))
    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:
        existing = existing[0]
        overlay.repo.remove_file(existing, True)
        idx_version = existing.rfind('_') + len('_')
        previous_version = existing[idx_version:].rstrip('.bb')
    try:
        current = oe_recipe(distro, 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(distro.name), distro.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}/' \
        'ros{1}-{4}_{5}.bb'.format(
            repo_dir,
            yoctoRecipe._get_ros_version(distro.name),
            distro.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['ros{0}-{1}'.format(
                yoctoRecipe._get_ros_version(distro.name),
                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
Example #13
0
def regenerate_pkg(overlay, pkg, distro, preserve_existing, tar_dir, md5_cache,
                   sha256_cache, skip_keys):
    pkg_names = get_package_names(distro)[0]
    if pkg not in pkg_names:
        yoctoRecipe.not_generated_recipes.add(pkg)
        raise RuntimeError("Unknown package '%s'" % pkg)
    try:
        version = get_pkg_version(distro, 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(
        distro.release_packages[pkg].repository_name)
    recipe = yoctoRecipe.convert_to_oe_name(pkg)
    # check for an existing recipe
    glob_pattern = '{0}/generated-recipes-{1}/{2}/{3}*.bb'.format(
        repo_dir, distro.name, component_name, recipe)
    existing = glob.glob(glob_pattern)
    if preserve_existing and existing:
        ok("recipe for package '%s' up to date, skipping..." % pkg)
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, []
    elif existing:
        overlay.repo.remove_file(existing[0], True)
    try:
        current = oe_installer(distro, pkg, tar_dir, md5_cache, sha256_cache,
                               skip_keys)
    except InvalidPackage as e:
        err('Invalid package: ' + str(e))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, []
    except Exception as e:
        err('Failed generating installer for {}! {}'.format(pkg, str(e)))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return 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, []
    except KeyError as ke:
        err("Failed to parse data for package {}! {}".format(pkg, str(ke)))
        yoctoRecipe.not_generated_recipes.add(pkg)
        return None, []
    make_dir("{0}/generated-recipes-{1}/{2}".format(repo_dir, distro.name,
                                                    component_name))
    success_msg = 'Successfully generated installer for package'
    ok('{0} \'{1}\'.'.format(success_msg, pkg))
    recipe_file_name = '{0}/generated-recipes-{1}/{2}/{3}_{4}.bb'.format(
        repo_dir, distro.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, []
    return current, []
Example #14
0
 def generate_rosdistro_conf(
         basepath, distro, version, platforms, skip_keys=[]):
     conf_dir = '{}/conf/ros-distro/include/{}/'.format(basepath, distro)
     conf_file_name = 'generated-ros-distro.inc'
     conf_path = '{}{}'.format(conf_dir, conf_file_name)
     try:
         make_dir(conf_dir)
         with open(conf_path, 'w') as conf_file:
             conf_file.write('# {}/{}\n'.format(distro, conf_file_name))
             conf_file.write('# Generated by superflore -- DO NOT EDIT')
             conf_file.write(
                 ' (except ROS_DISTRO_METADATA_VERSION_REVISION)\n#\n')
             conf_file.write(
                 '# Copyright ' + strftime("%Y", gmtime())
                 + ' Open Source Robotics Foundation\n\n')
             conf_file.write(
                 '# Increment every time meta-ros is released because of '
                 + 'a manually created change, ie, NOT as a result of a '
                 + 'superflore run (which\n# resets it to "0").')
             conf_file.write(
                 '\nROS_DISTRO_METADATA_VERSION_REVISION = "0"\n')
             conf_file.write(
                 '\nROS_SUPERFLORE_PROGRAM_VERSION = "{}"\n'
                 .format(get_superflore_version()))
             conf_file.write('ROS_SUPERFLORE_GENERATION_SCHEME = "1"\n')
             ros_version = yoctoRecipe._get_ros_version(distro)
             conf_file.write(
                 '\nROS_DISTRO_TYPE = "ros{}"\n'.format(ros_version))
             conf_file.write('ROS_VERSION = "{}"\n'.format(ros_version))
             conf_file.write('# DO NOT OVERRIDE ROS_PYTHON_VERSION\n')
             ros_python_version = 3
             if ros_version == 1:
                 ros_python_version = 2
             conf_file.write(
                 'ROS_PYTHON_VERSION = "{}"\n\n'.format(ros_python_version))
             oe_skip_keys = map(
                 lambda skip_key: yoctoRecipe.convert_to_oe_name(skip_key),
                 skip_keys
             )
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATION_SKIP_LIST', oe_skip_keys)
                 + '\n')
             conf_file.write(
                 '# Superflore was unable to generate recipes for these '
                 + 'packages, eg, because their repositories are not on '
                 + 'GitHub.\n')
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATION_NOT_POSSIBLE',
                 yoctoRecipe.not_generated_recipes) + '\n')
             conf_file.write(
                 '# Number of commits that will be returned by'
                 + ' "git log files/ROS_DISTRO-cache.yaml" when the '
                 + 'generated files are committed. This is\n# used for the'
                 + ' third version field of DISTRO_VERSION.\n')
             version = 1 if not version else len(version.splitlines()) + 1
             conf_file.write(
                 'ROS_NUM_CACHE_YAML_COMMITS = "{}"'.format(version)
                 + '\n\n')
             conf_file.write(
                 '# Iterated values of '
                 + 'ROS_DISTRO-cache.distribution_file.release_platforms.'
                 + '<LINUX-DISTRO>.[ <NAME> ... ] .\n')
             release_platforms = []
             for p in sorted(platforms.items()):
                 for release in p[1]:
                     release_platforms.append(p[0] + '-' + release)
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_DISTRO_RELEASE_PLATFORMS', release_platforms) + '\n')
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATED_RECIPES',
                 yoctoRecipe.generated_recipes.keys()) + '\n')
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATED_RECIPE_BASENAMES_WITH_COMPONENT',
                 [(yoctoRecipe.max_component_name - len(component)) * ' '
                  + component + '/' + recipe + '_' + version
                  for recipe, (version, component)
                  in yoctoRecipe.generated_recipes.items()],
                 key=lambda recipe: recipe.split('/')[1].split('_')[0]))
             conf_file.write(
                 '\n# What\'s built by packagegroup-ros-world. Does not '
                 + 'include packages that appear solely in '
                 + 'ROS_SUPERFLORE_GENERATED_BUILDTOOLS\n# (with a -native'
                 + ' suffix) or ROS_SUPERFLORE_GENERATED_TESTS.\n')
             recipes_set = set(yoctoRecipe.generated_recipes.keys())
             test_deps = set(map(
                 lambda test_dep: yoctoRecipe.convert_to_oe_name(test_dep),
                 yoctoRecipe.generated_test_deps
                 - yoctoRecipe.generated_non_test_deps
             ))
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATED_WORLD_PACKAGES', recipes_set
                 - yoctoRecipe.generated_native_recipes - test_deps))
             conf_file.write(
                 '\n# Packages found in the <buildtool_depend> and '
                 + '<buildtool_export_depend> items, ie, ones for which a '
                 + '-native is built. Does not\n# include those found in '
                 + 'the ROS_EXEC_DEPENDS values in the recipes of build '
                 + 'tools.\n')
             conf_file.write(
                 yoctoRecipe.generate_multiline_variable(
                     'ROS_SUPERFLORE_GENERATED_BUILDTOOLS',
                     yoctoRecipe.generated_native_recipes) + '\n')
             conf_file.write(yoctoRecipe.generate_multiline_variable(
                 'ROS_SUPERFLORE_GENERATED_PLATFORM_PACKAGE_DEPENDENCIES',
                 yoctoRecipe.platform_deps))
             conf_file.write(
                 '\n# Packages found only in <test_depend> items. Does not'
                 + ' include those found only in the ROS_*_DEPENDS of '
                 + 'recipes of tests.\n')
             conf_file.write(
                 yoctoRecipe.generate_multiline_variable(
                     'ROS_SUPERFLORE_GENERATED_TESTS',
                     test_deps) + '\n')
             conf_file.write(
                 yoctoRecipe.generate_multiline_variable(
                     'ROS_SUPERFLORE_GENERATED_RECIPES_FOR_COMPONENTS',
                     yoctoRecipe.generated_components))
             ok('Wrote {0}'.format(conf_path))
     except OSError as e:
         err('Failed to write conf {} to disk! {}'.format(conf_path, e))
         raise e
Example #15
0
def regenerate_pkg(overlay, pkg, distro, preserve_existing=False):
    version = get_pkg_version(distro, pkg)
    pkgbuild_name =\
        '/ros-{0}/{1}/{1}.pkgbuild'.format(distro.name, pkg)
    pkgbuild_name = overlay.repo.repo_dir + pkgbuild_name
    patch_path = '/ros-{}/{}/files'.format(distro.name, pkg)
    patch_path = overlay.repo.repo_dir + patch_path
    is_ros2 = get_distros()[distro.name]['distribution_type'] == 'ros2'
    has_patches = os.path.exists(patch_path)
    pkg_names = get_package_names(distro)[0]
    patches = None
    if os.path.exists(patch_path):
        patches = [
            f for f in glob.glob('%s/*.patch' % patch_path)
        ]
    if pkg not in pkg_names:
        raise RuntimeError("Unknown package '%s'" % (pkg))
    # otherwise, remove a (potentially) existing pkgbuild.
    prefix = '{0}/ros-{1}/{2}/'.format(overlay.repo.repo_dir, distro.name, pkg)
    existing = glob.glob('%s*.pkgbuild' % prefix)
    previous_version = None
    if preserve_existing and os.path.isfile(pkgbuild_name):
        ok("pkgbuild for package '%s' up to date, skipping..." % pkg)
        return None, [], None
    elif existing:
        overlay.repo.remove_file(existing[0])
        previous_version = existing[0].lstrip(prefix).rstrip('.pkgbuild')
        manifest_file = '{0}/ros-{1}/{2}/Manifest'.format(
            overlay.repo.repo_dir, distro.name, pkg
        )
        overlay.repo.remove_file(manifest_file)
    try:
        current = arch_pkgbuild(distro, pkg, has_patches)
        current.pkgbuild.name = pkg
        current.pkgbuild.version = version
        current.pkgbuild.patches = patches
        current.pkgbuild.is_ros2 = is_ros2
    except Exception as e:
        err('Failed to generate pkgbuild for package {}!'.format(pkg))
        raise e
    try:
        pkgbuild_text = current.pkgbuild_text()
    except UnresolvedDependency:
        dep_err = 'Failed to resolve required dependencies for'
        err("{0} package {1}!".format(dep_err, pkg))
        unresolved = current.pkgbuild.get_unresolved()
        for dep in unresolved:
            err(" unresolved: \"{}\"".format(dep))
        return None, current.pkgbuild.get_unresolved(), None
    except KeyError as ke:
        err("Failed to parse data for package {}!".format(pkg))
        raise ke
    make_dir(
        "{}/ros-{}/{}".format(overlay.repo.repo_dir, distro.name, pkg)
    )
    success_msg = 'Successfully generated pkgbuild for package'
    ok('{0} \'{1}\'.'.format(success_msg, pkg))

    try:
        pkgbuild_file = '{0}/ros-{1}/{2}/PKGBUILD'.format(
            overlay.repo.repo_dir,
            distro.name, 
            pkg,
        )
        ok(f"writing {pkgbuild_file}")
        with open(pkgbuild_file, "w") as pkgbuild_file_f:
            pkgbuild_file_f.write(pkgbuild_text)
    except Exception as e:
        err(f"Failed to write f{pkgbuild_file} to disk!")
        raise e
    return current, previous_version, pkg