Exemplo n.º 1
0
def execCommand(args, following_args):
    # remove the pseudo-name 'all': it wouldn't be recognised by build/cmake
    all_tests = 'all' in args.tests
    if all_tests:
        args.tests.remove('all')

    returncode = 0
    if args.build and not args.list_only:
        # we need to build before testing, make sure that any tests needed are
        # built:
        if all_tests:
            vars(args)['build_targets'] = args.tests + ['all_tests']
        else:
            vars(args)['build_targets'] = args.tests
        build_status = build.installAndBuild(args, following_args)
        # a generate or build step failure is fatal, but an install-step
        # failure should not prevent attempting tests:
        if build_status.get('generate_status', 0) != 0 or \
           build_status.get('build_status', 0) != 0 or \
           build_status.get('missing_status', 0) != 0:
            return 1
        else:
            returncode = build_status['status']

    cwd = os.getcwd()

    c = validate.currentDirectoryModule()
    if not c:
        return 1

    target, errors = c.satisfyTarget(args.target,
                                     additional_config=args.config)
    if errors:
        for error in errors:
            logging.error(error)
        return 1

    all_modules = c.getDependenciesRecursive(target=target,
                                             available_components=[
                                                 (c.getName(), c)
                                             ],
                                             test=True)

    builddir = os.path.join(cwd, 'build', target.getName())

    # get the list of tests we need to run, if --all is specified we also run
    # the tests for all of our submodules, otherwise we just run the tests for
    # this module.
    # If we have specific test specified, we also need to search for all the
    # tests, in case the specific test does not belong to this module
    tests = findCTests(builddir,
                       recurse_yotta_modules=(all_tests or len(args.tests)))

    errcode = c.runScript('preTest')
    if errcode:
        return errcode

    passed = 0
    failed = 0
    for dirname, test_definitions in tests:
        module = moduleFromDirname(os.path.relpath(dirname, builddir),
                                   all_modules, c)
        logging.debug('inferred module %s from path %s', module.getName(),
                      os.path.relpath(dirname, builddir))
        if (not len(args.tests)) and (module is not c) and not all_tests:
            continue
        info_filter = True
        filter_command = module.getScript('testReporter')
        for test_name, test_command in test_definitions:
            if len(args.tests) and not test_name in args.tests:
                logging.debug('skipping not-listed test %s: %s', test_name,
                              test_command)
                continue
            if info_filter and filter_command:
                info_filter = False
                logging.info('using filter "%s" for tests in %s',
                             ' '.join(filter_command), dirname)
            logging.info('test %s: %s', module.getName(), test_name)
            if args.list_only:
                continue
            test_returncode = target.test(test_dir=dirname,
                                          module_dir=module.path,
                                          test_command=test_command,
                                          filter_command=filter_command,
                                          forward_args=following_args)
            if test_returncode:
                logging.error('test %s failed (command: %s)', test_name,
                              test_command)
                failed += 1
                if not returncode:
                    returncode = 1
            else:
                logging.info('test %s passed', test_name)
                passed += 1
    if not args.list_only:
        logging.info("tests complete: %d passed, %d failed", passed, failed)

    return returncode
Exemplo n.º 2
0
def execCommand(args, following_args):
    # remove the pseudo-name 'all': it wouldn't be recognised by build/cmake
    all_tests = 'all' in args.tests
    if all_tests:
        args.tests.remove('all')

    returncode = 0
    if args.build and not args.list_only:
        # we need to build before testing, make sure that any tests needed are
        # built:
        if all_tests:
            vars(args)['build_targets'] = args.tests + ['all_tests']
        else:
            vars(args)['build_targets'] = args.tests
        build_status = build.installAndBuild(args, following_args)
        # a generate or build step failure is fatal, but an install-step
        # failure should not prevent attempting tests:
        if build_status.get('generate_status', 0) != 0 or \
           build_status.get('build_status', 0) != 0 or \
           build_status.get('missing_status', 0) != 0:
            return 1
        else:
            returncode = build_status['status']

    cwd = os.getcwd()

    c = validate.currentDirectoryModule()
    if not c:
        return 1

    target, errors = c.satisfyTarget(args.target, additional_config=args.config)
    if errors:
        for error in errors:
            logging.error(error)
        return 1

    all_modules = c.getDependenciesRecursive(
                      target = target,
        available_components = [(c.getName(), c)],
                        test = True
    )


    builddir = os.path.join(cwd, 'build', target.getName())

    # get the list of tests we need to run, if --all is specified we also run
    # the tests for all of our submodules, otherwise we just run the tests for
    # this module.
    # If we have specific test specified, we also need to search for all the
    # tests, in case the specific test does not belong to this module
    tests = findCTests(builddir, recurse_yotta_modules=(all_tests or len(args.tests)))

    errcode = c.runScript('preTest')
    if errcode:
        return errcode

    passed = 0
    failed = 0
    for dirname, test_definitions in tests:
        module = moduleFromDirname(os.path.relpath(dirname, builddir), all_modules, c)
        logging.debug('inferred module %s from path %s', module.getName(), os.path.relpath(dirname, builddir))
        if (not len(args.tests)) and (module is not c) and not all_tests:
            continue
        info_filter = True
        filter_command = module.getScript('testReporter')
        for test_name, test_command in test_definitions:
            if len(args.tests) and not test_name in args.tests:
                logging.debug('skipping not-listed test %s: %s', test_name, test_command)
                continue
            if info_filter and filter_command:
                info_filter = False
                logging.info('using filter "%s" for tests in %s', ' '.join(filter_command), dirname)
            logging.info('test %s: %s', module.getName(), test_name)
            if args.list_only:
                continue
            test_returncode = target.test(
                       test_dir = dirname,
                     module_dir = module.path,
                   test_command = test_command,
                 filter_command = filter_command,
                   forward_args = following_args
            )
            if test_returncode:
                logging.error('test %s failed (command: %s)', test_name, test_command)
                failed += 1
                if not returncode:
                    returncode = 1
            else:
                logging.info('test %s passed', test_name)
                passed += 1
    if not args.list_only:
        logging.info("tests complete: %d passed, %d failed", passed, failed)

    return returncode
