Ejemplo n.º 1
0
Archivo: list.py Proyecto: bearsh/yotta
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    if args.show_all:
        args.display_origin = True
    installed_modules = c.getDependenciesRecursive(target=target,
                                                   available_components=[
                                                       (c.getName(), c)
                                                   ],
                                                   test=True)
    if args.json:
        dependency_graph = resolveDependencyGraph(target, c, installed_modules)
        print(formatDependencyGraphAsJSON(dependency_graph))
    else:
        putln(
            ComponentDepsFormatter(target=target,
                                   available_components=installed_modules,
                                   plain=args.plain,
                                   list_all=args.show_all,
                                   display_origin=args.display_origin).format(
                                       c, [c.getName()]))
Ejemplo n.º 2
0
def execCommand(args, following_args):
    cwd = os.getcwd()

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

    if not c.isApplication():
        logging.error('This module describes a library not an executable. Only executables can be started.')
        return 1

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

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

    if args.program is None:
        # if no program was specified, default to the name of the executable
        # module (if this is an executable module)
        args.program = c.getName()

    errcode = c.runScript('preStart', {"YOTTA_PROGRAM":args.program})
    if errcode:
        return errcode

    error = target.start(builddir, args.program, following_args)
    if error:
        logging.error(error)
        errcode = 1

    return errcode
Ejemplo n.º 3
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    if args.show_all:
        args.display_origin = True
    installed_modules = c.getDependenciesRecursive(target=target, available_components=[(c.getName(), c)], test=True)
    if args.json:
        dependency_graph = resolveDependencyGraph(target, c, installed_modules)
        print(formatDependencyGraphAsJSON(dependency_graph))
    else:
        putln(
            ComponentDepsFormatter(
                target=target,
                available_components=installed_modules,
                plain=args.plain,
                list_all=args.show_all,
                display_origin=args.display_origin,
            ).format(c, [c.getName()])
        )
