[rtems-source-builder commit] sb. Add VERSION support for releasing the RSB.

Chris Johns chrisj at rtems.org
Thu Dec 3 11:26:23 UTC 2015


Module:    rtems-source-builder
Branch:    4.11
Commit:    e8f511157c396e19308a6cbed2de2dc8258f275d
Changeset: http://git.rtems.org/rtems-source-builder/commit/?id=e8f511157c396e19308a6cbed2de2dc8258f275d

Author:    Chris Johns <chrisj at rtems.org>
Date:      Thu Dec  3 22:22:17 2015 +1100

sb. Add VERSION support for releasing the RSB.

Add support to release the RSB by adding the VERSION file. The file
is a single line with the version.

Fix the reports to include the version. Update the INI file
support to include the details of the build.

Show the GIT or released version when the command starts.

Closes #2480.

---

 source-builder/defaults.mc       |   3 +
 source-builder/sb/bootstrap.py   |   2 +-
 source-builder/sb/build.py       |   2 +-
 source-builder/sb/check.py       |   2 +-
 source-builder/sb/options.py     |   9 ++-
 source-builder/sb/reports.py     | 124 +++++++++++++++++++++++++++------------
 source-builder/sb/rtemsconfig.py |   2 +-
 source-builder/sb/setbuilder.py  |   2 +-
 source-builder/sb/version.py     |  66 +++++++++++++++++++--
 9 files changed, 164 insertions(+), 48 deletions(-)

diff --git a/source-builder/defaults.mc b/source-builder/defaults.mc
index d38d090..1734033 100644
--- a/source-builder/defaults.mc
+++ b/source-builder/defaults.mc
@@ -45,6 +45,9 @@ version:             none,    none,     ''
 release:             none,    none,     ''
 buildname:           none,    none,     '%{name}'
 
+# The default is not release.
+is_rsb_release:      none,    none,     '0'
+
 # GNU triples needed to build packages
 _host:               triplet, required, ''
 _build:              triplet, required, ''
diff --git a/source-builder/sb/bootstrap.py b/source-builder/sb/bootstrap.py
index 712741c..15bd7f5 100644
--- a/source-builder/sb/bootstrap.py
+++ b/source-builder/sb/bootstrap.py
@@ -242,7 +242,7 @@ def run(args):
     try:
         optargs = { '--rtems':       'The RTEMS source directory',
                     '--preinstall':  'Preinstall AM generation' }
-        log.notice('RTEMS Source Builder - RTEMS Bootstrap, v%s' % (version.str()))
+        log.notice('RTEMS Source Builder - RTEMS Bootstrap, %s' % (version.str()))
         opts = options.load(sys.argv, optargs)
         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 3241133..b552780 100644
--- a/source-builder/sb/build.py
+++ b/source-builder/sb/build.py
@@ -534,7 +534,7 @@ def run(args):
     try:
         optargs = { '--list-configs': 'List available configurations' }
         opts = options.load(args, optargs)
