diff options
-rwxr-xr-x | configure.py | 14 | ||||
-rw-r--r-- | src/build-data/buildh.in | 9 | ||||
-rw-r--r-- | src/build-data/version.txt | 1 | ||||
-rw-r--r-- | src/lib/utils/version.cpp | 12 | ||||
-rwxr-xr-x | src/scripts/dist.py | 93 | ||||
-rw-r--r-- | src/tests/test_utils.cpp | 6 |
6 files changed, 97 insertions, 38 deletions
diff --git a/configure.py b/configure.py index 9c7d517e9..a8ab62536 100755 --- a/configure.py +++ b/configure.py @@ -90,6 +90,13 @@ class Version(object): if not Version.data: root_dir = os.path.dirname(os.path.realpath(__file__)) Version.data = parse_version_file(os.path.join(root_dir, 'src/build-data/version.txt')) + + suffix = Version.data["release_suffix"] + if suffix != "": + suffix_re = re.compile('-(alpha|beta|rc)[0-9]+') + + if not suffix_re.match(suffix): + raise Exception("Unexpected version suffix '%s'" % (suffix)) return Version.data @staticmethod @@ -105,6 +112,10 @@ class Version(object): return Version.get_data()["release_patch"] @staticmethod + def suffix(): + return Version.get_data()["release_suffix"] + + @staticmethod def packed(): # Used on macOS for dylib versioning return Version.major() * 1000 + Version.minor() @@ -123,7 +134,7 @@ class Version(object): @staticmethod def as_string(): - return '%d.%d.%d' % (Version.major(), Version.minor(), Version.patch()) + return '%d.%d.%d%s' % (Version.major(), Version.minor(), Version.patch(), Version.suffix()) @staticmethod def vc_rev(): @@ -1981,6 +1992,7 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch, 'version_major': Version.major(), 'version_minor': Version.minor(), 'version_patch': Version.patch(), + 'version_suffix': Version.suffix(), 'version_vc_rev': 'unknown' if options.no_store_vc_rev else Version.vc_rev(), 'abi_rev': Version.so_rev(), diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index c33e80acf..cede20ace 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -2,7 +2,9 @@ #define BOTAN_BUILD_CONFIG_H_ /* -* This file was automatically generated running +* Build configuration for Botan %{version} +* +* Automatically generated from * '%{command_line}' * * Target @@ -16,6 +18,11 @@ #define BOTAN_VERSION_PATCH %{version_patch} #define BOTAN_VERSION_DATESTAMP %{version_datestamp} +%{if version_suffix} +#define BOTAN_VERSION_SUFFIX %{version_suffix} +#define BOTAN_VERSION_SUFFIX_STR "%{version_suffix}" +%{endif} + #define BOTAN_VERSION_RELEASE_TYPE "%{release_type}" #define BOTAN_VERSION_VC_REVISION "%{version_vc_rev}" diff --git a/src/build-data/version.txt b/src/build-data/version.txt index 99ef56cc2..a823da188 100644 --- a/src/build-data/version.txt +++ b/src/build-data/version.txt @@ -2,6 +2,7 @@ release_major = 2 release_minor = 16 release_patch = 0 +release_suffix = '' release_so_abi_rev = 15 # These are set by the distribution script diff --git a/src/lib/utils/version.cpp b/src/lib/utils/version.cpp index ccf83bf6c..aa82d7cc9 100644 --- a/src/lib/utils/version.cpp +++ b/src/lib/utils/version.cpp @@ -23,7 +23,11 @@ const char* short_version_cstr() { return STR(BOTAN_VERSION_MAJOR) "." STR(BOTAN_VERSION_MINOR) "." - STR(BOTAN_VERSION_PATCH); + STR(BOTAN_VERSION_PATCH) +#if defined(BOTAN_VERSION_SUFFIX) + STR(BOTAN_VERSION_SUFFIX) +#endif + ; } const char* version_cstr() @@ -36,7 +40,11 @@ const char* version_cstr() return "Botan " STR(BOTAN_VERSION_MAJOR) "." STR(BOTAN_VERSION_MINOR) "." - STR(BOTAN_VERSION_PATCH) " (" + STR(BOTAN_VERSION_PATCH) +#if defined(BOTAN_VERSION_SUFFIX) + STR(BOTAN_VERSION_SUFFIX) +#endif + " (" #if defined(BOTAN_UNSAFE_FUZZER_MODE) "UNSAFE FUZZER MODE BUILD " #endif diff --git a/src/scripts/dist.py b/src/scripts/dist.py index a43b2a468..ce072ec10 100755 --- a/src/scripts/dist.py +++ b/src/scripts/dist.py @@ -164,32 +164,36 @@ def rewrite_version_file(version_file, target_version, snapshot_branch, rev_id, if snapshot_branch: assert target_version == snapshot_branch - version_file_name = os.path.basename(version_file) - contents = open(version_file).readlines() version_re = re.compile('release_(major|minor|patch) = ([0-9]+)') + version_suffix_re = re.compile('release_suffix = \'(-(alpha|beta|rc)[0-9]+)\'') + + def content_rewriter(target_version): + version_info = {} + + release_type = 'release' + + # Not included in old version files so set a default + version_info["suffix"] = "" - def content_rewriter(): for line in contents: if not snapshot_branch: - # Verify the version set in the source matches the tag match = version_re.match(line) if match: - name_to_idx = { - 'major': 0, - 'minor': 1, - 'patch': 2 - } - version_parts = target_version.split('.') - assert len(version_parts) == 3 - in_tag = int(version_parts[name_to_idx[match.group(1)]]) - in_file = int(match.group(2)) - - if in_tag != in_file: - raise Exception('Version number part "%s" in %s does not match tag %s' % - (match.group(1), version_file_name, target_version)) + version_info[match.group(1)] = int(match.group(2)) + + match = version_suffix_re.match(line) + if match: + suffix = match.group(1) + version_info['suffix'] = suffix + if suffix.find('alpha') >= 0: + release_type = 'alpha' + elif suffix.find('beta') >= 0: + release_type = 'beta' + elif suffix.find('rc') >= 0: + release_type = 'release candidate' if line == 'release_vc_rev = None\n': yield 'release_vc_rev = \'git:%s\'\n' % (rev_id) @@ -199,14 +203,29 @@ def rewrite_version_file(version_file, target_version, snapshot_branch, rev_id, if target_version == snapshot_branch: yield "release_type = 'snapshot:%s'\n" % (snapshot_branch) else: - yield "release_type = 'release'\n" + yield "release_type = '%s'\n" % (release_type) else: yield line - open(version_file, 'w').write(''.join(list(content_rewriter()))) + if not snapshot_branch: + for req_var in ["major", "minor", "patch", "suffix"]: + if req_var not in version_info.keys(): + raise Exception('Missing version field for %s in version file' % (req_var)) + + marked_version = "%d.%d.%d%s" % (version_info["major"], + version_info["minor"], + version_info["patch"], + version_info["suffix"]) -def write_archive(output_basename, archive_type, rel_epoch, all_files, hash_file): + if marked_version != target_version: + raise Exception('Release version file %s does not match tagged version %s' % ( + marked_version, target_version)) + new_contents = ''.join(list(content_rewriter(target_version))) + open(version_file, 'w').write(new_contents) + +def write_archive(version, output_basename, archive_type, rel_epoch, all_files, hash_file): + # pylint: disable=too-many-locals def archive_suffix(archive_type): if archive_type == 'tgz': return 'tgz' @@ -240,14 +259,21 @@ def write_archive(output_basename, archive_type, rel_epoch, all_files, hash_file # gzip format embeds the original filename, tarfile.py does the wrong # thing unless the output name ends in .gz. So pass an explicit # fileobj in that case, and supply a name in the form tarfile expects. - if archive_type == 'tgz': - archive = tarfile.open(output_basename + '.tar.gz', - write_mode(archive_type), - fileobj=open(output_archive, 'wb')) - else: - archive = tarfile.open(output_basename + '.tar', - write_mode(archive_type), - fileobj=open(output_archive, 'wb')) + archive_suffix = '.tar.gz' if archive_type == 'tgz' else '.tar' + + def archive_format(version): + # A change in Python meant that 2.14 and 2.15 were released with a + # tarfile using POSIX pax format (the new default for tarfile module) + # instead of the previously used GNU format. + if version in ['2.14.0', '2.15.0']: + return tarfile.PAX_FORMAT + else: + return tarfile.GNU_FORMAT + + archive = tarfile.open(output_basename + archive_suffix, + write_mode(archive_type), + format=archive_format(version), + fileobj=open(output_archive, 'wb')) for f in all_files: tarinfo = archive.gettarinfo(f) @@ -329,10 +355,6 @@ def main(args=None): elif len(args) == 1: try: logging.info('Creating release for version %s' % (target_version)) - - (major, minor, patch) = [int(x) for x in target_version.split('.')] - - assert target_version == '%d.%d.%d' % (major, minor, patch) except ValueError as e: logging.error('Invalid version number %s' % (target_version)) @@ -404,7 +426,12 @@ def main(args=None): hash_file = open(options.write_hash_file, 'w') for archive_type in archives: - output_files.append(write_archive(output_basename, archive_type, rel_epoch, all_files, hash_file)) + output_files.append(write_archive(target_version, + output_basename, + archive_type, + rel_epoch, + all_files, + hash_file)) if hash_file is not None: hash_file.close() diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp index 19350e2d3..efcffc45a 100644 --- a/src/tests/test_utils.cpp +++ b/src/tests/test_utils.cpp @@ -376,11 +376,15 @@ class Version_Tests final : public Test std::string sversion_str = Botan::short_version_string(); result.test_eq("Same short version string", sversion_str, std::string(sversion_cstr)); - const std::string expected_sversion = + std::string expected_sversion = std::to_string(BOTAN_VERSION_MAJOR) + "." + std::to_string(BOTAN_VERSION_MINOR) + "." + std::to_string(BOTAN_VERSION_PATCH); +#if defined(BOTAN_VERSION_SUFFIX) + expected_sversion += BOTAN_VERSION_SUFFIX_STR; +#endif + result.test_eq("Short version string has expected format", sversion_str, expected_sversion); |