Exemplo n.º 3
0
def installAndBuild(args, following_args):
    ''' Perform the build command, but provide detailed error information.
        Returns {status:0, build_status:0, generate_status:0, install_status:0} on success.
        If status: is nonzero there was some sort of error. Other properties
        are optional, and may not be set if that step was not attempted.
    '''
    build_status = generate_status = install_status = 0

    if not hasattr(args, 'build_targets'):
        vars(args)['build_targets'] = []

    if 'test' in args.build_targets:
        logging.error('Cannot build "test". Use "yotta test" to run tests.')
        return {'status': 1}

    cwd = os.getcwd()
    c = validate.currentDirectoryModule()
    if not c:
        return {'status': 1}

    try:
        target, errors = c.satisfyTarget(args.target,
                                         additional_config=args.config)
    except access_common.AccessException as e:
        logging.error(e)
        return {'status': 1}
    if errors:
        for error in errors:
            logging.error(error)
        return {'status': 1}

    # run the install command before building, we need to add some options the
    # install command expects to be present to do this:
    vars(args)['component'] = None
    vars(args)['act_globally'] = False
    if not hasattr(args, 'install_test_deps'):
        if 'all_tests' in args.build_targets:
            vars(args)['install_test_deps'] = 'all'
        elif not len(args.build_targets):
            vars(args)['install_test_deps'] = 'own'
        else:
            # If the named build targets include tests from other modules, we
            # need to install the deps for those modules. To do this we need to
            # be able to tell which module a library belongs to, which is not
            # straightforward (especially if there is custom cmake involved).
            # That's why this is 'all', and not 'none'.
            vars(args)['install_test_deps'] = 'all'

    # install may exit non-zero for non-fatal errors (such as incompatible
    # version specs), which it will display
    install_status = install.execCommand(args, [])

    builddir = os.path.join(cwd, 'build', target.getName())

    all_deps = c.getDependenciesRecursive(target=target,
                                          available_components=[(c.getName(),
                                                                 c)],
                                          test=True)

    # if a dependency is missing the build will almost certainly fail, so don't try
    missing = 0
    for d in all_deps.values():
        if not d and not (d.isTestDependency()
                          and args.install_test_deps != 'all'):
            logging.error('%s not available' % os.path.split(d.path)[1])
            missing += 1
    if missing:
        logging.error(
            'Missing dependencies prevent build. Use `yotta ls` to list them.')
        return {
            'status': 1,
            'install_status': install_status,
            'missing_status': missing
        }

    generator = cmakegen.CMakeGen(builddir, target)
    # only pass available dependencies to
    config = generator.configure(c, all_deps)
    logging.debug("config done, merged config: %s",
                  config['merged_config_json'])

    script_environment = {
        'YOTTA_MERGED_CONFIG_FILE': config['merged_config_json']
    }
    # run pre-generate scripts for all components:
    runScriptWithModules(c, all_deps.values(), 'preGenerate',
                         script_environment)

    app = c if len(c.getBinaries()) else None
    for error in generator.generateRecursive(c,
                                             all_deps,
                                             builddir,
                                             application=app):
        logging.error(error)
        generate_status = 1

    logging.debug("generate done.")
    # run pre-build scripts for all components:
    runScriptWithModules(c, all_deps.values(), 'preBuild', script_environment)

    if (not hasattr(args, 'generate_only')) or (not args.generate_only):
        error = target.build(
            builddir,
            c,
            args,
            release_build=args.release_build,
            build_args=following_args,
            targets=args.build_targets,
            release_no_debug_info_build=args.release_no_debug_info_build)

        if error:
            logging.error(error)
            build_status = 1
        else:
            # post-build scripts only get run if we were successful:
            runScriptWithModules(c, all_deps.values(), 'postBuild',
                                 script_environment)

        if install_status:
            logging.warning(
                "There were also errors installing and resolving dependencies, "
                +
                "which may have caused the build failure: see above, or run " +
                "`yotta install` for details.")

    return {
        'status': build_status or generate_status or install_status,
        'missing_status': missing,
        'build_status': build_status,
        'generate_status': generate_status,
        'install_status': install_status
    }