-        log.notice('RTEMS Source Builder, Package Builder v%s' % (version.str()))
+        log.notice('RTEMS Source Builder, Package Builder, %s' % (version.str()))
         if not check.host_setup(opts):
             if not opts.force():
                 raise error.general('host build environment is not set up' +
diff --git a/source-builder/sb/check.py b/source-builder/sb/check.py
index d2eba4f..9930fca 100644
--- a/source-builder/sb/check.py
+++ b/source-builder/sb/check.py
@@ -162,7 +162,7 @@ def run():
     import sys
     try:
         _opts = options.load(args = sys.argv)
-        log.notice('RTEMS Source Builder - Check, v%s' % (version.str()))
+        log.notice('RTEMS Source Builder - Check, %s' % (version.str()))
         if host_setup(_opts):
             print 'Environment is ok'
         else:
diff --git a/source-builder/sb/options.py b/source-builder/sb/options.py
index c611dfe..5835821 100644
--- a/source-builder/sb/options.py
+++ b/source-builder/sb/options.py
@@ -301,6 +301,12 @@ class command_line:
             if path.exists(rsb_macros):
                 self.defaults.load(rsb_macros)
 
+    def sb_released(self):
+        if version.released():
+            self.defaults['is_rsb_released'] = '1'
+            self.defaults['_sbreleased'] = '1'
+            self.defaults['_sbversion'] = version.str()
+
     def sb_git(self):
         repo = git.repo(self.defaults.expand('%{_sbdir}'), self)
         if repo.valid():
@@ -613,6 +619,7 @@ def load(args, optargs = None, defaults = '%{_sbdir}/defaults.mc'):
     for k in overrides:
         o.defaults[k] = overrides[k]
 
+    o.sb_released()
     o.sb_git()
     o.rtems_options()
     o.process()
@@ -623,7 +630,7 @@ def load(args, optargs = None, defaults = '%{_sbdir}/defaults.mc'):
 def run(args):
     try:
         _opts = load(args = args, defaults = 'defaults.mc')
-        log.notice('RTEMS Source Builder - Defaults, v%s' % (version.str()))
+        log.notice('RTEMS Source Builder - Defaults, %s' % (version.str()))
         _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 9a20b2e..e4ef687 100644
--- a/source-builder/sb/reports.py
+++ b/source-builder/sb/reports.py
@@ -1,6 +1,6 @@
 #
 # RTEMS Tools Project (http://www.rtems.org/)
-# Copyright 2010-2013 Chris Johns (chrisj at rtems.org)
+# Copyright 2010-2015 Chris Johns (chrisj at rtems.org)
 # All rights reserved.
 #
 # This file is part of the RTEMS Tools package in 'rtems-tools'.
@@ -53,6 +53,7 @@ _line_len = 78
 
 _title = 'RTEMS Tools Project <users at rtems.org>'
 
+_release_status_text = 'RTEMS Source Builder Release'
 _git_status_text = 'RTEMS Source Builder Repository Status'
 
 def _make_path(p, *args):
@@ -104,7 +105,7 @@ class formatter(object):
 
     def buildset_start(self, nest_level, name):
         self.line('=-' * (_line_len / 2))
-        self.line('Build Set: %s' % (name))
+        self.line('Build Set: (%d) %s' % (nest_level, name))
 
     def buildset_end(self, nest_level, name):
         return
@@ -166,6 +167,16 @@ class asciidoc_formatter(formatter):
         if intro_text:
             self.line('%s' % ('\n'.join(intro_text)))
 
+    def release_status(self, release_string):
+        self.line('')
+        self.line("'''")
+        self.line('')
+        self.line('.%s' % (_release_status_text))
+        self.line('*Version*: %s;;' % (release_string))
+        self.line('')
+        self.line("'''")
+        self.line('')
+
     def git_status(self, valid, dirty, head, remotes):
         self.line('')
         self.line("'''")
@@ -293,6 +304,14 @@ class text_formatter(formatter):
         self.line('=' * _line_len)
         self.line('Report: %s' % (name))
 
+    def release_status_header(self):
+        self.line('-' * _line_len)
+        self.line('%s' % (_release_status_text))
+
+    def release_status(self, release_string):
+        self.release_status_header()
+        self.line('%s Version: %s' % (self.cini, release_string))
+
     def git_status_header(self):
         self.line('-' * _line_len)
         self.line('%s' % (_git_status_text))
@@ -324,6 +343,8 @@ class ini_formatter(text_formatter):
     def __init__(self):
         super(ini_formatter, self).__init__()
         self.cini = ';'
+        self.ini_pkg = {}
+        self.name = None
 
     def format(self):
         return 'ini'
@@ -339,25 +360,57 @@ class ini_formatter(text_formatter):
             self.line('; %s' % ('\n; '.join(intro_text)))
             self.line(';')
 
+    def epilogue(self, name):
+        pkgs = sorted(self.ini_pkg.keys())
+        for pkg in pkgs:
+            self.line('')
+            self.line('[%s]' % (pkg))
+            items = sorted(self.ini_pkg[pkg].keys())
+            for item in items:
+                i = self.ini_pkg[pkg][item]
+                if len(i) == 1:
+                    self.line('%s = "%s"' % (item, i[0]))
+                else:
+                    self.line('%s = <<<DATA' % (item))
+                    self.line('\n'.join(i))
+                    self.line('DATA')
+        self.line('')
+
+    def release_status_header(self):
+        self.line(';')
+        self.line('; %s' % (_release_status_text))
+
     def git_status_header(self):
         self.line(';')
         self.line('; %s' % (_git_status_text))
         self.line(';')
 
     def config(self, nest_level, name, _config):
-        return
+        pass
 
     def buildset_start(self, nest_level, name):
-        return
+        if name.endswith('.cfg'):
+            self.name = path.basename(name[:-4])
+            if self.name not in self.ini_pkg:
+                self.ini_pkg[self.name] = {}
+
+    def buildset_end(self, nest_level, name):
+        self.name = None
 
     def info(self, nest_level, name, info, separated):
-        return
+        if self.name:
+            if 'info' not in self.ini_pkg[self.name]:
+                self.ini_pkg[self.name]['info'] = []
+            self.ini_pkg[self.name]['info'] += info
 
     def directive(self, nest_level, name, data):
-        return
+        if self.name:
+            if name not in self.ini_pkg[self.name]:
+                self.ini_pkg[self.name][name] = []
+            self.ini_pkg[self.name][name] += data
 
     def files(self, nest_level, singular, plural, _files):
-        return
+        pass
 
 class xml_formatter(formatter):
     def __init__(self):
@@ -377,6 +430,11 @@ class xml_formatter(formatter):
     def epilogue(self, name):
         self.line('</RTEMSSourceBuilderReport>')
 
+    def release_status(self, release_string):
+        self.line('\t<Release>')
+        self.line('\t\t<Version>%s</Version>' % (release_string))
+        self.line('\t</Release>')
+
     def git_status(self, valid, dirty, head, remotes):
         self.line('\t<Git>')
         if valid:
@@ -469,7 +527,7 @@ class report:
         self.files = { 'buildsets':[], 'configs':[] }
 
     def output(self, text):
-        self.out += text + '\n'
+        self.formatter.line(text)
 
     def is_ini(self):
         return self.formatter.format() == 'ini'
@@ -480,6 +538,9 @@ class report:
     def footer(self):
         pass
 
+    def release_status(self):
+        self.formatter.release_status(version.str())
+
     def git_status(self):
         r = git.repo('.', self.opts, self.macros)
         self.formatter.git_status(r.valid(), r.dirty(), r.head(), r.remotes())
@@ -487,7 +548,10 @@ class report:
     def introduction(self, name, intro_text = None):
         now = datetime.datetime.now().ctime()
         self.formatter.introduction(name, now, intro_text)
-        self.git_status()
+        if version.released():
+            self.release_status()
+        else:
+            self.git_status()
 
     def epilogue(self, name):
         self.formatter.epilogue(name)
@@ -504,11 +568,13 @@ class report:
         self.formatter.config_end(self.bset_nesting + 1, name)
 
     def buildset_start(self, name):
+        self.bset_nesting += 1
         self.files['buildsets'] += [name]
         self.formatter.buildset_start(self.bset_nesting, name)
 
     def buildset_end(self, name):
         self.formatter.buildset_end(self.bset_nesting, name)
+        self.bset_nesting -= 1
 
     def source(self, macros):
         def err(msg):
@@ -546,6 +612,13 @@ class report:
         if directive is not None:
             self.formatter.directive(self.bset_nesting + 2, name, directive)
 
+    def tree_packages(self, tree, packages = []):
+        if 'bset' in tree:
+            for node in sorted(tree['bset'].keys()):
+                packages += [_tree_name(node)]
+                packages += self.tree_packages(tree['bset'][node], packages)
+        return set(packages)
+
     def tree_sources(self, name, tree, sources = []):
         if 'cfg' in tree:
             packages = {}
@@ -626,26 +699,6 @@ class report:
                                        prefix_char,
                                        prefix)
 
