Пример #1
0
def argument_preprocessor(args):
    """Run verb and plugin preprocessors on arguments.

    The preprocessors take in raw arguments and return potentially trimmed
    arguments and extra options to be added to the argparse NameSpace object.

    This can fail if the positional path argument does not contain a valid path
    or if the build type of the package at that path does not have a
    corresponding build type plugin.

    :param list args: list of arguments as str's
    :returns: tuple of left over arguments and dictionary of extra options
    :raises: SystemError if underlying assumptions are not met
    """
    extras = {}

    # Extract make arguments
    args, make_flags = extract_argument_group(args, '--make-flags')

    # Detected build type if possible
    parser = argparse.ArgumentParser()
    add_path_argument(parser)
    opts, _ = parser.parse_known_args(args)
    try:
        path = validate_package_manifest_path(opts.path)
    except (MissingPluginError, ValueError) as exc:
        sys.exit("{0}".format(exc))
    build_type = get_build_type(path)
    build_type_impl = get_class_for_build_type(build_type)()
    # Let detected build type plugin do argument preprocessing
    args, extras = build_type_impl.argument_preprocessor(args)

    args = combine_make_flags(make_flags, args, extras)

    return args, extras
Пример #2
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    if not opts.skip_build:
        ignore_file = os.path.join(context.build_space, 'AMENT_IGNORE')
        if not os.path.exists(ignore_file) and not context.dry_run:
            os.makedirs(context.build_space, exist_ok=True)
            with open(ignore_file, 'w'):
                pass

        # Run the build command
        print("+++ Building '{0}'".format(pkg_name))
        on_build_ret = build_type_impl.on_build(context)
        handle_build_action(on_build_ret, context)
        expand_prefix_level_setup_files(context)

    if not opts.skip_install:
        # Run the install command
        print("+++ Installing '{0}'".format(pkg_name))
        on_install_ret = build_type_impl.on_install(context)
        handle_build_action(on_install_ret, context)
        deploy_prefix_level_setup_files(context)
Пример #3
0
def argument_preprocessor(args):
    """Run verb and plugin preprocessors on arguments.

    The preprocessors take in raw arguments and return potentially trimmed
    arguments and extra options to be added to the argparse NameSpace object.

    This can fail if the positional path argument does not contain a valid path
    or if the build type of the package at that path does not have a
    corresponding build type plugin.

    :param list args: list of arguments as str's
    :returns: tuple of left over arguments and dictionary of extra options
    :raises: SystemError if underlying assumptions are not met
    """
    extras = {}

    # Extract make arguments
    args, make_flags = extract_argument_group(args, '--make-flags')

    # Detected build type if possible
    parser = argparse.ArgumentParser()
    add_path_argument(parser)
    opts, _ = parser.parse_known_args(args)
    try:
        path = validate_package_manifest_path(opts.path)
    except (MissingPluginError, ValueError) as exc:
        sys.exit("{0}".format(exc))
    build_type = get_build_type(path)
    build_type_impl = get_class_for_build_type(build_type)()
    # Let detected build type plugin do argument preprocessing
    args, extras = build_type_impl.argument_preprocessor(args)

    args = combine_make_flags(make_flags, args, extras)

    return args, extras
Пример #4
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    if not opts.skip_build:
        ignore_file = os.path.join(context.build_space, 'AMENT_IGNORE')
        if not os.path.exists(ignore_file) and not context.dry_run:
            os.makedirs(context.build_space, exist_ok=True)
            with open(ignore_file, 'w'):
                pass

        # Run the build command
        print("+++ Building '{0}'".format(pkg_name))
        on_build_ret = build_type_impl.on_build(context)
        handle_build_action(on_build_ret, context)
        expand_prefix_level_setup_files(context)

    if not opts.skip_install:
        # Run the install command
        print("+++ Installing '{0}'".format(pkg_name))
        on_install_ret = build_type_impl.on_install(context)
        handle_build_action(on_install_ret, context)
        deploy_prefix_level_setup_files(context)
