From 29abbb75382cb21dfac88b21109899b7d5a4445b Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 10:05:09 +0200 Subject: [PATCH 1/6] move to pyproject file --- pyproject.toml | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..23e82e3 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,68 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.version] +path = "generic_parser/__init__.py" + +[tool.hatch.build.targets.sdist] +exclude = [ + "/.github", + "/doc", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["generic_parser"] + +[project] +name = "generic_parser" +readme = "README.md" +description = "An accelerator physics script collection for the OMC team at CERN." +authors = [ + {name = "PyLHC", email = "pylhc@github.com"}, + {name = "Joschua Dilly", email = "joschua.dilly@cern.ch"}, + {name = "Mael Le Garrec", email = "mael.le.garrec@cern.ch"}, + {name = "Felix Soubelet", email = "felix.soubelet@cern.ch"}, + {name = "Michael Hofer"}, +] +license = "MIT" +dynamic = ["version"] +requires-python = ">=3.9" + +classifiers = [ + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Topic :: Software Development :: Libraries :: Python Modules", + "Typing :: Typed", +] + +dependencies = [] + +[project.optional-dependencies] +test = [ + "pytest >= 7.0", + "pytest-cov>=2.9", +] +doc = [ + "sphinx >= 7.0", + "sphinx_rtd_theme >= 2.0", +] + +all = [ + "generic_parser[test]", + "generic_parser[doc]", +] + +[project.urls] +homepage = "https://github.com/pylhc/generic_parser" +repository = "https://github.com/pylhc/generic_parser" +documentation = "https://pylhc.github.io/generic_parser/" +changelog = "https://github.com/pylhc/generic_parser/blob/master/CHANGELOG.md" \ No newline at end of file From b0358030cd037d8d1d8547d72d988b82b17809cf Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 10:05:20 +0200 Subject: [PATCH 2/6] remove setup.py --- setup.py | 66 -------------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index c05abcb..0000000 --- a/setup.py +++ /dev/null @@ -1,66 +0,0 @@ -import pathlib - -from setuptools import setup, find_packages - -# Name of the module -MODULE_NAME = "generic_parser" - - -# The directory containing this file -TOPLEVEL_DIR = pathlib.Path(__file__).parent.absolute() -ABOUT_FILE = TOPLEVEL_DIR / MODULE_NAME / "__init__.py" -README = TOPLEVEL_DIR / "README.md" - - -def about_package(init_posixpath: pathlib.Path) -> dict: - """ - Return package information defined with dunders in __init__.py as a dictionary, when - provided with a PosixPath to the __init__.py file. - """ - about_text: str = init_posixpath.read_text() - return { - entry.split(" = ")[0]: entry.split(" = ")[1].strip('"').strip("'") - for entry in about_text.strip().split("\n") - if entry.startswith("__") - } - - -ABOUT_GENERIC_PARSER = about_package(ABOUT_FILE) - -# Dependencies for the module itself -DEPENDENCIES = [] - -# Extra dependencies for tools -EXTRA_DEPENDENCIES = { - "test": ["pytest>=5.2", "pytest-cov>=2.6", "hypothesis>=4.36.2", "attrs>=19.2.0"], - "doc": ["sphinx", "travis-sphinx", "sphinx_rtd_theme"], -} - -# The text of the README file -with README.open("r") as docs: - long_description = docs.read() - -setup( - name=ABOUT_GENERIC_PARSER["__title__"], - version=ABOUT_GENERIC_PARSER["__version__"], - description=ABOUT_GENERIC_PARSER["__description__"], - long_description=long_description, - long_description_content_type="text/markdown", - url=ABOUT_GENERIC_PARSER["__url__"], - author=ABOUT_GENERIC_PARSER["__author__"], - author_email=ABOUT_GENERIC_PARSER["__author_email__"], - license=ABOUT_GENERIC_PARSER["__license__"], - python_requires=">=3.6", - classifiers=[ - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - ], - packages=find_packages(include=("generic_parser",)), - install_requires=DEPENDENCIES, - tests_require=EXTRA_DEPENDENCIES["test"], - extras_require=EXTRA_DEPENDENCIES, -) From 4ae3401ba153dbb47b47a5eca82cefba2c8a7ea0 Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 10:08:12 +0200 Subject: [PATCH 3/6] use common workflows --- .github/workflows/README.md | 14 +++---- .github/workflows/coverage.yml | 65 ++--------------------------- .github/workflows/cron.yml | 42 +++---------------- .github/workflows/documentation.yml | 47 +++------------------ .github/workflows/publish.yml | 43 +------------------ .github/workflows/tests.yml | 41 ++++-------------- 6 files changed, 31 insertions(+), 221 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 4a0ab63..ce6d514 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -1,30 +1,28 @@ # Continous Integration Workflows -This package implements different workflows for CI. +This package implements different workflows for CI, based on our organisation's common workflows. They are organised as follows. ### Documentation The `documentation` workflow triggers on any push to master, builds the documentation and pushes it to the `gh-pages` branch (if the build is successful). -It runs on `ubuntu-latest` and `Python 3.7`. ### Testing Suite Tests are ensured in the `tests` workflow, which triggers on all pushes. -It runs on a matrix of all supported operating systems (ubuntu-18.04, ubuntu-20.04, windows-latest and macos-latest) for all supported Python versions (currently `3.7`, `3.8`, `3.9` and `3.10`). +It runs on a matrix of all supported operating systems for all supported Python versions. ### Test Coverage Test coverage is calculated in the `coverage` wokflow, which triggers on pushes to `master` and any push to a `pull request`. -It runs on `ubuntu-latest` & `Python 3.7`, and reports the coverage results of the test suite to `CodeClimate`, - +It reports the coverage results of the test suite to `CodeClimate`. ### Regular Testing A `cron` workflow triggers every Monday at 3am (UTC time) and runs the full testing suite, on all available operating systems and supported Python versions. -It also runs on `Python 3.x` so that newly released Python versions that would break tests are automatically detected. +It also runs on `Python 3.x` so that newly released Python versions that would break tests are automatically included. ### Publishing -Publishing to `PyPI` is done through the `publish` workflow, which triggers anytime a `release` is made of the Github repository. -It builds a `wheel`, checks it, and pushes to `PyPI` if checks are successful. \ No newline at end of file +Publishing to `PyPI` is done through the `publish` workflow, which triggers anytime a `release` is made of the GitHub repository. +It builds a `wheel`, checks it, and pushes to `PyPI` if checks are successful. diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4345d99..e5c138c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,10 +1,6 @@ # Runs all tests and pushes coverage report to codeclimate name: Coverage -defaults: - run: - shell: bash - on: # Runs on all push events to master branch and any push related to a pull request push: branches: @@ -13,60 +9,7 @@ on: # Runs on all push events to master branch and any push related to a pull r jobs: coverage: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: # only lowest supported Python on latest ubuntu - os: [ubuntu-latest] - python-version: [3.7] - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/setup.py' - - - name: Get full Python version - id: full-python-version - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Upgrade pip, setuptools and wheel - run: python -m pip install --upgrade pip setuptools wheel - - - name: Install package - run: python -m pip install '.[test]' - - - name: Set up env for CodeClimate (push) - run: | - echo "GIT_BRANCH=${GITHUB_REF/refs\/heads\//}" >> $GITHUB_ENV - echo "GIT_COMMIT_SHA=$GITHUB_SHA" >> $GITHUB_ENV - if: github.event_name == 'push' - - - name: Set up env for CodeClimate (pull_request) - env: - PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} - run: | - echo "GIT_BRANCH=$GITHUB_HEAD_REF" >> $GITHUB_ENV - echo "GIT_COMMIT_SHA=$PR_HEAD_SHA" >> $GITHUB_ENV - if: github.event_name == 'pull_request' - - - name: Prepare CodeClimate binary - env: - CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} - run: | - curl -LSs 'https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64' >./cc-test-reporter; - chmod +x ./cc-test-reporter - ./cc-test-reporter before-build - - - name: Run all tests - run: python -m pytest --cov-report xml --cov=generic_parser - - - name: Push Coverage to CodeClimate - if: ${{ success() }} # only if tests were successful - env: - CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} - run: ./cc-test-reporter after-build \ No newline at end of file + uses: pylhc/.github/.github/workflows/coverage.yml@master + with: + src-dir: generic_parser + secrets: inherit diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 30d642d..66cf544 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -1,43 +1,13 @@ -# Runs all tests on master everyday at 10 am (UTC time) +# Runs all tests on master on Mondays at 3 am (UTC time) name: Cron Testing -defaults: - run: - shell: bash -on: # Runs on master branch on Mondays at 3am UTC time +on: schedule: - cron: '* 3 * * mon' jobs: - tests: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-18.04, ubuntu-20.04, macos-latest, windows-latest] - # Make sure to escape 3.10 with quotes so it doesn't get interpreted as float 3.1 by GA's parser - python-version: [3.7, 3.8, 3.9, "3.10", 3.x] # crons should always run latest python hence 3.x - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/setup.py' - - - name: Get full Python version - id: full-python-version - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Upgrade pip, setuptools and wheel - run: python -m pip install --upgrade pip setuptools wheel - - - name: Install package - run: python -m pip install '.[test]' - - - name: Run all tests - run: python -m pytest \ No newline at end of file + tests: + uses: pylhc/.github/.github/workflows/cron.yml@master + with: + extra-dependencies: test diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index e548f81..e1195b9 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -1,51 +1,14 @@ # Build documentation +# The build is uploaded as artifact if the triggering event is a push for a pull request +# The build is published to github pages if the triggering event is a push to the master branch (PR merge) name: Build and upload documentation -defaults: - run: - shell: bash - -on: # Runs on any push event to master +on: # Runs on any push event in a PR or any push event to master + pull_request: push: branches: - 'master' jobs: documentation: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: # only lowest supported Python on latest ubuntu - os: [ubuntu-latest] - python-version: [3.7] - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/setup.py' - - - name: Get full Python version - id: full-python-version - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Upgrade pip, setuptools and wheel - run: python -m pip install --upgrade pip setuptools wheel - - - name: Install package - run: python -m pip install '.[doc]' - - - name: Build documentation - run: python -m sphinx -b html doc ./doc_build -d ./doc_build - - - name: Upload documentation to gh-pages - if: ${{ success() }} - uses: JamesIves/github-pages-deploy-action@3.7.1 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BRANCH: gh-pages - FOLDER: doc_build + uses: pylhc/.github/.github/workflows/documentation.yml@master diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ac83592..95fcfb7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,50 +1,11 @@ # Publishes to PyPI upon creation of a release name: Upload Package to PyPI -defaults: - run: - shell: bash - on: # Runs everytime a release is added to the repository release: types: [created] jobs: deploy: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: # only lowest supported Python on latest ubuntu - os: [ubuntu-latest] - python-version: [3.7] - - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/setup.py' - - - name: Get full Python version - id: full-python-version - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Upgrade pip, setuptools, wheel, build and twine - run: python -m pip install --upgrade pip setuptools wheel build twine - - - name: Build and check build - run: | - python -m build - twine check dist/* - - - name: Publish - if: ${{ success() }} - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - twine upload dist/* + uses: pylhc/.github/.github/workflows/publish.yml@master + secrets: inherit diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 698dfd1..149fc97 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,42 +1,17 @@ # Runs all tests -name: Tests +name: All Tests defaults: run: shell: bash -on: [push] # Runs on all push events to any branch - +on: # Runs on any push event to any branch except master (the coverage workflow takes care of that) + push: + branches-ignore: + - 'master' jobs: tests: - name: ${{ matrix.os }} / ${{ matrix.python-version }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-18.04, ubuntu-20.04, macos-latest, windows-latest] - # Make sure to escape 3.10 with quotes so it doesn't get interpreted as float 3.1 by GA's parser - python-version: [3.7, 3.8, 3.9, "3.10"] - - steps: - - uses: actions/checkout@v3 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: '**/setup.py' - - - name: Get full Python version - id: full-python-version - run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") - - - name: Upgrade pip, setuptools and wheel - run: python -m pip install --upgrade pip setuptools wheel - - - name: Install package - run: python -m pip install '.[test]' - - - name: Run basic tests - run: python -m pytest \ No newline at end of file + uses: pylhc/.github/.github/workflows/tests.yml@master + with: + extra-dependencies: test From 7e4cb3212c30a6ed1470647f1c864f3d7e2acb9e Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 10:09:00 +0200 Subject: [PATCH 4/6] define __all__ --- generic_parser/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic_parser/__init__.py b/generic_parser/__init__.py index d766a3c..87f82fa 100644 --- a/generic_parser/__init__.py +++ b/generic_parser/__init__.py @@ -9,3 +9,5 @@ __author__ = "pylhc" __author_email__ = "pylhc@github.com" __license__ = "MIT" + +__all__ = ["EntryPoint", "EntryPointParameters", "entrypoint", "DotDict"] From 85daef5c1cbd73d24e9b443f95fbfc7a75891312 Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 10:09:49 +0200 Subject: [PATCH 5/6] membership test should be 'not in' --- generic_parser/dict_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic_parser/dict_parser.py b/generic_parser/dict_parser.py index 7a255ad..e542836 100644 --- a/generic_parser/dict_parser.py +++ b/generic_parser/dict_parser.py @@ -160,7 +160,7 @@ def _parse_arguments(self, arg_dict, param_dict): checked_dict[key] = DictParser._check_value(key, arg_dict, param_dict) elif isinstance(param_dict[key], dict): try: - if not arg_dict or not (key in arg_dict): + if not arg_dict or key not in arg_dict: checked_dict[key] = self._parse_arguments({}, param_dict[key])[0] else: checked_dict[key] = self._parse_arguments(arg_dict[key], param_dict[key])[0] From 6de88ed3a47621fbc80db8083da97db21742f597 Mon Sep 17 00:00:00 2001 From: Felix Soubelet Date: Mon, 12 Aug 2024 15:47:24 +0200 Subject: [PATCH 6/6] update authors metadata as discussed --- pyproject.toml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 23e82e3..0f63224 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,11 +20,7 @@ name = "generic_parser" readme = "README.md" description = "An accelerator physics script collection for the OMC team at CERN." authors = [ - {name = "PyLHC", email = "pylhc@github.com"}, - {name = "Joschua Dilly", email = "joschua.dilly@cern.ch"}, - {name = "Mael Le Garrec", email = "mael.le.garrec@cern.ch"}, - {name = "Felix Soubelet", email = "felix.soubelet@cern.ch"}, - {name = "Michael Hofer"}, + {name = "OMC Team", email = "pylhc@github.com"}, # see zenodo file / commits for details ] license = "MIT" dynamic = ["version"]