-    def generate_ini_node(self, name, tree, sections = []):
-        if name not in sections:
-            sections += [name]
-            self.output('')
-            self.output('[%s]' % (name))
-            if 'bset' in tree and len(tree['bset']):
-                self.output(' packages = %s' % \
-                                (', '.join([_tree_name(n) for n in sorted(tree['bset'])])))
-            if 'cfg' in tree:
-                packages = {}
-                if 'sources' in tree['cfg']:
-                    _merge(packages, tree['cfg']['sources'])
-                if 'patches' in tree['cfg']:
-                    _merge(packages, tree['cfg']['patches'])
-                for package in packages:
-                    self.output(' %s = %s' % (package, ', '.join([s[0] for s in packages[package]])))
-            if 'bset' in tree:
-                for node in sorted(tree['bset'].keys()):
-                    self.generate_ini_node(_tree_name(node), tree['bset'][node], sections)
-
     def generate_ini_source(self, sources):
         self.output('')
         self.output('[source]')
@@ -664,7 +717,6 @@ class report:
             self.output(' %s = %s' % (source[0], hash))
 
     def generate_ini(self):
-        #self.output(pp.pformat(self.tree))
         nodes = sorted([node for node in self.tree.keys() if node != 'bset'])
         self.output(';')
         self.output('; Configuration Tree:')
@@ -681,13 +733,9 @@ class report:
         sources = sorted(set(sources))
         self.generate_ini_source(sources)
         self.generate_ini_hash(sources)
-        for node in nodes:
-            self.generate_ini_node(_tree_name(node), self.tree[node])
 
     def write(self, name):
         self.out = self.formatter.post_process()
-        if self.is_ini():
-            self.generate_ini()
         if name is not None:
             try:
                 o = open(path.host(name), "w")
