From 5f7c53a7bd5845a54ba1ad4776ac92324ef2f184 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Sun, 17 Nov 2019 16:39:43 +1100 Subject: sb: Align the version processing with rtems-tools. - Use the same VERSION file format as rtems-tools so a common release generation can be used. - The version.py is almost the same as rtems-tools. There are some minor differences, one is the RTEMS version is present in this file while rtems-tool uses config/rtems-release.ini. Updates #3822 --- source-builder/sb/bootstrap.py | 2 +- source-builder/sb/build.py | 2 +- source-builder/sb/check.py | 2 +- source-builder/sb/getsources.py | 2 +- source-builder/sb/options.py | 26 ++++- source-builder/sb/reports.py | 4 +- source-builder/sb/rtemsconfig.py | 2 +- source-builder/sb/setbuilder.py | 2 +- source-builder/sb/version.py | 244 ++++++++++++++++++++++++++++----------- 9 files changed, 207 insertions(+), 79 deletions(-) (limited to 'source-builder') diff --git a/source-builder/sb/bootstrap.py b/source-builder/sb/bootstrap.py index a91130d..ec7d7c3 100644 --- a/source-builder/sb/bootstrap.py +++ b/source-builder/sb/bootstrap.py @@ -244,7 +244,7 @@ def run(args): del os.environ['ACLOCAL_PATH'] optargs = { '--rtems': 'The RTEMS source directory', '--preinstall': 'Preinstall AM generation' } - log.notice('RTEMS Source Builder - RTEMS Bootstrap, %s' % (version.str())) + log.notice('RTEMS Source Builder - RTEMS Bootstrap, %s' % (version.string())) opts = options.load(sys.argv, optargs, logfile = False) if opts.get_arg('--rtems'): topdir = opts.get_arg('--rtems') diff --git a/source-builder/sb/build.py b/source-builder/sb/build.py index d9753cc..ceb179a 100644 --- a/source-builder/sb/build.py +++ b/source-builder/sb/build.py @@ -672,7 +672,7 @@ def run(args): try: optargs = { '--list-configs': 'List available configurations' } opts = options.load(args, optargs) - log.notice('RTEMS Source Builder, Package Builder, %s' % (version.str())) + log.notice('RTEMS Source Builder, Package Builder, %s' % (version.string())) opts.log_info() if not check.host_setup(opts): if not opts.force(): diff --git a/source-builder/sb/check.py b/source-builder/sb/check.py index ef8f6a4..9e4e953 100644 --- a/source-builder/sb/check.py +++ b/source-builder/sb/check.py @@ -264,7 +264,7 @@ def run(): import sys try: _opts = options.load(args = sys.argv, logfile = False) - log.notice('RTEMS Source Builder - Check, %s' % (version.str())) + log.notice('RTEMS Source Builder - Check, %s' % (version.string())) orphans = _opts.parse_args('--check-orphans', error = False, extra = False) if orphans: diff --git a/source-builder/sb/getsources.py b/source-builder/sb/getsources.py index e01d8b6..4700036 100644 --- a/source-builder/sb/getsources.py +++ b/source-builder/sb/getsources.py @@ -625,7 +625,7 @@ def run(args = sys.argv): argopts = argsp.parse_args(args[2:]) load_log(argopts.log) - log.notice('RTEMS Source Builder - Get Sources, %s' % (version.str())) + log.notice('RTEMS Source Builder - Get Sources, %s' % (version.string())) log.tracing = argopts.trace opts = load_options(args, argopts) diff --git a/source-builder/sb/options.py b/source-builder/sb/options.py index fa07c53..7e506b0 100644 --- a/source-builder/sb/options.py +++ b/source-builder/sb/options.py @@ -30,12 +30,14 @@ import re import os import string +import download import error import execute import git import log import macros import path +import sources import sys import version @@ -361,7 +363,7 @@ class command_line: def sb_released(self): if version.released(): self.defaults['rsb_released'] = '1' - self.defaults['rsb_version'] = version.str() + self.defaults['rsb_version'] = version.string() def sb_git(self): repo = git.repo(self.defaults.expand('%{_sbdir}'), self) @@ -599,7 +601,7 @@ class command_line: self.args.append('--with-tools=%s' % (rtems_tools[1])) rtems_version = self.parse_args('--rtems-version') if rtems_version is None: - rtems_version = version.version() + rtems_version = str(version.version()) else: rtems_version = rtems_version[1] self.defaults['rtems_version'] = rtems_version @@ -701,14 +703,28 @@ def load(args, optargs = None, defaults = '%{_sbdir}/defaults.mc', logfile = Tru # # Load the release settings # - version.load_release_settings(o.defaults) - + def setting_error(msg): + raise error.general(msg) + hashes = version.load_release_settings('hashes', error = setting_error) + for hash in hashes: + hs = hash[1].split() + if len(hs) != 2: + raise error.general('invalid release hash in VERSION') + sources.hash((hs[0], hash[0], hs[1]), o.defaults, setting_error) + release_path = version.load_release_setting('version', 'release_path', + raw = True, error = setting_error) + if release_path is not None: + try: + release_path = ','.join([rp.strip() for rp in release_path.split(',')]) + except: + raise error.general('invalid release path in VERSION') + download.set_release_path(release_path, o.defaults) return o def run(args): try: _opts = load(args = args, defaults = 'defaults.mc') - log.notice('RTEMS Source Builder - Defaults, %s' % (version.str())) + log.notice('RTEMS Source Builder - Defaults, %s' % (version.string())) _opts.log_info() log.notice('Options:') log.notice(str(_opts)) diff --git a/source-builder/sb/reports.py b/source-builder/sb/reports.py index 9d3a342..86a4c3a 100644 --- a/source-builder/sb/reports.py +++ b/source-builder/sb/reports.py @@ -645,7 +645,7 @@ class report: pass def release_status(self): - self.formatter.release_status(version.str()) + self.formatter.release_status(version.string()) def git_status(self): r = git.repo('.', self.opts, self.macros) @@ -896,7 +896,7 @@ def run(args): opts = options.load(args, optargs, logfile = False) if opts.get_arg('--output') and len(opts.params()) > 1: raise error.general('--output can only be used with a single config') - print('RTEMS Source Builder, Reporter, %s' % (version.str())) + print('RTEMS Source Builder, Reporter, %s' % (version.string())) opts.log_info() if not check.host_setup(opts): log.warning('forcing build with known host setup problems') diff --git a/source-builder/sb/rtemsconfig.py b/source-builder/sb/rtemsconfig.py index 6ac894e..97ede7f 100644 --- a/source-builder/sb/rtemsconfig.py +++ b/source-builder/sb/rtemsconfig.py @@ -193,7 +193,7 @@ def run(args): bsp = bsp_config(opts, prefix, opts.get_arg('--rtems-bsp')[1]) if opts.get_arg('--list'): - log.notice('RTEMS Source Builder - RTEMS Configuration, %s' % (version.str())) + log.notice('RTEMS Source Builder - RTEMS Configuration, %s' % (version.string())) opts.log_info() configs = list(bsp.keys()) for c in sorted(configs.keys()): diff --git a/source-builder/sb/setbuilder.py b/source-builder/sb/setbuilder.py index 3d10d58..09633bd 100644 --- a/source-builder/sb/setbuilder.py +++ b/source-builder/sb/setbuilder.py @@ -698,7 +698,7 @@ def run(): else: mail['to'] = macro_expand(opts.defaults, '%{_mail_tools_to}') mail['from'] = mail['mail'].from_address() - log.notice('RTEMS Source Builder - Set Builder, %s' % (version.str())) + log.notice('RTEMS Source Builder - Set Builder, %s' % (version.string())) opts.log_info() if not check.host_setup(opts): raise error.general('host build environment is not set up correctly') diff --git a/source-builder/sb/version.py b/source-builder/sb/version.py index 34fb421..296f717 100644 --- a/source-builder/sb/version.py +++ b/source-builder/sb/version.py @@ -1,36 +1,84 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2016 Chris Johns (chrisj@rtems.org) +# Copyright 2010-2018 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. # -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. # -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # -# To release the RSB create a git archive and then add a suitable VERSION file -# to the top directory. +# Releasing RTEMS Tools +# --------------------- +# +# Format: +# +# The format is INI. The file requires a `[version`] section and a `revision` +# option: +# +# [version] +# revision = +# +# The `` has the `version` and `revision` delimited by a +# single `.`. An example file is: +# +# [version] +# revision = 5.0.not_released +# +# where the `version` is `5` and the revision is `0` and the package is not +# released. The label `not_released` is reversed to mean the package is not +# released. A revision string can contain extra characters after the +# `revision` number for example `5.0-rc1` or is deploying a package +# `5.0-nasa-cfs` +# +# Packages can optionally add specialised sections to a version configuration +# files. These can be accessed via the: +# +# load_release_settings: Return the items in a section +# load_release_setting: Return an item from a section +# +# User deployment: +# +# Create a git archive and then add a suitable VERSION file to the top +# directory of the package. The package assumes your python executable is +# location in `bin` directory which is one below the top of the package's +# install prefix. +# +# Notes: +# +# This module uses os.apth for paths and assumes all paths are in the host +# format. # from __future__ import print_function +import os import sys -import download import error import git import path -import sources # # Default to an internal string. @@ -40,6 +88,7 @@ _revision = 'not_released' _version_str = '%s.%s' % (_version, _revision) _released = False _git = False +_is_loaded = False def _top(): top = path.dirname(sys.argv[0]) @@ -48,84 +97,147 @@ def _top(): return top def _load_released_version_config(): + '''Local worker to load a configuration file.''' top = _top() - for ver in [top, '..']: - if path.exists(path.join(ver, 'VERSION')): + for ver in [path.join(top, 'VERSION'), + path.join('..', 'VERSION')]: + if path.exists(path.join(ver)): try: import configparser except ImportError: import ConfigParser as configparser v = configparser.SafeConfigParser() try: - v.read(path.join(ver, 'VERSION')) - except: - raise error.general('Invalid VERSION file') - return v - return None + v.read(path.host(ver)) + except Exception as e: + raise error.general('Invalid version config format: %s: %s' % (ver, + e)) + return ver, v + return None, None def _load_released_version(): + '''Load the release data if present. If not found the package is not released. + + A release can be made by adding a file called `VERSION` to the top level + directory of a package. This is useful for user deploying a package and + making custom releases. + + The RTEMS project reserves the `rtems-version.ini` file for it's + releases. This is the base release and should not be touched by users + deploying a package. + + ''' + global _version + global _revision global _released global _version_str - v = _load_released_version_config() - if v is not None: - try: - _version_str = v.get('version', 'release') - except: - raise error.general('Invalid VERSION file') - _released = True + global _is_loaded + + if not _is_loaded: + vc, v = _load_released_version_config() + if v is not None: + try: + ver_str = v.get('version', 'revision') + except Exception as e: + raise error.general('Invalid version file: %s: %s' % (vc, e)) + ver_split = ver_str.split('.', 1) + if len(ver_split) < 2: + raise error.general('Invalid version release value: %s: %s' % (vc, + ver_str)) + ver = ver_split[0] + rev = ver_split[1] + try: + _version = int(ver) + except: + raise error.general('Invalid version config value: %s: %s' % (vc, + ver)) + _revision = rev + if 'not_released' not in ver: + _released = True + _version_str = ver_str + _is_loaded = True return _released def _load_git_version(): + global _version + global _revision global _git global _version_str - repo = git.repo(_top()) - if repo.valid(): - head = repo.head() - if repo.dirty(): - modified = ' modified' - else: - modified = '' - _version_str = '%s (%s%s)' % (_version, head[0:12], modified) - _git = True + global _is_loaded + + if not _is_loaded: + repo = git.repo(_top()) + if repo.valid(): + head = repo.head() + if repo.dirty(): + modified = 'modified' + revision_sep = '-' + sep = ' ' + else: + modified = '' + revision_sep = '' + sep = '' + _revision = '%s%s%s' % (head[0:12], revision_sep, modified) + _version_str = '%s (%s%s%s)' % (_version, head[0:12], sep, modified) + _git = True + _is_loaded = True return _git +def load_release_settings(section, error = False): + vc, v = _load_released_version_config() + items = [] + if v is not None: + try: + items = v.items(section) + except Exception as e: + if not isinstance(error, bool): + error(e) + elif error: + raise error.general('Invalid config section: %s: %s: %s' % (vc, + section, + e)) + return items + +def load_release_setting(section, option, raw = False, error = False): + vc, v = _load_released_version_config() + value = None + if v is not None: + try: + value = v.get(section, option, raw = raw) + except Exception as e: + if not isinstance(error, bool): + error(e) + elif error: + raise error.general('Invalid config section: %s: %s: %s.%s' % (vc, + section, + option, + e)) + return value + def released(): return _load_released_version() def version_control(): return _load_git_version() -def str(): - if not _released and not _git: - if not _load_released_version(): - _load_git_version() +def string(): + _load_released_version() + _load_git_version() return _version_str -def load_release_settings(macros): - def setting_error(msg): - raise error.general(msg) - - if released(): - v = _load_released_version_config() - if v is not None: - try: - hashes = v.items('hashes') - except: - hashes = [] - for hash in hashes: - hs = hash[1].split() - if len(hs) != 2: - raise error.general('invalid release hash in VERSION') - sources.hash((hs[0], hash[0], hs[1]), macros, setting_error) - try: - release_path = v.get('version', 'release_path', raw = True) - release_path = ','.join([rp.strip() for rp in release_path.split(',')]) - except: - release_path = None - download.set_release_path(release_path, macros) - def version(): + _load_released_version() + _load_git_version() return _version +def revision(): + _load_released_version() + _load_git_version() + return _revision + if __name__ == '__main__': - print('Version: %s' % (str())) + print('Version: %s' % (str(version()))) + print('Revision: %s' % (str(revision()))) + print('String: %s' % (string())) + if version() == 'undefined': + raise Exception('version is undefined') -- cgit v1.2.3