source: rtems-source-builder/source-builder/sb/version.py

Last change on this file was 5f7c53a, checked in by Chris Johns <chrisj@…>, on Nov 17, 2019 at 5:39:43 AM

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

  • Property mode set to 100644
File size: 7.9 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2018 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# 1. Redistributions of source code must retain the above copyright notice,
12# this list of conditions and the following disclaimer.
13#
14# 2. Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31#
32# Releasing RTEMS Tools
33# ---------------------
34#
35# Format:
36#
37#  The format is INI. The file requires a `[version`] section and a `revision`
38#  option:
39#
40#   [version]
41#   revision = <version-string>
42#
43#  The `<version-string>` has the `version` and `revision` delimited by a
44#  single `.`. An example file is:
45#
46#   [version]
47#   revision = 5.0.not_released
48#
49#  where the `version` is `5` and the revision is `0` and the package is not
50#  released. The label `not_released` is reversed to mean the package is not
51#  released. A revision string can contain extra characters after the
52#  `revision` number for example `5.0-rc1` or is deploying a package
53#  `5.0-nasa-cfs`
54#
55#  Packages can optionally add specialised sections to a version configuration
56#  files. These can be accessed via the:
57#
58#   load_release_settings: Return the items in a section
59#   load_release_setting: Return an item from a section
60#
61# User deployment:
62#
63#  Create a git archive and then add a suitable VERSION file to the top
64#  directory of the package. The package assumes your python executable is
65#  location in `bin` directory which is one below the top of the package's
66#  install prefix.
67#
68# Notes:
69#
70#  This module uses os.apth for paths and assumes all paths are in the host
71#  format.
72#
73
74from __future__ import print_function
75
76import os
77import sys
78
79import error
80import git
81import path
82
83#
84# Default to an internal string.
85#
86_version = '5'
87_revision = 'not_released'
88_version_str = '%s.%s' % (_version, _revision)
89_released = False
90_git = False
91_is_loaded = False
92
93def _top():
94    top = path.dirname(sys.argv[0])
95    if len(top) == 0:
96        top = '.'
97    return top
98
99def _load_released_version_config():
100    '''Local worker to load a configuration file.'''
101    top = _top()
102    for ver in [path.join(top, 'VERSION'),
103                path.join('..', 'VERSION')]:
104        if path.exists(path.join(ver)):
105            try:
106                import configparser
107            except ImportError:
108                import ConfigParser as configparser
109            v = configparser.SafeConfigParser()
110            try:
111                v.read(path.host(ver))
112            except Exception as e:
113                raise error.general('Invalid version config format: %s: %s' % (ver,
114                                                                               e))
115            return ver, v
116    return None, None
117
118def _load_released_version():
119    '''Load the release data if present. If not found the package is not released.
120
121    A release can be made by adding a file called `VERSION` to the top level
122    directory of a package. This is useful for user deploying a package and
123    making custom releases.
124
125    The RTEMS project reserves the `rtems-version.ini` file for it's
126    releases. This is the base release and should not be touched by users
127    deploying a package.
128
129    '''
130    global _version
131    global _revision
132    global _released
133    global _version_str
134    global _is_loaded
135
136    if not _is_loaded:
137        vc, v = _load_released_version_config()
138        if v is not None:
139            try:
140                ver_str = v.get('version', 'revision')
141            except Exception as e:
142                raise error.general('Invalid version file: %s: %s' % (vc, e))
143            ver_split = ver_str.split('.', 1)
144            if len(ver_split) < 2:
145                raise error.general('Invalid version release value: %s: %s' % (vc,
146                                                                               ver_str))
147            ver = ver_split[0]
148            rev = ver_split[1]
149            try:
150                _version = int(ver)
151            except:
152                raise error.general('Invalid version config value: %s: %s' % (vc,
153                                                                              ver))
154            _revision = rev
155            if 'not_released' not in ver:
156                _released = True
157            _version_str = ver_str
158            _is_loaded = True
159    return _released
160
161def _load_git_version():
162    global _version
163    global _revision
164    global _git
165    global _version_str
166    global _is_loaded
167
168    if not _is_loaded:
169        repo = git.repo(_top())
170        if repo.valid():
171            head = repo.head()
172            if repo.dirty():
173                modified = 'modified'
174                revision_sep = '-'
175                sep = ' '
176            else:
177                modified = ''
178                revision_sep = ''
179                sep = ''
180            _revision = '%s%s%s' % (head[0:12], revision_sep, modified)
181            _version_str = '%s (%s%s%s)' % (_version, head[0:12], sep, modified)
182            _git = True
183            _is_loaded = True
184    return _git
185
186def load_release_settings(section, error = False):
187    vc, v = _load_released_version_config()
188    items = []
189    if v is not None:
190        try:
191            items = v.items(section)
192        except Exception as e:
193            if not isinstance(error, bool):
194                error(e)
195            elif error:
196                raise error.general('Invalid config section: %s: %s: %s' % (vc,
197                                                                            section,
198                                                                            e))
199    return items
200
201def load_release_setting(section, option, raw = False, error = False):
202    vc, v = _load_released_version_config()
203    value = None
204    if v is not None:
205        try:
206            value = v.get(section, option, raw = raw)
207        except Exception as e:
208            if not isinstance(error, bool):
209                error(e)
210            elif error:
211                raise error.general('Invalid config section: %s: %s: %s.%s' % (vc,
212                                                                               section,
213                                                                               option,
214                                                                               e))
215    return value
216
217def released():
218    return _load_released_version()
219
220def version_control():
221    return _load_git_version()
222
223def string():
224    _load_released_version()
225    _load_git_version()
226    return _version_str
227
228def version():
229    _load_released_version()
230    _load_git_version()
231    return _version
232
233def revision():
234    _load_released_version()
235    _load_git_version()
236    return _revision
237
238if __name__ == '__main__':
239    print('Version: %s' % (str(version())))
240    print('Revision: %s' % (str(revision())))
241    print('String: %s' % (string()))
242    if version() == 'undefined':
243        raise Exception('version is undefined')
Note: See TracBrowser for help on using the repository browser.