Пример #5
0
def prepare_arguments(parser, args):
    """
    Add parameters to argparse for the build_pkg verb and its plugins.

    After adding the generic verb arguments, this function tries to determine
    the build type of the target package. This is done by gracefully trying
    to get the positional ``path`` argument from the arguments, falling back
    to the default ``os.curdir``. Then it searches for a package manifest in
    that path. If it finds the package manifest it then determines the build
    type of the package, e.g. ``ament_cmake``. It then tries to load a build
    type plugin for that build type. If the loading is successful it will allow
    the plugin to add additional arguments to the parser in a new
    :py:class:`argparse.ArgumentGroup` for that build type.

    :param parser: ArgumentParser object to which arguments are added
    :type parser: :py:class:`argparse.ArgumentParser`
    :param list args: list of arguments as str's
    :returns: modified version of the original parser given
    :rtype: :py:class:`argparse.ArgumentParser`
    """
    # Add verb arguments
    add_path_argument(parser)
    add_arguments(parser)

    # Detected build type if possible
    try:
        # Remove -h and --help to prevent printing help messages
        filt_args = list(filter(lambda x: x not in ['-h', '--help'], args))
        # Remove first position argument, because that will be the verb
        for i, arg in enumerate(filt_args):
            if not arg.startswith('-'):
                del filt_args[i]
                break
        # Parse the arguments to find the user's provided path (or the default)
        opts, _ = parser.parse_known_args(filt_args)
        # Check to ensure the path has a package
        validate_package_path(opts.path)
        # Get the build_type from the package manifest
        build_type = get_build_type(opts.path)
        # Find an entry point which supports this build type
        build_type_impl = get_class_for_build_type(build_type)()
        # Let the detected build type plugin add arguments
        group = parser.add_argument_group(
            '{0} (detected) options'.format(build_type_impl.build_type))
        call_prepare_arguments(
            build_type_impl.prepare_arguments,
            group,
            args,
        )
    # Catch value and system errors which will raise later
    # This is done to preserve -h and --help's ability to function
    except (MissingPluginError, ValueError) as exc:
        # If system exit AND -h or --help are used, show the error
        if '-h' in args or '--help' in args:
            print('Error: Could not detect package build type:', exc)
    return parser
Пример #6
0
def prepare_arguments(parser, args):
    """
    Add parameters to argparse for the build_pkg verb and its plugins.

    After adding the generic verb arguments, this function tries to determine
    the build type of the target package. This is done by gracefully trying
    to get the positional ``path`` argument from the arguments, falling back
    to the default ``os.curdir``. Then it searches for a package manifest in
    that path. If it finds the package manifest it then determines the build
    type of the package, e.g. ``ament_cmake``. It then tries to load a build
    type plugin for that build type. If the loading is successful it will allow
    the plugin to add additional arguments to the parser in a new
    :py:class:`argparse.ArgumentGroup` for that build type.

    :param parser: ArgumentParser object to which arguments are added
    :type parser: :py:class:`argparse.ArgumentParser`
    :param list args: list of arguments as str's
    :returns: modified version of the original parser given
    :rtype: :py:class:`argparse.ArgumentParser`
    """
    # Add verb arguments
    add_path_argument(parser)
    add_arguments(parser)

    # Detected build type if possible
    try:
        # Remove -h and --help to prevent printing help messages
        filt_args = list(filter(lambda x: x not in ['-h', '--help'], args))
        # Remove first position argument, because that will be the verb
        for i, arg in enumerate(filt_args):
            if not arg.startswith('-'):
                del filt_args[i]
                break
        # Parse the arguments to find the user's provided path (or the default)
        opts, _ = parser.parse_known_args(filt_args)
        # Check to ensure the path has a package
        validate_package_path(opts.path)
        # Get the build_type from the package manifest
        build_type = get_build_type(opts.path)
        # Find an entry point which supports this build type
        build_type_impl = get_class_for_build_type(build_type)()
        # Let the detected build type plugin add arguments
        group = parser.add_argument_group('{0} (detected) options'.format(
            build_type_impl.build_type))
        call_prepare_arguments(
            build_type_impl.prepare_arguments,
            group,
            args,
        )
    # Catch value and system errors which will raise later
    # This is done to preserve -h and --help's ability to function
    except (MissingPluginError, ValueError) as exc:
        # If system exit AND -h or --help are used, show the error
        if '-h' in args or '--help' in args:
            print('Error: Could not detect package build type:', exc)
    return parser
Пример #7
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    # Run the uninstall command
    print("+++ Uninstalling '{0}'".format(pkg_name))
    on_uninstall_ret = build_type_impl.on_uninstall(context)
    handle_build_action(on_uninstall_ret, context)
Пример #8
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    # Run the uninstall command
    print("+++ Uninstalling '{0}'".format(pkg_name))
    on_uninstall_ret = build_type_impl.on_uninstall(context)
    handle_build_action(on_uninstall_ret, context)