Exemplo n.º 4
0
def installAndBuild(args, following_args):
    ''' Perform the build command, but provide detailed error information.
        Returns {status:0, build_status:0, generate_status:0, install_status:0} on success.
        If status: is nonzero there was some sort of error. Other properties
        are optional, and may not be set if that step was not attempted.
    '''
    build_status = generate_status = install_status = 0

    if not hasattr(args, 'build_targets'):
        vars(args)['build_targets'] = []

    if 'test' in args.build_targets:
        logging.error('Cannot build "test". Use "yotta test" to run tests.')
        return {'status':1}

    cwd = os.getcwd()
    c = validate.currentDirectoryModule()
    if not c:
        return {'status':1}

    try:
        target, errors = c.satisfyTarget(args.target, additional_config=args.config)
    except access_common.AccessException as e:
        logging.error(e)
        return {'status':1}
    if errors:
        for error in errors:
            logging.error(error)
        return {'status':1}

    # run the install command before building, we need to add some options the
    # install command expects to be present to do this:
    vars(args)['component'] = None
    vars(args)['act_globally'] = False
    if not hasattr(args, 'install_test_deps'):
        if 'all_tests' in args.build_targets:
            vars(args)['install_test_deps'] = 'all'
        elif not len(args.build_targets):
            vars(args)['install_test_deps'] = 'own'
        else:
            # If the named build targets include tests from other modules, we
            # need to install the deps for those modules. To do this we need to
            # be able to tell which module a library belongs to, which is not
            # straightforward (especially if there is custom cmake involved).
            # That's why this is 'all', and not 'none'.
            vars(args)['install_test_deps'] = 'all'

    # install may exit non-zero for non-fatal errors (such as incompatible
    # version specs), which it will display
    install_status = install.execCommand(args, [])

    builddir = os.path.join(cwd, 'build', target.getName())

    all_deps = c.getDependenciesRecursive(
                      target = target,
        available_components = [(c.getName(), c)],
                        test = True
    )

    # if a dependency is missing the build will almost certainly fail, so don't try
    missing = 0
    for d in all_deps.values():
        if not d and not (d.isTestDependency() and args.install_test_deps != 'all'):
            logging.error('%s not available' % os.path.split(d.path)[1])
            missing += 1
    if missing:
        logging.error('Missing dependencies prevent build. Use `yotta ls` to list them.')
        return {'status': 1, 'install_status':install_status, 'missing_status':missing}

    generator = cmakegen.CMakeGen(builddir, target)
    # only pass available dependencies to
    config = generator.configure(c, all_deps)
    logging.debug("config done, merged config: %s", config['merged_config_json'])

    script_environment = {
        'YOTTA_MERGED_CONFIG_FILE': config['merged_config_json']
    }
    # run pre-generate scripts for all components:
    runScriptWithModules(c, all_deps.values(), 'preGenerate', script_environment)

    app = c if len(c.getBinaries()) else None
    for error in generator.generateRecursive(c, all_deps, builddir, application=app):
        logging.error(error)
        generate_status = 1

    logging.debug("generate done.")
    # run pre-build scripts for all components:
    runScriptWithModules(c, all_deps.values(), 'preBuild', script_environment)

    if (not hasattr(args, 'generate_only')) or (not args.generate_only):
        error = target.build(
                builddir, c, args, release_build=args.release_build,
                build_args=following_args, targets=args.build_targets
        )

        if error:
            logging.error(error)
            build_status = 1
        else:
            # post-build scripts only get run if we were successful:
            runScriptWithModules(c, all_deps.values(), 'postBuild', script_environment)

        if install_status:
            logging.warning(
                "There were also errors installing and resolving dependencies, "+
                "which may have caused the build failure: see above, or run "+
                "`yotta install` for details."
            )

    return {
                'status': build_status or generate_status or install_status,
        'missing_status': missing,
          'build_status': build_status,
       'generate_status': generate_status,
        'install_status': install_status
    }