From 2e6ab77866bbdef6abcc149ddc430b1d9481b4f7 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Mon, 25 Jan 2021 01:19:44 +0300 Subject: project.ci: auto-detect CI system --- .github/workflows/ci_github.yml | 4 +-- project/ci/boost.py | 19 ++++++++++--- project/ci/cmake.py | 20 +++++++++++--- project/ci/dirs.py | 60 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci_github.yml b/.github/workflows/ci_github.yml index 00813b5..9f1b71e 100644 --- a/.github/workflows/ci_github.yml +++ b/.github/workflows/ci_github.yml @@ -44,10 +44,10 @@ jobs: python-version: '3.x' - name: Build Boost - run: python -m project.ci.github.boost -- --with-filesystem + run: python -m project.ci.boost -- --with-filesystem - name: Build example project - run: python -m project.ci.github.cmake --install --subdir examples/boost -- -D Boost_DEBUG=ON + run: python -m project.ci.cmake --install --subdir examples/boost - name: Run example project run: | diff --git a/project/ci/boost.py b/project/ci/boost.py index 3da5c9b..0320b1a 100644 --- a/project/ci/boost.py +++ b/project/ci/boost.py @@ -10,16 +10,18 @@ import sys from project.boost.build import BuildParameters, build from project.boost.download import DownloadParameters, download from project.boost.toolchain import ToolchainType +from project.ci.dirs import Dirs from project.linkage import Linkage +from project.utils import setup_logging -def _parse_args(dirs, argv=None): +def _parse_args(argv=None): if argv is None: argv = sys.argv[1:] logging.info('Command line arguments: %s', argv) parser = argparse.ArgumentParser( - description=dirs.get_boost_help(), + description=Dirs.get_boost_help(), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('--link', metavar='LINKAGE', @@ -40,7 +42,9 @@ def _parse_args(dirs, argv=None): def build_ci(dirs, argv=None): - args = _parse_args(dirs, argv) + args = _parse_args(argv) + if dirs is None: + dirs = Dirs.detect() version = dirs.get_boost_version() build_dir = dirs.get_build_dir() @@ -56,3 +60,12 @@ def build_ci(dirs, argv=None): toolset=args.toolset, b2_args=args.b2_args) build(params) + + +def main(argv=None): + with setup_logging(): + build_ci(None, argv) + + +if __name__ == '__main__': + main() diff --git a/project/ci/cmake.py b/project/ci/cmake.py index 262aafa..ff21873 100644 --- a/project/ci/cmake.py +++ b/project/ci/cmake.py @@ -8,17 +8,19 @@ import logging import os.path import sys +from project.ci.dirs import Dirs from project.cmake.build import BuildParameters, build from project.toolchain import ToolchainType +from project.utils import setup_logging -def _parse_args(dirs, argv=None): +def _parse_args(argv=None): if argv is None: argv = sys.argv[1:] logging.info('Command line arguments: %s', argv) parser = argparse.ArgumentParser( - description=dirs.get_cmake_help(), + description=Dirs.get_cmake_help(), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('--install', action='store_true', @@ -36,12 +38,15 @@ def _parse_args(dirs, argv=None): def build_ci(dirs, argv=None): - args = _parse_args(dirs, argv) + args = _parse_args(argv) + if dirs is None: + dirs = Dirs.detect() src_dir = dirs.get_src_dir() if args.subdir: src_dir = os.path.join(src_dir, args.subdir) install_dir = dirs.get_install_dir() if args.install else None + params = BuildParameters(src_dir, build_dir=dirs.get_cmake_dir(), install_dir=install_dir, @@ -51,3 +56,12 @@ def build_ci(dirs, argv=None): toolset=args.toolset, cmake_args=dirs.get_cmake_args() + args.cmake_args) build(params) + + +def main(argv=None): + with setup_logging(): + build_ci(None, argv) + + +if __name__ == '__main__': + main() diff --git a/project/ci/dirs.py b/project/ci/dirs.py index 6c6de65..bda4360 100644 --- a/project/ci/dirs.py +++ b/project/ci/dirs.py @@ -4,6 +4,7 @@ # Distributed under the MIT License. import abc +import os import os.path from project.boost.version import Version @@ -14,9 +15,28 @@ from project.utils import env class Dirs(abc.ABC): + @staticmethod + def detect(): + matching = [ci for ci in _ALL_CI_LIST if ci.this_one()] + if len(matching) == 0: + raise RuntimeError('no CI system was detected') + if len(matching) > 1: + names = ', '.join(ci.get_name() for ci in matching) + raise RuntimeError(f"can't select a single CI system out of these: {names}") + return matching[0] + def __init__(self): pass + @staticmethod + @abc.abstractmethod + def get_name(): + pass + + @abc.abstractmethod + def this_one(self): + pass + @abc.abstractmethod def get_platform(self): pass @@ -49,26 +69,37 @@ class Dirs(abc.ABC): def get_cmake_args(self): pass - def get_boost_help(self): - return f'''Download & build Boost on Travis/AppVeyor. + @staticmethod + def get_boost_help(): + names = ', '.join(ci.get_name() for ci in _ALL_CI_LIST) + return f'''Download & build Boost during a CI run. This is similar to running both project.boost.download & project.boost.build, but auto-fills some parameters from environment variables. -Boost is built in {self.get_boost_dir()}. +The supported CI systems are: {names}. ''' - def get_cmake_help(self): - return f'''Build a CMake project on Travis/AppVeyor. + @staticmethod + def get_cmake_help(): + names = ', '.join(ci.get_name() for ci in _ALL_CI_LIST) + return f'''Build a CMake project during a CI run. This is similar to running project.cmake.build, but auto-fills some parameters from environment variables. -The project is built in {self.get_cmake_dir()} and installed to {self.get_install_dir()}. +The supported CI systems are: {names}. ''' class Travis(Dirs): + @staticmethod + def get_name(): + return 'Travis' + + def this_one(self): + return 'TRAVIS' in os.environ + def get_platform(self): return Platform.parse(env('platform')) @@ -86,6 +117,13 @@ class Travis(Dirs): class AppVeyor(Dirs): + @staticmethod + def get_name(): + return 'AppVeyor' + + def this_one(self): + return 'APPVEYOR' in os.environ + def get_platform(self): return Platform.parse(env('PLATFORM')) @@ -103,6 +141,13 @@ class AppVeyor(Dirs): class GitHub(Dirs): + @staticmethod + def get_name(): + return 'GitHub Actions' + + def this_one(self): + return 'GITHUB_ACTIONS' in os.environ + def get_platform(self): return Platform.parse(env('platform')) @@ -117,3 +162,6 @@ class GitHub(Dirs): def get_cmake_args(self): return [] + + +_ALL_CI_LIST = (Travis(), AppVeyor(), GitHub()) -- cgit v1.2.3