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)
def resolveDependencyGraph(target, top_component, available_modules, processed=None): from collections import OrderedDict r = OrderedDict() if processed is None: processed = set() if not 'modules' in r: r['modules'] = [] module_description = OrderedDict([ ('name', top_component.getName()), ('version', str(top_component.getVersion())), ('path', top_component.path), ]) if top_component.installedLinked(): module_description['linkedTo'] = fsutils.realpath(top_component.path) if top_component.is_test_dependency: module_description['testOnly'] = True specs = dict([(x.name, x) for x in top_component.getDependencySpecs(target=target)]) deps = top_component.getDependencies( available_components=available_modules, target=target, test=True, warnings=False) if not top_component: module_description['errors'] = [top_component.getError()] specifications = [] for name, dep in deps.items(): spec_info = { 'name': name, 'version': str(specs[name].nonShrinkwrappedVersionReq()), } if specs[name].isShrinkwrapped(): spec_info['shrinkwrapped'] = str(specs[name].versionReq()) if specs[name].is_test_dependency: spec_info['testOnly'] = True specifications.append(spec_info) if len(specifications): module_description['specifications'] = specifications processed.add(top_component.getName()) r['modules'].append(module_description) for name, dep in deps.items(): if not name in processed: r['modules'] += resolveDependencyGraph(target, dep, available_modules, processed)['modules'] return r
def resolveDependencyGraph(target, top_component, available_modules, processed=None, test=True): from collections import OrderedDict r = OrderedDict() if processed is None: processed = set() if not 'modules' in r: r['modules'] = [] module_description = OrderedDict([ ('name', top_component.getName()), ('version', str(top_component.getVersion())), ('path', top_component.path), ]) if top_component.installedLinked(): module_description['linkedTo'] = fsutils.realpath(top_component.path) if top_component.is_test_dependency: module_description['testOnly'] = True specs = dict([(x.name, x) for x in top_component.getDependencySpecs(target=target)]) deps = top_component.getDependencies( available_components = available_modules, target = target, test = test, warnings = False ) if not top_component: module_description['errors'] = [top_component.getError()] specifications = [] for name, dep in deps.items(): spec_info = { 'name': name, 'version': str(specs[name].nonShrinkwrappedVersionReq()), } if specs[name].isShrinkwrapped(): spec_info['shrinkwrapped'] = str(specs[name].versionReq()) if specs[name].is_test_dependency: spec_info['testOnly'] = True specifications.append(spec_info) if len(specifications): module_description['specifications'] = specifications processed.add(top_component.getName()) r['modules'].append(module_description) if test == 'toplevel': test = False for name, dep in deps.items(): if not name in processed: r['modules'] += resolveDependencyGraph(target, dep, available_modules, processed, test=test)['modules'] return r
def displayCurrentTarget(args): if not args.plain: DIM = colorama.Style.DIM #pylint: disable=no-member BRIGHT = colorama.Style.BRIGHT #pylint: disable=no-member GREEN = colorama.Fore.GREEN #pylint: disable=no-member RED = colorama.Fore.RED #pylint: disable=no-member RESET = colorama.Style.RESET_ALL #pylint: disable=no-member else: DIM = BRIGHT = GREEN = RED = RESET = u'' line = u'' c = component.Component(os.getcwd()) if c.isApplication(): app_path = c.path else: app_path = None derived_target, errors = target.getDerivedTarget( args.target, c.targetsPath(), application_dir=app_path, install_missing=False, shrinkwrap=c.getShrinkwrap()) for error in errors: logging.error(error) if derived_target is None: line = BRIGHT + RED + args.target + u' missing' + RESET else: for t in derived_target.hierarchy: if len(line): line += '\n' if t: line += t.getName() + DIM + u' ' + str(t.getVersion()) + RESET if t.installedLinked(): line += GREEN + BRIGHT + u' -> ' + RESET + GREEN + fsutils.realpath( t.path) else: line += BRIGHT + RED + t.getName() + DIM + u' ' + str( t.getVersion()) + BRIGHT + u' missing' line += RESET base_spec = t.baseTargetSpec() if base_spec: # if the last target in the hierarchy has a base spec, then the # hierarchy is incomplete: line += '\n' + BRIGHT + RED + base_spec.name + u' ' + base_spec.versionReq( ) + u' missing' if u'unicode' in str(type(line)): # python 2.7 print(line.encode('utf-8')) else: print(line) return len(errors)
def tryLink(src, dst): # fsutils, , misc filesystem utils, internal from yotta.lib import fsutils try: fsutils.symlink(src, dst) except Exception as e: if src == fsutils.realpath(src): logging.error('failed to create link (create the first half of the link first)') else: logging.error('failed to create link: %s', e) return 1 return 0
def displayCurrentTarget(args): if not args.plain: DIM = colorama.Style.DIM #pylint: disable=no-member BRIGHT = colorama.Style.BRIGHT #pylint: disable=no-member GREEN = colorama.Fore.GREEN #pylint: disable=no-member RED = colorama.Fore.RED #pylint: disable=no-member RESET = colorama.Style.RESET_ALL #pylint: disable=no-member else: DIM = BRIGHT = GREEN = RED = RESET = u'' line = u'' c = component.Component(os.getcwd()) if c.isApplication(): app_path = c.path else: app_path = None derived_target, errors = target.getDerivedTarget( args.target, c.targetsPath(), application_dir=app_path, install_missing=False ) for error in errors: logging.error(error) if derived_target is None: line = BRIGHT + RED + args.target + u' missing' + RESET else: for t in derived_target.hierarchy: if len(line): line += '\n' if t: line += t.getName() + DIM + u' ' + str(t.getVersion()) + RESET if t.installedLinked(): line += GREEN + BRIGHT + u' -> ' + RESET + GREEN + fsutils.realpath(t.path) else: line += BRIGHT + RED + t.getName() + DIM + u' ' + str(t.getVersion()) + BRIGHT + u' missing' line += RESET base_spec = t.baseTargetSpec() if base_spec: # if the last target in the hierarchy has a base spec, then the # hierarchy is incomplete: line += '\n' + BRIGHT + RED + base_spec.name + u' ' + base_spec.versionReq() + u' missing' if u'unicode' in str(type(line)): # python 2.7 print(line.encode('utf-8')) else: print(line) return len(errors)
def resolveDependencyGraph(target, top_component, available_modules, processed=None): from collections import OrderedDict r = OrderedDict() if processed is None: processed = set() if not "modules" in r: r["modules"] = [] module_description = OrderedDict( [("name", top_component.getName()), ("version", str(top_component.getVersion())), ("path", top_component.path)] ) if top_component.installedLinked(): module_description["linkedTo"] = fsutils.realpath(top_component.path) if top_component.is_test_dependency: module_description["testOnly"] = True specs = dict([(x.name, x) for x in top_component.getDependencySpecs(target=target)]) deps = top_component.getDependencies( available_components=available_modules, target=target, test=True, warnings=False ) if not top_component: module_description["errors"] = [top_component.getError()] specifications = [] for name, dep in deps.items(): spec_info = {"name": name, "version": str(specs[name].nonShrinkwrappedVersionReq())} if specs[name].isShrinkwrapped(): spec_info["shrinkwrapped"] = str(specs[name].versionReq()) if specs[name].is_test_dependency: spec_info["testOnly"] = True specifications.append(spec_info) if len(specifications): module_description["specifications"] = specifications processed.add(top_component.getName()) r["modules"].append(module_description) for name, dep in deps.items(): if not name in processed: r["modules"] += resolveDependencyGraph(target, dep, available_modules, processed)["modules"] return r
def __init__( self, path, description_filename, installed_linked, schema_filename = None, latest_suitable_version = None, inherit_shrinkwrap = None ): # version, , represent versions and specifications, internal from yotta.lib import version # vcs, , represent version controlled directories, internal from yotta.lib import vcs # resolve links at creation time, to minimise path lengths: self.unresolved_path = path self.path = fsutils.realpath(path) self.installed_linked = installed_linked self.vcs = None self.error = None self.latest_suitable_version = latest_suitable_version self.version = None self.description_filename = description_filename self.ignore_list_fname = Ignore_List_Fname self.ignore_patterns = copy.copy(Default_Publish_Ignore) self.origin_info = None description_file = os.path.join(path, description_filename) if os.path.isfile(description_file): try: self.description = ordered_json.load(description_file) if self.description: if not 'name' in self.description: raise Exception('missing "name"') if 'version' in self.description: self.version = version.Version(self.description['version']) else: raise Exception('missing "version"') except Exception as e: self.description = OrderedDict() self.error = "Description invalid %s: %s" % (description_file, e); logger.debug(self.error) raise InvalidDescription(self.error) else: self.error = "No %s file." % description_filename self.description = OrderedDict() try: with open(os.path.join(path, self.ignore_list_fname), 'r') as ignorefile: self.ignore_patterns += self._parseIgnoreFile(ignorefile) except IOError as e: if e.errno != errno.ENOENT: raise # warn about invalid yotta versions before schema errors (as new yotta # might introduce new schema) yotta_version_spec = None if self.description and self.description.get('yotta', None): try: yotta_version_spec = version.Spec(self.description['yotta']) except ValueError as e: logger.warning( "could not parse yotta version spec '%s' from %s: it "+ "might require a newer version of yotta", self.description['yotta'], self.description['name'] ) if yotta_version_spec is not None: import yotta yotta_version = version.Version(yotta.__version__) if not yotta_version_spec.match(yotta_version): self.error = "requires yotta version %s (current version is %s). see http://yottadocs.mbed.com for update instructions" % ( str(yotta_version_spec), str(yotta_version) ) if self.description and schema_filename and not self.path in self.schema_errors_displayed: self.schema_errors_displayed.add(self.path) have_errors = False with open(schema_filename, 'r') as schema_file: schema = json.load(schema_file) validator = jsonschema.Draft4Validator(schema) for error in validator.iter_errors(self.description): if not have_errors: logger.warning(u'%s has invalid %s:' % ( os.path.split(self.path.rstrip('/'))[1], description_filename )) have_errors = True logger.warning(u" %s value %s" % (u'.'.join([str(x) for x in error.path]), error.message)) # for now schema validation errors aren't fatal... will be soon # though! #if have_errors: # raise InvalidDescription('Invalid %s' % description_filename) self.inherited_shrinkwrap = None self.shrinkwrap = None # we can only apply shrinkwraps to instances with valid descriptions: # instances do not become valid after being invalid so this is safe # (but it means you cannot trust the shrinkwrap of an invalid # component) # (note that it is unsafe to use the __bool__ operator on self here as # we are not fully constructed) if self.description: self.inherited_shrinkwrap = inherit_shrinkwrap self.shrinkwrap = tryReadJSON(os.path.join(path, Shrinkwrap_Fname), Shrinkwrap_Schema) if self.shrinkwrap: logger.warning('dependencies of %s are pegged by yotta-shrinkwrap.json', self.getName()) if self.inherited_shrinkwrap: logger.warning('shrinkwrap in %s overrides inherited shrinkwrap', self.getName()) #logger.info('%s created with inherited_shrinkwrap %s', self.getName(), self.inherited_shrinkwrap) self.vcs = vcs.getVCS(path)
def format(self, component, processed, indent=u"", tee=u"", installed_at=u"", test_dep=False, spec=None): r = u"" if self.use_colours: DIM = colorama.Style.DIM # pylint: disable=no-member BRIGHT = colorama.Style.BRIGHT # pylint: disable=no-member GREEN = colorama.Fore.GREEN # pylint: disable=no-member RED = colorama.Fore.RED # pylint: disable=no-member RESET = colorama.Style.RESET_ALL # pylint: disable=no-member else: DIM = BRIGHT = GREEN = RED = RESET = u"" mods_path = component.modulesPath() deps = component.getDependencies( available_components=self.available, target=self.target, test=True, warnings=False ) specs = dict([(x.name, x) for x in component.getDependencySpecs(target=self.target)]) def isTestOnly(name): return specs[name].is_test_dependency def shouldDisplay(x): if self.list_all: # list everything everywhere (apart from test dependencies of test # dependencies, which should be considered irrelevant) if component.isTestDependency() and isTestOnly(x[0]): return False else: return True if not isTestOnly(x[0]) or not len(indent): # this is non-test dependency, or a top-level test dependency if not x[1]: # if it's missing, display it return True if x[1].path == os.path.join(mods_path, x[0]): # if it's installed in this module, display it return True if x[0] in deps_here: # if it's first depended on by this module, then display it return True # everything else shouldn't be displayed here return False origin_descr = "" if self.display_origin: origin = component.origin() if origin is not None: if origin.startswith("github://"): origin_descr = " (" + origin[9:] + ")" else: origin_descr = " (" + friendlyRegistryName(origin, short=True) + ")" line = indent[:-2] + tee + component.getName() + u" " + DIM + str(component.getVersion()) + origin_descr + RESET if spec and not spec.match(component.getVersion()): line += u" " + RESET + BRIGHT + RED + str(spec) + RESET if test_dep: line += u" " + DIM + u"(test dependency)" + RESET if len(installed_at): line += u" " + DIM + installed_at + RESET if component.installedLinked(): line += GREEN + BRIGHT + u" -> " + RESET + GREEN + fsutils.realpath(component.path) + RESET r += line + "\n" deps_here = [x for x in list(deps.keys()) if (x not in processed)] print_deps = [x for x in list(deps.items()) if shouldDisplay(x)] processed += [x[0] for x in print_deps] for (name, dep), last in islast(print_deps): if last: next_indent = indent + u" " tee = self.L_Char + self.Dash_Char + u" " next_tee = self.L_Char + self.Dash_Char + u" " else: next_indent = indent + self.Pipe_Char + u" " tee = self.T_Char + self.Dash_Char + u" " next_tee = self.T_Char + self.Dash_Char + u" " test_dep_status = u"" if isTestOnly(name): test_dep_status = u" (test dependency)" version_req = specs[name].nonShrinkwrappedVersionReq() if not dep: r += ( indent + tee + name + u" " + version_req + test_dep_status + BRIGHT + RED + " missing" + RESET + "\n" ) else: spec = access.remoteComponentFor(name, version_req, "modules").versionSpec() if not spec: spec_descr = u"" elif spec.match(dep.getVersion()): spec_descr = u" " + str(spec) else: spec_descr = u" " + RESET + BRIGHT + RED + str(spec) spec_descr += test_dep_status if name in deps_here: # dependencies that are first used here may actually be # installed higher up our dependency tree, if they are, # illustrate that: if dep.path == os.path.join(mods_path, name): r += self.format(dep, processed, next_indent, next_tee, test_dep=isTestOnly(name), spec=spec) else: r += self.format( dep, processed, next_indent, next_tee, installed_at=relpathIfSubdir(dep.unresolved_path), test_dep=isTestOnly(name), spec=spec, ) else: r += indent + tee + DIM + name + spec_descr + RESET + "\n" return r
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)
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)
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)
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)
def format(self, component, processed, indent=u'', tee=u'', installed_at=u'', test_dep=False, spec=None): r = u'' if self.use_colours: DIM = colorama.Style.DIM #pylint: disable=no-member BRIGHT = colorama.Style.BRIGHT #pylint: disable=no-member GREEN = colorama.Fore.GREEN #pylint: disable=no-member RED = colorama.Fore.RED #pylint: disable=no-member RESET = colorama.Style.RESET_ALL #pylint: disable=no-member else: DIM = BRIGHT = GREEN = RED = RESET = u'' mods_path = component.modulesPath() deps = component.getDependencies(available_components=self.available, target=self.target, test=True, warnings=False) specs = dict([(x.name, x) for x in component.getDependencySpecs(target=self.target) ]) def isTestOnly(name): return specs[name].is_test_dependency def shouldDisplay(x): if self.list_all: # list everything everywhere (apart from test dependencies of test # dependencies, which should be considered irrelevant) if component.isTestDependency() and isTestOnly(x[0]): return False else: return True if (not isTestOnly(x[0]) or not len(indent)): # this is non-test dependency, or a top-level test dependency if not x[1]: # if it's missing, display it return True if x[1].path == os.path.join(mods_path, x[0]): # if it's installed in this module, display it return True if x[0] in deps_here: # if it's first depended on by this module, then display it return True # everything else shouldn't be displayed here return False origin_descr = '' if self.display_origin: origin = component.origin() if origin is not None: if origin.startswith('github://'): origin_descr = ' (' + origin[9:] + ')' else: origin_descr = ' (' + friendlyRegistryName( origin, short=True) + ')' line = indent[:-2] + tee + component.getName() + u' ' + DIM + str( component.getVersion()) + origin_descr + RESET if spec and not spec.match(component.getVersion()): line += u' ' + RESET + BRIGHT + RED + str(spec) + RESET if test_dep: line += u' ' + DIM + u'(test dependency)' + RESET if len(installed_at): line += u' ' + DIM + installed_at + RESET if component.installedLinked(): line += GREEN + BRIGHT + u' -> ' + RESET + GREEN + fsutils.realpath( component.path) + RESET r += line + '\n' deps_here = [x for x in list(deps.keys()) if (x not in processed)] print_deps = [x for x in list(deps.items()) if shouldDisplay(x)] processed += [x[0] for x in print_deps] for (name, dep), last in islast(print_deps): if last: next_indent = indent + u' ' tee = self.L_Char + self.Dash_Char + u' ' next_tee = self.L_Char + self.Dash_Char + u' ' else: next_indent = indent + self.Pipe_Char + u' ' tee = self.T_Char + self.Dash_Char + u' ' next_tee = self.T_Char + self.Dash_Char + u' ' test_dep_status = u'' if isTestOnly(name): test_dep_status = u' (test dependency)' version_req = specs[name].nonShrinkwrappedVersionReq() if not dep: r += indent + tee + name + u' ' + version_req + test_dep_status + BRIGHT + RED + ' missing' + RESET + '\n' else: spec = access.remoteComponentFor(name, version_req, 'modules').versionSpec() if not spec: spec_descr = u'' elif spec.match(dep.getVersion()): spec_descr = u' ' + str(spec) else: spec_descr = u' ' + RESET + BRIGHT + RED + str(spec) spec_descr += test_dep_status if name in deps_here: # dependencies that are first used here may actually be # installed higher up our dependency tree, if they are, # illustrate that: if dep.path == os.path.join(mods_path, name): r += self.format(dep, processed, next_indent, next_tee, test_dep=isTestOnly(name), spec=spec) else: r += self.format(dep, processed, next_indent, next_tee, installed_at=relpathIfSubdir( dep.unresolved_path), test_dep=isTestOnly(name), spec=spec) else: r += indent + tee + DIM + name + spec_descr + RESET + '\n' return r
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)
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)
def __init__(self, path, description_filename, installed_linked, schema_filename=None, latest_suitable_version=None, inherit_shrinkwrap=None): # version, , represent versions and specifications, internal from yotta.lib import version # vcs, , represent version controlled directories, internal from yotta.lib import vcs # resolve links at creation time, to minimise path lengths: self.unresolved_path = path self.path = fsutils.realpath(path) self.installed_linked = installed_linked self.vcs = None self.error = None self.latest_suitable_version = latest_suitable_version self.version = None self.description_filename = description_filename self.ignore_list_fname = Ignore_List_Fname self.ignore_patterns = copy.copy(Default_Publish_Ignore) self.origin_info = None description_file = os.path.join(path, description_filename) if os.path.isfile(description_file): try: self.description = ordered_json.load(description_file) if self.description: if not 'name' in self.description: raise Exception('missing "name"') if 'version' in self.description: self.version = version.Version( self.description['version']) else: raise Exception('missing "version"') except Exception as e: self.description = OrderedDict() self.error = "Description invalid %s: %s" % (description_file, e) logger.debug(self.error) raise InvalidDescription(self.error) else: self.error = "No %s file." % description_filename self.description = OrderedDict() try: with open(os.path.join(path, self.ignore_list_fname), 'r') as ignorefile: self.ignore_patterns += self._parseIgnoreFile(ignorefile) except IOError as e: if e.errno != errno.ENOENT: raise # warn about invalid yotta versions before schema errors (as new yotta # might introduce new schema) yotta_version_spec = None if self.description and self.description.get('yotta', None): try: yotta_version_spec = version.Spec(self.description['yotta']) except ValueError as e: logger.warning( "could not parse yotta version spec '%s' from %s: it " + "might require a newer version of yotta", self.description['yotta'], self.description['name']) if yotta_version_spec is not None: import yotta yotta_version = version.Version(yotta.__version__) if not yotta_version_spec.match(yotta_version): self.error = "requires yotta version %s (current version is %s). see http://yottadocs.mbed.com for update instructions" % ( str(yotta_version_spec), str(yotta_version)) if self.description and schema_filename and not self.path in self.schema_errors_displayed: self.schema_errors_displayed.add(self.path) have_errors = False with open(schema_filename, 'r') as schema_file: schema = json.load(schema_file) validator = jsonschema.Draft4Validator(schema) for error in validator.iter_errors(self.description): if not have_errors: logger.warning(u'%s has invalid %s:' % (os.path.split( self.path.rstrip('/'))[1], description_filename)) have_errors = True logger.warning( u" %s value %s" % (u'.'.join([str(x) for x in error.path]), error.message)) # for now schema validation errors aren't fatal... will be soon # though! #if have_errors: # raise InvalidDescription('Invalid %s' % description_filename) self.inherited_shrinkwrap = None self.shrinkwrap = None # we can only apply shrinkwraps to instances with valid descriptions: # instances do not become valid after being invalid so this is safe # (but it means you cannot trust the shrinkwrap of an invalid # component) # (note that it is unsafe to use the __bool__ operator on self here as # we are not fully constructed) if self.description: if inherit_shrinkwrap is not None: # when inheriting a shrinkwrap, check that this module is # listed in the shrinkwrap, otherwise emit a warning: if next((x for x in inherit_shrinkwrap.get('modules', []) if x['name'] == self.getName()), None) is None: logger.warning("%s missing from shrinkwrap", self.getName()) self.inherited_shrinkwrap = inherit_shrinkwrap self.shrinkwrap = tryReadJSON(os.path.join(path, Shrinkwrap_Fname), Shrinkwrap_Schema) if self.shrinkwrap: logger.warning( 'dependencies of %s are pegged by yotta-shrinkwrap.json', self.getName()) if self.inherited_shrinkwrap: logger.warning( 'shrinkwrap in %s overrides inherited shrinkwrap', self.getName()) #logger.info('%s created with inherited_shrinkwrap %s', self.getName(), self.inherited_shrinkwrap) self.vcs = vcs.getVCS(path)