Ejemplo n.º 4
0
    def test_targetAppConfigMerge(self):
        test_dir = self.writeTestFiles(Test_Target_Config_Merge_App, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertIn("foo", merged_config)
        self.assertIn("bar", merged_config)
        self.assertIn("new", merged_config)
        self.assertIn("a", merged_config['foo'])
        self.assertIn("b", merged_config['foo'])
        self.assertIn("c", merged_config['foo'])
        self.assertEqual(merged_config['foo']['a'], 321)
        self.assertEqual(merged_config['foo']['b'], 456)
        self.assertEqual(merged_config['foo']['c'], 112233)
        self.assertIn("bar", merged_config)
        self.assertIn("d", merged_config['bar'])
        self.assertEqual(merged_config['bar']['d'], "ghi")
        self.assertIn("new", merged_config)
        self.assertEqual(merged_config['new'], 123)

        os.chdir(self.restore_cwd)
        rmRf(test_dir)
Ejemplo n.º 5
0
    def test_targetAppConfigMerge(self):
        test_dir = util.writeTestFiles(Test_Target_Config_Merge_App, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertIn("foo", merged_config)
        self.assertIn("bar", merged_config)
        self.assertIn("new", merged_config)
        self.assertIn("a", merged_config['foo'])
        self.assertIn("b", merged_config['foo'])
        self.assertIn("c", merged_config['foo'])
        self.assertEqual(merged_config['foo']['a'], 321)
        self.assertEqual(merged_config['foo']['b'], 456)
        self.assertEqual(merged_config['foo']['c'], 112233)
        self.assertIn("bar", merged_config)
        self.assertIn("d", merged_config['bar'])
        self.assertEqual(merged_config['bar']['d'], "ghi")
        self.assertIn("new", merged_config)
        self.assertEqual(merged_config['new'], 123)

        os.chdir(self.restore_cwd)
        util.rmRf(test_dir)
Ejemplo n.º 6
0
    def test_targetAppConfigMerge(self):
        test_dir = self.writeTestFiles(Test_Target_Config_Merge_App, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget("bar,")
        merged_config = target.getMergedConfig()

        self.assertIn("foo", merged_config)
        self.assertIn("bar", merged_config)
        self.assertIn("new", merged_config)
        self.assertIn("a", merged_config["foo"])
        self.assertIn("b", merged_config["foo"])
        self.assertIn("c", merged_config["foo"])
        self.assertEqual(merged_config["foo"]["a"], 321)
        self.assertEqual(merged_config["foo"]["b"], 456)
        self.assertEqual(merged_config["foo"]["c"], 112233)
        self.assertIn("bar", merged_config)
        self.assertIn("d", merged_config["bar"])
        self.assertEqual(merged_config["bar"]["d"], "ghi")
        self.assertIn("new", merged_config)
        self.assertEqual(merged_config["new"], 123)

        os.chdir(self.restore_cwd)
        rmRf(test_dir)
Ejemplo n.º 7
0
def execCommand(args, following_args):
    if args.link_target:
        c = validate.currentDirectoryModule()
        if not c:
            return 1
        err = validate.targetNameValidationError(args.link_target)
        if err:
            logging.error(err)
            return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_targets'))
        src = os.path.join(folders.globalTargetInstallDirectory(), args.link_target)
        dst = os.path.join(os.getcwd(), 'yotta_targets', args.link_target)
        # if the target is already installed, rm it
        fsutils.rmRf(dst)
    else:
        t = validate.currentDirectoryTarget()
        if not t:
            return 1
        fsutils.mkDirP(folders.globalTargetInstallDirectory())
        src = os.getcwd()
        dst = os.path.join(folders.globalTargetInstallDirectory(), t.getName())

    if args.link_target:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            logging.warning(
              ('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED + 'BROKEN' + colorama.Fore.RESET #pylint: disable=no-member
            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
    else:
        logging.info('%s -> %s' % (dst, src))
    fsutils.symlink(src, dst)
Ejemplo n.º 8
0
    def test_moduleConfigIgnored(self):
        test_dir = self.writeTestFiles(Test_Module_Config_Ignored, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertNotIn("new", merged_config)

        os.chdir(self.restore_cwd)
        rmRf(test_dir)
Ejemplo n.º 9
0
    def test_moduleConfigIgnored(self):
        test_dir = util.writeTestFiles(Test_Module_Config_Ignored, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertNotIn("new", merged_config)

        os.chdir(self.restore_cwd)
        util.rmRf(test_dir)
Ejemplo n.º 10
0
def execCommand(args, following_args):
    # standard library modules
    import logging

    # validate, , validate things, internal
    from yotta.lib import validate
    # ordered_json, , order-preserving json handling, internal
    from yotta.lib import ordered_json
    # fsutils, , filesystem utils, internal
    from yotta.lib.fsutils import rmF
    # list, , the yotta list subcommand, internal
    from yotta import list as yotta_list

    # first remove any existing shrinkwrap:
    rmF('yotta-shrinkwrap.json')

    c = validate.currentDirectoryModule()
    if not c:
        return 1
    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    installed_modules = c.getDependenciesRecursive(target=target,
                                                   available_components=[
                                                       (c.getName(), c)
                                                   ],
                                                   test='toplevel')

    dependency_list = yotta_list.resolveDependencyGraph(target,
                                                        c,
                                                        installed_modules,
                                                        test='toplevel')

    errors = checkDependenciesForShrinkwrap(dependency_list)
    if len(errors):
        logging.error("Dependency errors prevent shrinkwrap creation:")
        for error in errors:
            logging.error(error)
        logging.error("Perhaps you need to `yotta install` first?")
        return 1

    with open('yotta-shrinkwrap.json', 'w') as f:
        f.write(
            ordered_json.dumps(
                prepareShrinkwarp(dependency_list, target.hierarchy)))
Ejemplo n.º 11
0
def removeGlobally(module_or_target):
    # folders, , get places to install things, internal
    from yotta.lib import folders
    if module_or_target == 'module':
        global_dir = folders.globalInstallDirectory()
        p = validate.currentDirectoryModule()
    else:
        global_dir = folders.globalTargetInstallDirectory()
        p = validate.currentDirectoryTarget()
    if p is None:
        return 1
    path = os.path.join(global_dir, p.getName())
    return rmLinkOrDirectory(path, ('%s is not linked globally' % p.getName()))
Ejemplo n.º 12
0
def removeDependency(args, module_or_target):
    c = validate.currentDirectoryModule()
    if not c:
        return 1
    if module_or_target == 'module':
        subdir = c.modulesPath()
        err = validate.componentNameValidationError(args.module)
    else:
        subdir = c.targetsPath()
        err = validate.targetNameValidationError(args.module)
    if err:
        logging.error(err)
        return 1
    path = os.path.join(subdir, args.module)
    return rmLinkOrDirectory(path, '%s %s not found' % (('dependency', 'target')[module_or_target=='target'], args.module))
Ejemplo n.º 13
0
def execCommand(args, following_args):
    # standard library modules
    import logging

    # validate, , validate things, internal
    from yotta.lib import validate
    # ordered_json, , order-preserving json handling, internal
    from yotta.lib import ordered_json
    # fsutils, , filesystem utils, internal
    from yotta.lib.fsutils import rmF
    # list, , the yotta list subcommand, internal
    from yotta import list as yotta_list

    # first remove any existing shrinkwrap:
    rmF('yotta-shrinkwrap.json')

    c = validate.currentDirectoryModule()
    if not c:
        return 1
    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    installed_modules = c.getDependenciesRecursive(
                      target = target,
        available_components = [(c.getName(), c)],
                        test = 'toplevel'
    )

    dependency_list = yotta_list.resolveDependencyGraph(target, c, installed_modules, test='toplevel')

    errors = checkDependenciesForShrinkwrap(dependency_list)
    if len(errors):
        logging.error("Dependency errors prevent shrinkwrap creation:")
        for error in errors:
            logging.error(error)
        logging.error("Perhaps you need to `yotta install` first?")
        return 1

    with open('yotta-shrinkwrap.json', 'w') as f:
        f.write(ordered_json.dumps(prepareShrinkwarp(dependency_list, target.hierarchy)))
Ejemplo n.º 14
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1
    logging.debug('update for %s' % c)
    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1
    target, errors = c.satisfyTarget(args.target, update_installed=True, additional_config=args.config)
    if errors:
        for error in errors:
            logging.error(error)
        return 1
    if args.component is None:
        updateDeps(c, target, args)
    else:
        updateComponent(c, target, args)
Ejemplo n.º 15
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    dependencies = c.getDependenciesRecursive(
                      target = target,
        available_components = [(c.getName(), c)]
    )

    errors = []
    if args.list_all:
        for name, dep in dependencies.items():
            if not dep:
                errors.append(u'%s is missing: license unknown!' % name)
            else:
                print(u'%s: %s' % (name, u', '.join(dep.licenses())))
    else:
        licenses = defaultdict(list)
        for name, dep in dependencies.items():
            if not dep:
                errors.append(u'%s is missing: license unknown!' % name)
            else:
                for lic in dep.licenses():
                    licenses[lic].append(name)
        for lic in licenses:
            print(lic)

    if len(errors):
        for err in errors:
            logging.error(err)
        return 1
    return 0
Ejemplo n.º 16
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    dependencies = c.getDependenciesRecursive(target=target,
                                              available_components=[
                                                  (c.getName(), c)
                                              ])

    errors = []
    if args.list_all:
        for name, dep in dependencies.items():
            if not dep:
                errors.append(u'%s is missing: license unknown!' % name)
            else:
                print(u'%s: %s' % (name, u', '.join(dep.licenses())))
    else:
        licenses = defaultdict(list)
        for name, dep in dependencies.items():
            if not dep:
                errors.append(u'%s is missing: license unknown!' % name)
            else:
                for lic in dep.licenses():
                    licenses[lic].append(name)
        for lic in licenses:
            print(lic)

    if len(errors):
        for err in errors:
            logging.error(err)
        return 1
    return 0
Ejemplo n.º 17
0
def execCommand(args, following_args):
    err = validate.componentNameValidationError(args.component)
    if err:
        logging.error(err)
        return 1
    c = validate.currentDirectoryModule()
    if not c:
        return 1
    status = 0
    if not c.removeDependency(args.component):
        status = 1
    else:
        c.writeDescription()
    path = os.path.join(c.modulesPath(), args.component)
    if fsutils.isLink(path):
        fsutils.rmF(path)
    else:
        fsutils.rmRf(path)
    return status
Ejemplo n.º 18
0
def execCommand(args, following_args):
    err = validate.componentNameValidationError(args.component)
    if err:
        logging.error(err)
        return 1
    c = validate.currentDirectoryModule()
    if not c:
        return 1
    status = 0
    if not c.removeDependency(args.component):
        status = 1
    else:
        c.writeDescription()
    path = os.path.join(c.modulesPath(), args.component)
    if fsutils.isLink(path):
        fsutils.rmF(path)
    else:
        fsutils.rmRf(path)
    return status
Ejemplo n.º 19
0
    def test_targetConfigMerge(self):
        test_dir = util.writeTestFiles(Test_Target_Config_Merge, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertIn("foo", merged_config)
        self.assertIn("bar", merged_config)
        self.assertIn("a", merged_config['foo'])
        self.assertIn("b", merged_config['foo'])
        self.assertIn("c", merged_config['foo'])
        self.assertEqual(merged_config['foo']['a'], 321)
        self.assertEqual(merged_config['foo']['b'], 456)
        self.assertEqual(merged_config['foo']['c'], 789)
        self.assertIn("bar", merged_config)
        self.assertIn("d", merged_config['bar'])
        self.assertEqual(merged_config['bar']['d'], "def")

        os.chdir(self.restore_cwd)
        util.rmRf(test_dir)
Ejemplo n.º 20
0
    def test_targetConfigMerge(self):
        test_dir = self.writeTestFiles(Test_Target_Config_Merge, True)

        os.chdir(test_dir)
        c = validate.currentDirectoryModule()
        target, errors = c.satisfyTarget('bar,')
        merged_config = target.getMergedConfig()

        self.assertIn("foo", merged_config)
        self.assertIn("bar", merged_config)
        self.assertIn("a", merged_config['foo'])
        self.assertIn("b", merged_config['foo'])
        self.assertIn("c", merged_config['foo'])
        self.assertEqual(merged_config['foo']['a'], 321)
        self.assertEqual(merged_config['foo']['b'], 456)
        self.assertEqual(merged_config['foo']['c'], 789)
        self.assertIn("bar", merged_config)
        self.assertIn("d", merged_config['bar'])
        self.assertEqual(merged_config['bar']['d'], "def")

        os.chdir(self.restore_cwd)
        rmRf(test_dir)
Ejemplo n.º 21
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    if not args.target:
        logging.error('No target has been set, use "yotta target" to set one.')
        return 1

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

    config = target.getMergedConfig()

    if not args.plain:
        # then display blame information with nice colours :)
        dumpWithBlame(config, target.getConfigBlame())
        sys.stdout.write('\n')
    else:
        print(json.dumps(config, indent=2, separators=(',', ': ')))
Ejemplo n.º 22
0
def execCommand(args, following_args):
    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

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

    if args.program is None:
        if c.isApplication():
            # if no program was specified, default to the name of the executable
            # module (if this is an executable module)
            args.program = c.getName()
        else:
            logging.error(
                'This module describes a library not an executable, so you must name an executable to debug.'
            )
            return 1

    errcode = c.runScript('preDebug', {"YOTTA_PROGRAM": args.program})
    if errcode:
        return errcode

    error = target.debug(builddir, args.program)
    if error:
        logging.error(error)
        errcode = 1

    return errcode
Ejemplo n.º 23
0
def execCommand(args, following_args):
    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

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

    # !!! FIXME: the program should be specified by the description of the
    # current project (or a default value for the program should)
    errcode = None
    error = target.debug(builddir, args.program)
    if error:
        logging.error(error)
        errcode = 1

    return errcode
Ejemplo n.º 24
0
def execCommand(args, following_args):
    # validate, , validate things, internal
    from yotta.lib import validate

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

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

    dependencies = c.getDependenciesRecursive(target=target,
                                              available_components=[
                                                  (c.getName(), c)
                                              ],
                                              test=True)
    specs = c.getDependencySpecs(target=target)
    for mod in dependencies.values():
        specs += mod.getDependencySpecs(target=target)

    return displayOutdated(dependencies, specs, use_colours=(not args.plain))
Ejemplo n.º 25
0
def execCommand(args, following_args):
    # validate, , validate things, internal
    from yotta.lib import validate

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

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

    dependencies = c.getDependenciesRecursive(
                      target = target,
        available_components = [(c.getName(), c)],
                        test = True
    )
    specs = c.getDependencySpecs(target = target)
    for mod in dependencies.values():
        specs += mod.getDependencySpecs(target = target)

    return displayOutdated(dependencies, specs, use_colours=(not args.plain))
Ejemplo n.º 26
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    fsutils.rmRf(os.path.join(c.path, 'build'))
Ejemplo n.º 27
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
Ejemplo n.º 28
0
def execCommand(args, following_args):
    c = validate.currentDirectoryModule()
    if not c:
        return 1

    fsutils.rmRf(os.path.join(c.path, 'build'))
Ejemplo n.º 29
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
    }
Ejemplo n.º 30
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
    }
Ejemplo n.º 31
0
def execCommand(args, following_args):
    # standard library modules, , ,
    import logging
    import os

    # colorama, BSD 3-Clause license, color terminal output, pip install colorama
    import colorama

    # fsutils, , misc filesystem utils, internal
    from yotta.lib import fsutils
    # validate, , validate things, internal
    from yotta.lib import validate
    # folders, , get places to install things, internal
    from yotta.lib import folders
    c = None
    t = None
    link_target_name = None
    if args.target_or_path:
        link_target_name = args.target_or_path
        c = validate.currentDirectoryModule()
        if not c:
            return 1
        err = validate.targetNameValidationError(args.target_or_path)
        if err:
            # check if the target name is really a path to an existing target
            if os.path.isdir(args.target_or_path):
                # make sure the first half of the link exists,
                src = os.path.abspath(args.target_or_path)
                # if it isn't a valid target, that's an error:
                tgt = validate.directoryTarget(src)
                if not tgt:
                    logging.error("%s is not a valid target: %s", args.target_or_path, tgt.getError())
                    return 1
                link_target_name = tgt.getName()
                dst = os.path.join(folders.globalInstallDirectory(), link_target_name)
                errcode = tryLink(src, dst)
                if errcode:
                    return errcode
            else:
                logging.error(err)
                return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_targets'))
        src = os.path.join(folders.globalTargetInstallDirectory(), link_target_name)
        dst = os.path.join(os.getcwd(), 'yotta_targets', link_target_name)
        # if the target is already installed, rm it
        fsutils.rmRf(dst)
    else:
        t = validate.currentDirectoryTarget()
        if not t:
            return 1
        fsutils.mkDirP(folders.globalTargetInstallDirectory())
        src = os.getcwd()
        dst = os.path.join(folders.globalTargetInstallDirectory(), t.getName())

    broken_link = False
    if link_target_name:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            broken_link = True
            logging.warning(
              ('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED + 'BROKEN' + colorama.Fore.RESET #pylint: disable=no-member
            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check that the linked target is actually set as the target (or is
        # inherited from by something set as the target), if it isn't, warn the
        # user:
        if c and link_target_name != nameFromTargetSpec(args.target):
            target = c.getTarget(args.target, args.config)
            if target:
                if not target.inheritsFrom(link_target_name):
                    logging.warning(
                        'target "%s" is not used by the current target (%s), so '
                        'this link will have no effect. Perhaps you meant to '
                        'use "yotta target <targetname>" to set the build '
                        'target first.',
                        link_target_name,
                        nameFromTargetSpec(args.target)
                    )
            else:
                logging.warning(
                    'Could not check if linked target "%s" is used by the '+
                    'current target "%s": run "yotta target" to check.',
                    link_target_name,
                    nameFromTargetSpec(args.target)
                )

    else:
        logging.info('%s -> %s' % (dst, src))
    try:
        fsutils.symlink(src, dst)
    except Exception as e:
        if broken_link:
            logging.error('failed to create link (create the first half of the link first)')
        else:
            logging.error('failed to create link: %s', e)
Ejemplo n.º 32
0
def execCommand(args, following_args):
    c = None
    t = None
    if args.link_target:
        c = validate.currentDirectoryModule()
        if not c:
            return 1
        err = validate.targetNameValidationError(args.link_target)
        if err:
            logging.error(err)
            return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_targets'))
        src = os.path.join(folders.globalTargetInstallDirectory(),
                           args.link_target)
        dst = os.path.join(os.getcwd(), 'yotta_targets', args.link_target)
        # if the target is already installed, rm it
        fsutils.rmRf(dst)
    else:
        t = validate.currentDirectoryTarget()
        if not t:
            return 1
        fsutils.mkDirP(folders.globalTargetInstallDirectory())
        src = os.getcwd()
        dst = os.path.join(folders.globalTargetInstallDirectory(), t.getName())

    broken_link = False
    if args.link_target:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            broken_link = True
            logging.warning(('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED +
                            'BROKEN' + colorama.Fore.RESET  #pylint: disable=no-member
                            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check that the linked target is actually set as the target (or is
        # inherited from by something set as the target), if it isn't, warn the
        # user:
        if c and args.link_target != nameFromTargetSpec(args.target):
            target = c.getTarget(args.target, args.config)
            if target:
                if not target.inheritsFrom(args.link_target):
                    logging.warning(
                        'target "%s" is not used by the current target (%s), so '
                        'this link will have no effect. Perhaps you meant to '
                        'use "yotta target <targetname>" to set the build '
                        'target first.', args.link_target,
                        nameFromTargetSpec(args.target))
            else:
                logging.warning(
                    'Could not check if linked target "%s" is used by the ' +
                    'current target "%s": run "yotta target" to check.',
                    args.link_target, nameFromTargetSpec(args.target))

    else:
        logging.info('%s -> %s' % (dst, src))
    try:
        fsutils.symlink(src, dst)
    except Exception as e:
        if broken_link:
            logging.error(
                'failed to create link (create the first half of the link first)'
            )
        else:
            logging.error('failed to create link: %s', e)
Ejemplo n.º 33
0
def execCommand(args, following_args):
    c = None
    t = None
    if args.link_target:
        c = validate.currentDirectoryModule()
        if not c:
            return 1
        err = validate.targetNameValidationError(args.link_target)
        if err:
            logging.error(err)
            return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_targets'))
        src = os.path.join(folders.globalTargetInstallDirectory(), args.link_target)
        dst = os.path.join(os.getcwd(), 'yotta_targets', args.link_target)
        # if the target is already installed, rm it
        fsutils.rmRf(dst)
    else:
        t = validate.currentDirectoryTarget()
        if not t:
            return 1
        fsutils.mkDirP(folders.globalTargetInstallDirectory())
        src = os.getcwd()
        dst = os.path.join(folders.globalTargetInstallDirectory(), t.getName())

    broken_link = False
    if args.link_target:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            broken_link = True
            logging.warning(
              ('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED + 'BROKEN' + colorama.Fore.RESET #pylint: disable=no-member
            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check that the linked target is actually set as the target (or is
        # inherited from by something set as the target), if it isn't, warn the
        # user:
        if c and args.link_target != nameFromTargetSpec(args.target):
            target = c.getTarget(args.target, args.config)
            if target:
                if not target.inheritsFrom(args.link_target):
                    logging.warning(
                        'target "%s" is not used by the current target (%s), so '
                        'this link will have no effect. Perhaps you meant to '
                        'use "yotta target <targetname>" to set the build '
                        'target first.',
                        args.link_target,
                        nameFromTargetSpec(args.target)
                    )
            else:
                logging.warning(
                    'Could not check if linked target "%s" is used by the '+
                    'current target "%s": run "yotta target" to check.',
                    args.link_target,
                    nameFromTargetSpec(args.target)
                )

    else:
        logging.info('%s -> %s' % (dst, src))
    try:
        fsutils.symlink(src, dst)
    except Exception as e:
        if broken_link:
            logging.error('failed to create link (create the first half of the link first)')
        else:
            logging.error('failed to create link: %s', e)
Ejemplo n.º 34
0
def execCommand(args, following_args):
    # standard library modules, , ,
    import logging
    import os

    # colorama, BSD 3-Clause license, color terminal output, pip install colorama
    import colorama

    # validate, , validate things, internal
    from yotta.lib import validate
    # folders, , get places to install things, internal
    from yotta.lib import folders
    # fsutils, , misc filesystem utils, internal
    from yotta.lib import fsutils

    c = validate.currentDirectoryModule()
    if not c:
        return 1
    if args.component:
        err = validate.componentNameValidationError(args.component)
        if err:
            logging.error(err)
            return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_modules'))
        src = os.path.join(folders.globalInstallDirectory(), args.component)
        dst = os.path.join(os.getcwd(), 'yotta_modules', args.component)
        # if the component is already installed, rm it
        fsutils.rmRf(dst)
    else:
        fsutils.mkDirP(folders.globalInstallDirectory())

        src = os.getcwd()
        dst = os.path.join(folders.globalInstallDirectory(), c.getName())

    broken_link = False
    if args.component:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            broken_link = True
            logging.warning(
              ('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED + 'BROKEN' + colorama.Fore.RESET #pylint: disable=no-member
            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check if the thing we linked is actually a dependency, if it isn't
        # warn about that. To do this we may have to get the current target
        # description. This might fail, in which case we warn that we couldn't
        # complete the check:
        target = c.getTarget(args.target, args.config)
        if target:
            if not c.hasDependencyRecursively(args.component, target=target, test_dependencies=True):
                logging.warning(
                    '"%s" is not installed as a dependency, so will not '+
                    ' be built. Perhaps you meant to "yotta install %s" '+
                    'first?',
                    args.component,
                    args.component
                )
        else:
            logging.warning(
                'Could not check if linked module "%s" is installed as a '+
                'dependency, because target "%s" is not available. Run '
                '"yotta ls" to check.',
                args.component,
                args.target
            )
    else:
        logging.info('%s -> %s' % (dst, src))

    try:
        fsutils.symlink(src, dst)
    except Exception as e:
        if broken_link:
            logging.error('failed to create link (create the first half of the link first)')
        else:
            logging.error('failed to create link: %s', e)
Ejemplo n.º 35
0
Archivo: link.py Proyecto: Timmmm/yotta
def execCommand(args, following_args):
    # standard library modules, , ,
    import logging
    import os

    # colorama, BSD 3-Clause license, color terminal output, pip install colorama
    import colorama

    # validate, , validate things, internal
    from yotta.lib import validate
    # folders, , get places to install things, internal
    from yotta.lib import folders
    # fsutils, , misc filesystem utils, internal
    from yotta.lib import fsutils

    c = validate.currentDirectoryModule()
    if not c:
        return 1
    link_module_name = None
    if args.module_or_path:
        link_module_name = args.module_or_path
        err = validate.componentNameValidationError(args.module_or_path)
        if err:
            # check if the module name is really a path to a module
            if os.path.isdir(args.module_or_path):
                # make sure the first half of the link exists,
                src = os.path.abspath(args.module_or_path)
                # if it isn't a valid module, that's an error:
                dep = validate.directoryModule(src)
                if not dep:
                    logging.error("%s is not a valid module: %s", args.module_or_path, dep.getError())
                    return 1
                link_module_name = dep.getName()
                dst = os.path.join(folders.globalInstallDirectory(), link_module_name)
                errcode = tryLink(src, dst)
                if errcode:
                    return errcode
            else:
                logging.error("%s is neither a valid module name, nor a path to an existing module.", args.module_or_path)
                logging.error(err)
                return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_modules'))
        src = os.path.join(folders.globalInstallDirectory(), link_module_name)
        dst = os.path.join(os.getcwd(), 'yotta_modules', link_module_name)
        # if the component is already installed, rm it
        fsutils.rmRf(dst)
    else:
        fsutils.mkDirP(folders.globalInstallDirectory())

        src = os.getcwd()
        dst = os.path.join(folders.globalInstallDirectory(), c.getName())

    if link_module_name:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            logging.warning(
              ('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED + 'BROKEN' + colorama.Fore.RESET #pylint: disable=no-member
            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check if the thing we linked is actually a dependency, if it isn't
        # warn about that. To do this we may have to get the current target
        # description. This might fail, in which case we warn that we couldn't
        # complete the check:
        target = c.getTarget(args.target, args.config)
        if target:
            if not c.hasDependencyRecursively(link_module_name, target=target, test_dependencies=True):
                logging.warning(
                    '"%s" is not installed as a dependency, so will not '+
                    ' be built. Perhaps you meant to "yotta install %s" '+
                    'first?',
                    link_module_name,
                    link_module_name
                )
        else:
            logging.warning(
                'Could not check if linked module "%s" is installed as a '+
                'dependency, because target "%s" is not available. Run '
                '"yotta ls" to check.',
                link_module_name,
                args.target
            )
    else:
        logging.info('%s -> %s' % (dst, src))
    return tryLink(src, dst)
Ejemplo n.º 36
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
Ejemplo n.º 37
0
def execCommand(args, following_args):
    # standard library modules, , ,
    import logging
    import os

    # colorama, BSD 3-Clause license, color terminal output, pip install colorama
    import colorama

    # validate, , validate things, internal
    from yotta.lib import validate
    # folders, , get places to install things, internal
    from yotta.lib import folders
    # fsutils, , misc filesystem utils, internal
    from yotta.lib import fsutils

    c = validate.currentDirectoryModule()
    if not c:
        return 1
    link_module_name = None
    if args.module_or_path:
        link_module_name = args.module_or_path
        err = validate.componentNameValidationError(args.module_or_path)
        if err:
            # check if the module name is really a path to a module
            if os.path.isdir(args.module_or_path):
                # make sure the first half of the link exists,
                src = os.path.abspath(args.module_or_path)
                # if it isn't a valid module, that's an error:
                dep = validate.directoryModule(src)
                if not dep:
                    logging.error("%s is not a valid module: %s",
                                  args.module_or_path, dep.getError())
                    return 1
                link_module_name = dep.getName()
                dst = os.path.join(folders.globalInstallDirectory(),
                                   link_module_name)
                errcode = tryLink(src, dst)
                if errcode:
                    return errcode
            else:
                logging.error(
                    "%s is neither a valid module name, nor a path to an existing module.",
                    args.module_or_path)
                logging.error(err)
                return 1
        fsutils.mkDirP(os.path.join(os.getcwd(), 'yotta_modules'))
        src = os.path.join(folders.globalInstallDirectory(), link_module_name)
        dst = os.path.join(os.getcwd(), 'yotta_modules', link_module_name)
        # if the component is already installed, rm it
        fsutils.rmRf(dst)
    else:
        fsutils.mkDirP(folders.globalInstallDirectory())

        src = os.getcwd()
        dst = os.path.join(folders.globalInstallDirectory(), c.getName())

    if link_module_name:
        realsrc = fsutils.realpath(src)
        if src == realsrc:
            logging.warning(('%s -> %s -> ' % (dst, src)) + colorama.Fore.RED +
                            'BROKEN' + colorama.Fore.RESET  #pylint: disable=no-member
                            )
        else:
            logging.info('%s -> %s -> %s' % (dst, src, realsrc))
        # check if the thing we linked is actually a dependency, if it isn't
        # warn about that. To do this we may have to get the current target
        # description. This might fail, in which case we warn that we couldn't
        # complete the check:
        target = c.getTarget(args.target, args.config)
        if target:
            if not c.hasDependencyRecursively(
                    link_module_name, target=target, test_dependencies=True):
                logging.warning(
                    '"%s" is not installed as a dependency, so will not ' +
                    ' be built. Perhaps you meant to "yotta install %s" ' +
                    'first?', link_module_name, link_module_name)
        else:
            logging.warning(
                'Could not check if linked module "%s" is installed as a ' +
                'dependency, because target "%s" is not available. Run '
                '"yotta ls" to check.', link_module_name, args.target)
    else:
        logging.info('%s -> %s' % (dst, src))
    return tryLink(src, dst)