Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)