def getBuildInfo(self, sourcedir, builddir): ''' Write the build info header file, and return (path_to_written_header, set_cmake_definitions) ''' cmake_defs = '' preproc_defs = '// yotta build info, #include YOTTA_BUILD_INFO_HEADER to access\n' # standard library modules import datetime # vcs, , represent version controlled directories, internal from yotta.lib import vcs now = datetime.datetime.utcnow() vcs_instance = vcs.getVCS(sourcedir) if self.build_uuid is None: import uuid self.build_uuid = uuid.uuid4() definitions = [ ('YOTTA_BUILD_YEAR', now.year, 'UTC year'), ('YOTTA_BUILD_MONTH', now.month, 'UTC month 1-12'), ('YOTTA_BUILD_DAY', now.day, 'UTC day 1-31'), ('YOTTA_BUILD_HOUR', now.hour, 'UTC hour 0-24'), ('YOTTA_BUILD_MINUTE', now.minute, 'UTC minute 0-59'), ('YOTTA_BUILD_SECOND', now.second, 'UTC second 0-61'), ('YOTTA_BUILD_UUID', self.build_uuid, 'unique random UUID for each build'), ] if vcs_instance is not None: commit_id = None repotype = vcs_instance.__class__.__name__ try: commit_id = vcs_instance.getCommitId() except vcs.VCSNotInstalled as e: logger.warning( '%s is not installed, VCS status build info is not available', repotype) commit_id = None except vcs.VCSError as e: logger.debug('%s', e) logger.warning( 'error detecting build info: "%s", build info is not available to the build. Please check that this is a valid %s repository!', str(e).split('\n')[0], repotype) if commit_id is not None: clean_state = int(vcs_instance.isClean()) definitions += [ ('YOTTA_BUILD_VCS_ID', commit_id, 'git or mercurial hash'), ('YOTTA_BUILD_VCS_CLEAN', clean_state, 'evaluates true if the version control system was clean, otherwise false' ) ] for d in definitions: preproc_defs += '#define %s %s // %s\n' % d cmake_defs += 'set(%s "%s") # %s\n' % d buildinfo_include_file = os.path.join(builddir, 'yotta_build_info.h') self._writeFile( buildinfo_include_file, '#ifndef __YOTTA_BUILD_INFO_H__\n' + '#define __YOTTA_BUILD_INFO_H__\n' + preproc_defs + '#endif // ndef __YOTTA_BUILD_INFO_H__\n') return (buildinfo_include_file, cmake_defs)
def getBuildInfo(self, sourcedir, builddir): ''' Write the build info header file, and return (path_to_written_header, set_cmake_definitions) ''' cmake_defs = '' preproc_defs = '// yotta build info, #include YOTTA_BUILD_INFO_HEADER to access\n' # standard library modules import datetime # vcs, , represent version controlled directories, internal from yotta.lib import vcs now = datetime.datetime.utcnow() vcs_instance = vcs.getVCS(sourcedir) if self.build_uuid is None: import uuid self.build_uuid = uuid.uuid4() definitions = [ ('YOTTA_BUILD_YEAR', now.year, 'UTC year'), ('YOTTA_BUILD_MONTH', now.month, 'UTC month 1-12'), ('YOTTA_BUILD_DAY', now.day, 'UTC day 1-31'), ('YOTTA_BUILD_HOUR', now.hour, 'UTC hour 0-24'), ('YOTTA_BUILD_MINUTE', now.minute, 'UTC minute 0-59'), ('YOTTA_BUILD_SECOND', now.second, 'UTC second 0-61'), ('YOTTA_BUILD_UUID', self.build_uuid, 'unique random UUID for each build'), ] if vcs_instance is not None: commit_id = None repotype = vcs_instance.__class__.__name__ try: commit_id = vcs_instance.getCommitId() except vcs.VCSNotInstalled as e: logger.warning('%s is not installed, VCS status build info is not available', repotype) commit_id = None except vcs.VCSError as e: logger.debug('%s', e) logger.warning( 'error detecting build info: "%s", build info is not available to the build. Please check that this is a valid %s repository!', str(e).split('\n')[0], repotype ) if commit_id is not None: clean_state = int(vcs_instance.isClean()) definitions += [ ('YOTTA_BUILD_VCS_ID', commit_id, 'git or mercurial hash'), ('YOTTA_BUILD_VCS_CLEAN', clean_state, 'evaluates true if the version control system was clean, otherwise false') ] for d in definitions: preproc_defs += '#define %s %s // %s\n' % d cmake_defs += 'set(%s "%s") # %s\n' % d buildinfo_include_file = os.path.join(builddir, 'yotta_build_info.h') self._writeFile( buildinfo_include_file, '#ifndef __YOTTA_BUILD_INFO_H__\n'+ '#define __YOTTA_BUILD_INFO_H__\n'+ preproc_defs+ '#endif // ndef __YOTTA_BUILD_INFO_H__\n' ) return (buildinfo_include_file, cmake_defs)
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 __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)