From c96889bae8e2291f4d4e78da4695714cfa951314 Mon Sep 17 00:00:00 2001 From: Lars Toenning Date: Tue, 11 Jun 2024 22:19:29 +0200 Subject: [PATCH] build: Move build util functions to separate file Previously, having everything in a single file causes issues, because build.py is also called from CMake to get the version number. This only worked for users, who had "requests" installed, as this library is required in build.py. --- .github/workflows/build.yml | 2 +- cmake/tools.cmake | 2 +- scripts/build.py | 82 ++++++++----------------------------- scripts/utils.py | 77 ++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 66 deletions(-) create mode 100644 scripts/utils.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e0a849d3..639704591 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: - name: Get version number id: version run: | - echo "value=$(python3 -u scripts/build.py --version)" >>$GITHUB_OUTPUT + echo "value=$(python3 -u scripts/utils.py --version)" >>$GITHUB_OUTPUT - name: Remove artifacts uses: swift-project/delete-artifact@swift with: diff --git a/cmake/tools.cmake b/cmake/tools.cmake index 26aee97f7..eda67d947 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 macro(get_version_number) - execute_process(COMMAND python scripts/build.py --version + execute_process(COMMAND python scripts/utils.py --version WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE SWIFT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/scripts/build.py b/scripts/build.py index 0284dc72d..3408f8156 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -4,7 +4,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 import getopt -import json import os import os.path as path import platform @@ -14,6 +13,7 @@ import sys import datastore import tarfile from lib.util import get_vs_env +import utils class Builder: @@ -29,7 +29,7 @@ class Builder: print('Updating from datastore ...') host = 'https://datastore.swift-project.org' datastore_version = '0.7.0' - source_path = self._get_swift_source_path() + source_path = utils.get_swift_source_path() shared_path = os.path.abspath(os.path.join(source_path, 'resources', 'share')) datastore.update_shared(host, datastore_version, shared_path) @@ -54,7 +54,7 @@ class Builder: '-DSWIFT_USE_CRASHPAD={}'.format(use_crashpad)] + cmake_args subprocess.check_call(cmake_call, env=dict(os.environ)) - # Workaround while using Make for MacOS to pass number of jobs + # Workaround while using Make for macOS to pass number of jobs if self.__class__.__name__ == 'MacOSBuilder': subprocess.check_call(["cmake", "--build", ".", "-j3"], env=dict(os.environ)) elif self.__class__.__name__ == 'MSVCBuilder': @@ -76,14 +76,14 @@ class Builder: def create_installer(self): bitrock_builder_bin = os.environ["BITROCK_BUILDER"] - os.chdir(self._get_swift_source_path()) + os.chdir(utils.get_swift_source_path()) os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} installer_platform_map = {'Linux': 'linux-x{}'.format(self.word_size), 'Darwin': 'osx', 'Windows': 'windows'} extension_map = {'Linux': 'run', 'Darwin': 'app', 'Windows': 'exe'} extension = extension_map[platform.system()] os_name = os_map[platform.system()] - version_full = self.__get_swift_version_base() - version_rev = self.__get_rev_count() + version_full = utils.get_swift_version_base() + version_rev = utils.get_rev_count() windows64 = 1 if os_name == 'windows' and int(self.word_size) == 64 else 0 installer_platform = installer_platform_map[platform.system()] @@ -142,7 +142,7 @@ class Builder: os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} archive_name = '-'.join(['xswiftbus', os_map[platform.system()], self.word_size, self.version]) + '.7z' archive_path = path.abspath(path.join(os.pardir, archive_name)) - content_path = path.abspath(path.join(self._get_swift_source_path(), 'dist', 'xswiftbus')) + content_path = path.abspath(path.join(utils.get_swift_source_path(), 'dist', 'xswiftbus')) subprocess.check_call(['7z', 'a', '-mx=9', archive_path, content_path, "-xr!*.debug", "-xr!*.dSYM"], env=dict(os.environ)) def symbols(self, upload_symbols): @@ -163,12 +163,12 @@ class Builder: if platform.system() == 'Windows': binary_path = path.abspath(path.join(build_path, 'out')) else: - binary_path = path.abspath(path.join(self._get_swift_source_path(), 'dist')) + binary_path = path.abspath(path.join(utils.get_swift_source_path(), 'dist')) os_map = {'Linux': 'linux', 'Darwin': 'macos', 'Windows': 'windows'} tar_filename = '-'.join( ['swiftsymbols', os_map[platform.system()], self.word_size, self.version]) + '.tar.gz' - tar_path = path.abspath(path.join(self._get_swift_source_path(), tar_filename)) + tar_path = path.abspath(path.join(utils.get_swift_source_path(), tar_filename)) tar = tarfile.open(tar_path, "w:gz") ignore_list = ['sample', 'test', 'win', 'liblin.so', 'libmac.dylib'] @@ -207,9 +207,6 @@ class Builder: def bundle_csl2xsb(self): pass - def _get_swift_source_path(self) -> str: - return self.__source_path - def _get_swift_build_path(self) -> str: return self.__build_path @@ -232,63 +229,23 @@ class Builder: return True def _get_externals_path(self) -> str: - return path.abspath(path.join(self._get_swift_source_path(), 'externals', self._get_platform_name(), self.word_size, 'lib')) + return path.abspath(path.join(utils.get_swift_source_path(), 'externals', self._get_platform_name(), self.word_size, 'lib')) def _strip_debug(self): raise NotImplementedError() def __init__(self, word_size): - self.__source_path = path.abspath(path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) - self.__build_path = path.abspath(path.join(self.__source_path, 'build')) + self.__build_path = path.abspath(path.join(utils.get_swift_source_path(), 'build')) - files = os.listdir(self.__source_path) + files = os.listdir(utils.get_swift_source_path()) for swift_dir in ['src', 'installer', 'third_party']: if swift_dir not in files: raise RuntimeError('Cannot find {} folder! Are we in the right directory?'.format(swift_dir)) self.word_size = word_size - self.version = self.__get_swift_version() + self.version = utils.get_swift_version() - def __get_version_file(self) -> str: - """ - :return: Path to the version.json - """ - return path.abspath(path.join(self._get_swift_source_path(), 'version')) + '.json' - def __get_swift_version(self) -> str: - """ - :return: Full version number (for example "0.12.123") - """ - return self.__get_swift_version_base() + '.' + str(self.__get_rev_count()) - - def __get_swift_version_base(self) -> str: - """ - :return: Base version number without revision (for example "0.12") - """ - f = open(self.__get_version_file()) - config_json = json.load(f) - f.close() - version_major = config_json['version']['major'] - version_minor = config_json['version']['minor'] - return '.'.join([str(version_major), str(version_minor)]) - - def __get_rev_count(self) -> int: - """ - :return: Number of commits since the current major and minor version was set in version.json - """ - this_version = self.__get_swift_version_base() - config_log = subprocess.check_output(['git', 'log', '--format=%H', self.__get_version_file()]) - for sha in config_log.decode("utf-8").split(): - json_data = subprocess.check_output(['git', 'show', sha + ':version.json']) - config_json = json.loads(json_data.decode("utf-8")) - version_major = config_json['version']['major'] - version_minor = config_json['version']['minor'] - if this_version == '.'.join([str(version_major), str(version_minor)]): - base_commit = sha - else: - break - count = subprocess.check_output(['git', 'rev-list', '--count', 'HEAD', '^' + base_commit]) - return int(count.decode("utf-8")) def __upload_symbol_files(self, symbols_package): print('Uploading symbols') @@ -331,7 +288,7 @@ class MSVCBuilder(Builder): pass def bundle_csl2xsb(self): - os.chdir(self._get_swift_source_path()) + os.chdir(utils.get_swift_source_path()) subprocess.check_call(["pyinstaller", "-y", "--distpath", "dist/share", "--workpath", os.environ["TEMP"], "scripts/csl2xsb/CSL2XSB.py"]) @@ -371,7 +328,7 @@ class LinuxBuilder(Builder): "bin/plugins/weatherdata/libweatherdatagfs.so", "xswiftbus/64/lin.xpl", ] - dist_path = path.join(self._get_swift_source_path(), "dist") + dist_path = path.join(utils.get_swift_source_path(), "dist") for file in files: subprocess.check_call(["objcopy", "--only-keep-debug", path.join(dist_path, file), @@ -420,7 +377,7 @@ class MacOSBuilder(Builder): "bin/plugins/weatherdata/libweatherdatagfs.dylib", "xswiftbus/64/mac.xpl", ] - dist_path = path.join(self._get_swift_source_path(), "dist") + dist_path = path.join(utils.get_swift_source_path(), "dist") # Put output of bundle files directly in bin folder for file in bundle_files: @@ -439,7 +396,7 @@ def print_help(): 'Windows': ['msvc'] } compiler_help = '|'.join(supported_compilers[platform.system()]) - print('build.py -w <32|64> -t <' + compiler_help + '> [-v] [-c ]') + print('build.py -w <32|64> -t <' + compiler_help + '> [-c ]') # Entry point if called as a standalone program @@ -450,7 +407,7 @@ def main(argv): cmake_args = [] try: - opts, args = getopt.getopt(argv, 'hw:t:uc:v', ['wordsize=', 'toolchain=', 'upload', 'cmake-arg=', 'version']) + opts, args = getopt.getopt(argv, 'hw:t:uc', ['wordsize=', 'toolchain=', 'upload', 'cmake-arg=']) except getopt.GetoptError: print_help() sys.exit(2) @@ -463,9 +420,6 @@ def main(argv): if opt == '-h': print_help() sys.exit() - elif opt in ('-v', '--version'): - print(Builder(None).version) - sys.exit() elif opt in ('-w', '--wordsize'): word_size = arg elif opt in ('-t', '--toolchain'): diff --git a/scripts/utils.py b/scripts/utils.py new file mode 100644 index 000000000..9ec91e547 --- /dev/null +++ b/scripts/utils.py @@ -0,0 +1,77 @@ +# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors +# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 + + +from os import path, pardir +import json +import subprocess +import argparse + + +def get_swift_source_path() -> str: + return path.abspath(path.join(path.dirname(path.realpath(__file__)), pardir)) + + +def get_swift_version() -> str: + """ + :return: Full version number (for example "0.12.123") + """ + return get_swift_version_base() + '.' + str(get_rev_count()) + + +def get_swift_version_base() -> str: + """ + :return: Base version number without revision (for example "0.12") + """ + f = open(__get_version_file()) + config_json = json.load(f) + f.close() + version_major = config_json['version']['major'] + version_minor = config_json['version']['minor'] + return '.'.join([str(version_major), str(version_minor)]) + + +def get_rev_count() -> int: + """ + :return: Number of commits since the current major and minor version was set in version.json + """ + this_version = get_swift_version_base() + config_log = subprocess.check_output(['git', 'log', '--format=%H', __get_version_file()]) + for sha in config_log.decode('utf-8').split(): + json_data = subprocess.check_output(['git', 'show', sha + ':version.json']) + config_json = json.loads(json_data.decode('utf-8')) + version_major = config_json['version']['major'] + version_minor = config_json['version']['minor'] + if this_version == '.'.join([str(version_major), str(version_minor)]): + base_commit = sha + else: + break + count = subprocess.check_output(['git', 'rev-list', '--count', 'HEAD', '^' + base_commit]) + return int(count.decode('utf-8')) + + +def __get_version_file() -> str: + """ + :return: Path to the version.json + """ + return path.abspath(path.join(get_swift_source_path(), 'version')) + '.json' + + +if __name__ == '__main__': + parser = argparse.ArgumentParser('swift utils') + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-v', '--version', action='store_true', help='Print the swift version') + group.add_argument('--rev', action='store_true', help='Print the revision number (aka the last number of the ' + 'version') + group.add_argument('--base', action='store_true', + help='Print the base version number (aka the first two numbers of ' + 'the version') + + args = parser.parse_args() + + if args.version: + print(get_swift_version()) + elif args.rev: + print(get_rev_count()) + elif args.base: + print(get_swift_version_base())