@@ -698,7 +746,6 @@ class report:
                 raise error.general('writing output file: %s: %s' % (name, err))
 
     def generate(self, name, tree = None, opts = None, macros = None):
-        self.bset_nesting += 1
         self.buildset_start(name)
         if tree is None:
             tree = self.tree
@@ -715,16 +762,19 @@ class report:
             if c.endswith('.bset'):
                 self.generate(c, tree[name]['bset'], bset.opts, macros)
             elif c.endswith('.cfg'):
+                self.buildset_start(c)
                 self.config(config.file(c, bset.opts, macros),
                             tree[name]['cfg'], bset.opts, macros)
+                self.buildset_end(c)
             else:
                 raise error.general('invalid config type: %s' % (c))
         self.buildset_end(name)
-        self.bset_nesting -= 1
 
     def create(self, inname, outname = None, intro_text = None):
         self.introduction(inname, intro_text)
         self.generate(inname)
+        if self.is_ini():
+            self.generate_ini()
         self.epilogue(inname)
         self.write(outname)
 
@@ -737,7 +787,7 @@ def run(args):
         opts = options.load(args, optargs)
         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 v%s' % (version.str())
+        print 'RTEMS Source Builder, Reporter, %s' % (version.str())
         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 dcd1394..f91183e 100644
--- a/source-builder/sb/rtemsconfig.py
+++ b/source-builder/sb/rtemsconfig.py
@@ -191,7 +191,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, v%s' % (version.str()))
+            log.notice('RTEMS Source Builder - RTEMS Configuration, %s' % (version.str()))
             opts.log_info()
             configs = bsp.keys()
             for c in sorted(configs.keys()):
diff --git a/source-builder/sb/setbuilder.py b/source-builder/sb/setbuilder.py
index 3b05cff..01062ab 100644
--- a/source-builder/sb/setbuilder.py
+++ b/source-builder/sb/setbuilder.py
@@ -468,7 +468,7 @@ def run():
                     '--report-format': 'The report format (text, html, asciidoc).' }
         mailer.append_options(optargs)
         opts = options.load(sys.argv, optargs)
-        log.notice('RTEMS Source Builder - Set Builder, v%s' % (version.str()))
+        log.notice('RTEMS Source Builder - Set Builder, %s' % (version.str()))
         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 802fafa..95b58cf 100644
--- a/source-builder/sb/version.py
+++ b/source-builder/sb/version.py
@@ -1,6 +1,6 @@
 #
 # RTEMS Tools Project (http://www.rtems.org/)
-# Copyright 2010-2014 Chris Johns (chrisj at rtems.org)
+# Copyright 2010-2015 Chris Johns (chrisj at rtems.org)
 # All rights reserved.
 #
 # This file is part of the RTEMS Tools package in 'rtems-tools'.
@@ -18,17 +18,73 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #
-# Manage paths locally. The internally the path is in Unix or shell format and
-# we convert to the native format when performing operations at the Python
-# level. This allows macro expansion to work.
+# To release the RSB create a git archive and then add a suitable VERSION file
+# to the top directory.
 #
 
+import sys
+
+import error
+import git
+import path
+
 major = 4
 minor = 11
 revision = 0
 
+#
+# Default to an internal string.
+#
+_version_str =  '%d.%d.%d' % (major, minor, revision)
+_released = False
+_git = False
+
+def _top():
+    top = path.dirname(sys.argv[0])
+    if len(top) == 0:
+        top = '.'
+    return top
+
+def _load_released_version():
+    global _released
+    global _version_str
+    top = _top()
+    for ver in [top, '..']:
+        if path.exists(path.join(ver, 'VERSION')):
+            try:
+                with open(path.join(ver, 'VERSION')) as v:
+                    _version_str = v.readline().strip()
+                v.close()
+                _released = True
+            except:
+                raise error.general('Cannot access the VERSION file')
+    return _released
+
+def _load_git_version():
+    global _git
+    global _version_str
+    repo = git.repo(_top())
+    if repo.valid():
+        head = repo.head()
+        if repo.dirty():
+            modified = ' modified'
+        else:
+            modified = ''
+        _version_str = '%d.%d.%d (%s%s)' % (major, minor, revision, head[0:12], modified)
+        _git = True
+    return _git
+
+def released():
+    return _load_released_version()
+
+def version_control():
+    return _load_git_version()
+
 def str():
-    return '%d.%d.%d'% (major, minor, revision)
+    if not _released and not _git:
+        if not _load_released_version():
+            _load_git_version()
+    return _version_str
 
 if __name__ == '__main__':
     print 'major = %d' % (major)



More information about the vc mailing list