Пример #9
0
def main(opts):
    opts.build_tests = True
    context = build_pkg_get_context(opts)
    context.retest_until_pass = (opts.retest_until_pass > 0)
    rc = build_pkg_run(opts, context)
    if rc:
        return rc

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Run the test command
    pkg_name = context.package_manifest.name
    print("+++ Testing '{0}'".format(pkg_name))
    context.test_iteration = 0
    while True:
        try:
            on_test_ret = build_type_impl.on_test(context)
        except (AttributeError, NotImplementedError):
            print("on_test() is not implemented for build type '%s'" %
                  build_type,
                  file=sys.stderr)
            return
        try:
            handle_build_action(on_test_ret, context)
        except SystemExit as e:
            # check if tests should be rerun
            if opts.retest_until_pass > context.test_iteration:
                context.test_iteration += 1
                print(
                    "+++ Testing '%s' again (retry #%d of %d)" %
                    (pkg_name, context.test_iteration, opts.retest_until_pass))
                continue
            # Automated systems can use --ignore-return-codes to allow them to react to
            # a failure to *run* a test but not a failure generated by a test that ran as
            # intended. Otherwise, we'll combine the two cases to help users to notice
            # when anything went wrong during a test run.
            if opts.ignore_return_codes:
                return
            else:
                return e.code
        # check if tests should be rerun
        if opts.retest_until_fail > context.test_iteration:
            context.test_iteration += 1
            print("+++ Testing '%s' again (retry #%d of %d)" %
                  (pkg_name, context.test_iteration, opts.retest_until_fail))
            continue
        break
Пример #10
0
def main(opts):
    opts.build_tests = True
    context = build_pkg_get_context(opts)
    context.retest_until_pass = (opts.retest_until_pass > 0)
    rc = build_pkg_run(opts, context)
    if rc:
        return rc

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Run the test command
    pkg_name = context.package_manifest.name
    print("+++ Testing '{0}'".format(pkg_name))
    context.test_iteration = 0
    while True:
        try:
            on_test_ret = build_type_impl.on_test(context)
        except (AttributeError, NotImplementedError):
            print("on_test() is not implemented for build type '%s'" %
                  build_type, file=sys.stderr)
            return
        try:
            handle_build_action(on_test_ret, context)
        except SystemExit as e:
            # check if tests should be rerun
            if opts.retest_until_pass > context.test_iteration:
                context.test_iteration += 1
                print("+++ Testing '%s' again (retry #%d of %d)" %
                      (pkg_name, context.test_iteration, opts.retest_until_pass))
                continue
            # Automated systems can use --ignore-return-codes to allow them to react to
            # a failure to *run* a test but not a failure generated by a test that ran as
            # intended. Otherwise, we'll combine the two cases to help users to notice
            # when anything went wrong during a test run.
            if opts.ignore_return_codes:
                return
            else:
                return e.code
        # check if tests should be rerun
        if opts.retest_until_fail > context.test_iteration:
            context.test_iteration += 1
            print("+++ Testing '%s' again (retry #%d of %d)" %
                  (pkg_name, context.test_iteration, opts.retest_until_fail))
            continue
        break
Пример #11
0
def main(opts):
    opts.build_tests = True
    context = build_pkg_get_context(opts)
    context.retest_until_pass = (opts.retest_until_pass > 0)
    rc = build_pkg_run(opts, context)
    if rc:
        return rc

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Run the test command
    pkg_name = context.package_manifest.name
    print("+++ Testing '{0}'".format(pkg_name))
    context.test_iteration = 0
    while True:
        try:
            on_test_ret = build_type_impl.on_test(context)
        except (AttributeError, NotImplementedError):
            print("on_test() is not implemented for build type '%s'" %
                  build_type,
                  file=sys.stderr)
            return
        try:
            handle_build_action(on_test_ret, context)
        except SystemExit:
            # check if tests should be rerun
            if opts.retest_until_pass > context.test_iteration:
                context.test_iteration += 1
                print(
                    "+++ Testing '%s' again (retry #%d of %d)" %
                    (pkg_name, context.test_iteration, opts.retest_until_pass))
                continue
            # there is no way to distinguish why the test returned non zero
            # the test invocation itself could have failed:
            # return e.code
            # but it could have also run successful and only failed some tests:
            return
        # check if tests should be rerun
        if opts.retest_until_fail > context.test_iteration:
            context.test_iteration += 1
            print("+++ Testing '%s' again (retry #%d of %d)" %
                  (pkg_name, context.test_iteration, opts.retest_until_fail))
            continue
        break
Пример #12
0
def create_context(opts):
    # Setup build_pkg common context
    context = Context()
    context.source_space = os.path.abspath(os.path.normpath(opts.path))
    context.package_manifest = _get_cached_package_manifest(opts.path)
    pkg_name = context.package_manifest.name
    context.build_space = os.path.join(opts.build_space, pkg_name)
    context.install_space = opts.install_space
    context.install = True
    context.build_dependencies = opts.build_dependencies \
        if 'build_dependencies' in opts else []
    context.exec_dependency_paths_in_workspace = opts.exec_dependency_paths_in_workspace \
        if 'exec_dependency_paths_in_workspace' in opts else []
    context.symlink_install = opts.symlink_install
    context.make_flags = opts.make_flags
    context.dry_run = False
    context.build_tests = opts.build_tests
    context.python_interpreter = opts.python_interpreter
    print('')
    print("Process package '{0}' with context:".format(pkg_name))
    print('-' * 80)
    keys = [
        'source_space',
        'build_space',
        'install_space',
        'make_flags',
        'build_tests',
    ]
    max_key_len = str(max(len(k) for k in keys))
    for key in keys:
        value = context[key]
        if isinstance(value, list):
            value = ', '.join(value) if value else 'None'
        print(('{0:>' + max_key_len + '} => {1}').format(key, value))
    print('-' * 80)

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Allow the build type plugin to process options into a context extender
    ce = build_type_impl.extend_context(opts)
    # Extend the context with the context extender
    ce.apply_to_context(context)

    return context
Пример #13
0
def create_context(opts):
    # Setup build_pkg common context
    context = Context()
    context.source_space = os.path.abspath(os.path.normpath(opts.path))
    context.package_manifest = _get_cached_package_manifest(opts.path)
    pkg_name = context.package_manifest.name
    context.build_space = os.path.join(opts.build_space, pkg_name)
    context.install_space = opts.install_space
    context.install = True
    context.build_dependencies = opts.build_dependencies \
        if 'build_dependencies' in opts else []
    context.exec_dependency_paths_in_workspace = opts.exec_dependency_paths_in_workspace \
        if 'exec_dependency_paths_in_workspace' in opts else []
    context.symlink_install = opts.symlink_install
    context.make_flags = opts.make_flags
    context.dry_run = False
    context.build_tests = opts.build_tests
    context.python_interpreter = opts.python_interpreter
    print('')
    print("Process package '{0}' with context:".format(pkg_name))
    print('-' * 80)
    keys = [
        'source_space',
        'build_space',
        'install_space',
        'make_flags',
        'build_tests',
    ]
    max_key_len = str(max(len(k) for k in keys))
    for key in keys:
        value = context[key]
        if isinstance(value, list):
            value = ', '.join(value) if value else 'None'
        print(('{0:>' + max_key_len + '} => {1}').format(key, value))
    print('-' * 80)

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Allow the build type plugin to process options into a context extender
    ce = build_type_impl.extend_context(opts)
    # Extend the context with the context extender
    ce.apply_to_context(context)

    return context
Пример #14
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    if not opts.skip_build:
        # Run the build command
        print("+++ Building '{0}'".format(pkg_name))
        on_build_ret = build_type_impl.on_build(context)
        handle_build_action(on_build_ret, context)
        expand_prefix_level_setup_files(context)

    if not opts.skip_install:
        # Run the install command
        print("+++ Installing '{0}'".format(pkg_name))
        on_install_ret = build_type_impl.on_install(context)
        handle_build_action(on_install_ret, context)
        deploy_prefix_level_setup_files(context)
Пример #15
0
def run(opts, context):
    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    pkg_name = context.package_manifest.name

    if not opts.skip_build:
        # Run the build command
        print("+++ Building '{0}'".format(pkg_name))
        on_build_ret = build_type_impl.on_build(context)
        handle_build_action(on_build_ret, context)
        expand_prefix_level_setup_files(context)

    if not opts.skip_install:
        # Run the install command
        print("+++ Installing '{0}'".format(pkg_name))
        on_install_ret = build_type_impl.on_install(context)
        handle_build_action(on_install_ret, context)
        deploy_prefix_level_setup_files(context)
Пример #16
0
def main(opts):
    opts.build_tests = True
    context = build_pkg_get_context(opts)
    rc = build_pkg_run(opts, context)
    if rc:
        return rc

    # Load up build type plugin class
    build_type = get_build_type(opts.path)
    build_type_impl = get_class_for_build_type(build_type)()

    # Run the test command
    pkg_name = context.package_manifest.name
    print("+++ Testing '{0}'".format(pkg_name))
    try:
        on_test_ret = build_type_impl.on_test(context)
    except (AttributeError, NotImplementedError):
        print("on_test() is not implemented for build type '%s'" % build_type,
              file=sys.stderr)
        return
    try:
        handle_build_action(on_test_ret, context)
    except SystemExit:
        return 1