diff --git a/.github/workflows/analyse.yml b/.github/workflows/analyse.yml new file mode 100644 index 0000000..6a6d12c --- /dev/null +++ b/.github/workflows/analyse.yml @@ -0,0 +1,37 @@ +name: Analyse + +on: + pull_request: + push: + +jobs: + build: + name: ${{ matrix.platform.os }} / ${{ matrix.platform.arch }} / python-${{ matrix.python_version }} + runs-on: ${{ matrix.platform.os }} + timeout-minutes: 30 + defaults: + run: + shell: bash -l {0} + strategy: + fail-fast: false + matrix: + python_version: ["3.12"] + platform: + - { os: "ubuntu-22.04", arch: x64 } + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python_version }} + cache: "pip" + cache-dependency-path: "**/requirements*.txt" + - name: Install packages + run: | + pip install -r environment/configuration/requirements.txt -r environment/configuration/requirements-dev.txt + - name: Analyse files + run: | + pre-commit install + # TODO For some reason pylint in a GH workflow complains about PySide6... + SKIP=pylint pre-commit run --all-files diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..ff6cdc6 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,59 @@ +name: Test + +on: + pull_request: + push: + +jobs: + build: + name: ${{ matrix.platform.os }} / ${{ matrix.platform.arch }} / python-${{ matrix.python_version }} + runs-on: ${{ matrix.platform.os }} + timeout-minutes: 30 + defaults: + run: + shell: bash -l {0} + strategy: + fail-fast: false + matrix: + # min version, max version + # 3.11 is the first version supported by darwin / arm64 runner + python_version: ["3.11", "3.12"] + platform: + - { os: "macos-14", arch: arm64 } + - { os: "macos-13", arch: x64 } + - { os: "ubuntu-22.04", arch: x64 } + - { os: "windows-2022", arch: x64 } + steps: + - name: Setup Linux platform + if: ${{ startsWith(matrix.platform.os, 'ubuntu') }} + run: | + sudo apt-get update + sudo apt-get install libegl1 + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + id: py + with: + python-version: ${{ matrix.python_version }} + cache: "pip" + cache-dependency-path: "**/requirements*.txt" + - name: Install packages + run: | + py_interpreter="${{ steps.py.outputs.python-path }}" + $py_interpreter -m pip install \ + -r environment/configuration/requirements.txt \ + -r environment/configuration/requirements-dev.txt + - name: Run tests + run: | + mkdir build + cd build + cmake -S .. -G Ninja + ctest --test-dir . --output-on-failure + - name: Create documentation + run: | + cmake --build build --target documentation + # - name: Create and verify release + # run: | + # py_interpreter="${{ steps.py.outputs.python-path }}" + # PYTHONPATH=source/package ${py_interpreter} environment/script/create_and_verify_release.py ./build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bbe309d..51fc56a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,15 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files - repo: https://github.com/psf/black - rev: 24.1.1 + rev: 24.3.0 hooks: - id: black - repo: https://github.com/pycqa/isort @@ -17,7 +17,7 @@ repos: hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.9.0 hooks: - id: mypy additional_dependencies: ["types-requests"] @@ -37,13 +37,14 @@ repos: [ "-rn", # Only display messages "-sn", # Don't display the score + "--extension-pkg-allow-list=PySide6", ] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.2 hooks: - id: pyupgrade - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.5.4 + rev: v1.5.5 hooks: - id: forbid-tabs - id: remove-tabs @@ -55,11 +56,3 @@ repos: (?x)^( adaptation_pathways.spec.in| )$ -# - repo: https://github.com/cmake-lint/cmake-lint -# rev: 1.4.2 -# hooks: -# - id: cmakelint -# args: -# [ -# "--filter=-linelength,-convention/filename,-package/stdargs", -# ] diff --git a/README.md b/README.md index 273b08e..71bd931 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # Adaptation pathways +[![Test](https://github.com/Deltares-research/PathwaysGenerator/actions/workflows/test.yml/badge.svg)](https://github.com/Deltares-research/PathwaysGenerator/actions/workflows/test.yml) +[![Analyse](https://github.com/Deltares-research/PathwaysGenerator/actions/workflows/analyse.yml/badge.svg)](https://github.com/Deltares-research/PathwaysGenerator/actions/workflows/analyse.yml) -https://publicwiki.deltares.nl/display/AP/Adaptation+Pathways +- [Developer manual](documentation/develop/index.rst) +- [User manual](documentation/use/index.rst) +- [Tester manual](documentation/test/index.rst) diff --git a/documentation/develop/index.rst b/documentation/develop/index.rst index 5e68094..49b970c 100644 --- a/documentation/develop/index.rst +++ b/documentation/develop/index.rst @@ -41,19 +41,11 @@ In commands: pip3 install -r environment/configuration/requirements.txt -r environment/configuration/requirements-dev.txt # Install handy tools that will keep our code in good shape: - pip3 install pre-commit pre-commit install # Note: commit .pre-commit-config.yaml if any hooks actually got updated pre-commit autoupdate - # Use a local updated version of pylint instead of the older version possibly installed on - # the system and instead of the normal pylint pre-commit hook. pre-commit hooks run in their own - # virtual environment that doesn't know about our package, resulting in lots of errors. - pip3 install pylint - - pathways_generator.py browser - pathways_generator.py window - jupyter-lab --notebook-dir=source/notebook/ + source/script/ap_pathway_generator.py --help The project contains code for generating :ref:`targets `, like documentation and the diff --git a/environment/configuration/requirements-dev.txt b/environment/configuration/requirements-dev.txt index 626a5d6..ff530f7 100644 --- a/environment/configuration/requirements-dev.txt +++ b/environment/configuration/requirements-dev.txt @@ -6,7 +6,12 @@ linkchecker ninja pre-commit pyinstaller + +# Use a local updated version of pylint instead of the older version possibly installed on +# the system and instead of the normal pylint pre-commit hook. pre-commit hooks run in their own +# virtual environment that doesn't know about our package, resulting in lots of errors. pylint + sphinx sphinxcontrib-mermaid sphinx-gallery diff --git a/environment/configuration/requirements.txt b/environment/configuration/requirements.txt index e8d4e7b..616b386 100644 --- a/environment/configuration/requirements.txt +++ b/environment/configuration/requirements.txt @@ -1,4 +1,4 @@ docopt matplotlib networkx[default] -pyside6 +pyside6>=6.6 diff --git a/environment/script/create_and_verify_release.py b/environment/script/create_and_verify_release.py index 205261e..88c2d6d 100755 --- a/environment/script/create_and_verify_release.py +++ b/environment/script/create_and_verify_release.py @@ -11,6 +11,7 @@ import docopt import adaptation_pathways as ap +from adaptation_pathways.cli.main import main_function def verify_build_directory(build_directory_path: Path) -> None: @@ -129,7 +130,8 @@ def create_and_verify_release(build_directory_path: Path) -> Path: return release_zip_path -def main() -> None: +@main_function +def main() -> int: command = os.path.basename(sys.argv[0]) usage = f"""\ Create a release and verify the contents seem OK @@ -152,6 +154,8 @@ def main() -> None: print(f"\nPackage {release_zip_path} is ready to be released!") + return 0 + if __name__ == "__main__": - main() + sys.exit(main()) diff --git a/pyproject.toml b/pyproject.toml index 1fc7068..0456415 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,7 @@ [tool.isort] +known_ap = "adaptation_pathways" lines_after_imports = 2 +sections = "FUTURE,STDLIB,THIRDPARTY,AP,FIRSTPARTY,LOCALFOLDER" profile = "black" [tool.pylint] diff --git a/source/package/adaptation_pathways/__init__.py b/source/package/adaptation_pathways/__init__.py index dfe00b2..2f934de 100644 --- a/source/package/adaptation_pathways/__init__.py +++ b/source/package/adaptation_pathways/__init__.py @@ -1,6 +1,7 @@ """ Package containing all code related to the Adaptation Pathways """ + from .action import Action from .action_combination import ActionCombination from .version import __version__ diff --git a/source/package/adaptation_pathways/cli/create_logo.py b/source/package/adaptation_pathways/cli/create_logo.py index efb4d3d..9445123 100644 --- a/source/package/adaptation_pathways/cli/create_logo.py +++ b/source/package/adaptation_pathways/cli/create_logo.py @@ -5,49 +5,49 @@ import docopt import matplotlib.pyplot as plt -from ..graph.conversion import ( - sequence_graph_to_pathway_map, - sequences_to_sequence_graph, -) -from ..graph.io import ( - action_level_by_first_occurrence, - read_sequences, - read_tipping_points, -) +from ..graph import conversion +from ..io import text from ..plot import init_axes, plot_classic_pathway_map, save_plot +from ..plot.util import action_level_by_first_occurrence from ..version import __version__ as version from .main import main_function @main_function def create_logo(plot_pathname: str) -> int: - sequences = read_sequences( + actions, colour_by_action = text.read_actions( StringIO( """ -a b -a c -a d -c d -""" + a #ffbf616a + b #ffd08770 + c #ffebcb8b + d #ffa3be8c + """ ) ) - sequence_graph = sequences_to_sequence_graph(sequences) - level_by_action = action_level_by_first_occurrence(sequences) - pathway_map = sequence_graph_to_pathway_map(sequence_graph) - tipping_points = read_tipping_points( + sequences, tipping_point_by_action = text.read_sequences( StringIO( """ -a 2040 -b 2050 -c 2060 -d 2070 -""" + a a 2040 + a b 2050 + a c 2060 + a d[1] 2070 + c d[2] 2070 + """ ), - pathway_map.actions(), + actions, ) + sequence_graph = conversion.sequences_to_sequence_graph(sequences) + pathway_map = conversion.sequence_graph_to_pathway_map(sequence_graph) + + level_by_action = action_level_by_first_occurrence(sequences) + colour_by_action_name = { + action.name: colour for action, colour in colour_by_action.items() + } - pathway_map.assign_tipping_points(tipping_points) - pathway_map.set_attribute("level", level_by_action) + pathway_map.assign_tipping_points(tipping_point_by_action) + pathway_map.set_attribute("level_by_action", level_by_action) + pathway_map.set_attribute("colour_by_action_name", colour_by_action_name) _, axes = plt.subplots(layout="constrained") init_axes(axes) diff --git a/source/package/adaptation_pathways/graph/node/__init__.py b/source/package/adaptation_pathways/graph/node/__init__.py index 0b5012d..ce9bd83 100644 --- a/source/package/adaptation_pathways/graph/node/__init__.py +++ b/source/package/adaptation_pathways/graph/node/__init__.py @@ -6,6 +6,7 @@ (position in a layout for example), and some information needs to be shared between nodes but unique per action (colour in a plot for example). """ + from .action import Action from .action_begin import ActionBegin from .action_conversion import ActionConversion diff --git a/source/package/adaptation_pathways/graph/node/action_conversion.py b/source/package/adaptation_pathways/graph/node/action_conversion.py index 49ebfca..0108a44 100644 --- a/source/package/adaptation_pathways/graph/node/action_conversion.py +++ b/source/package/adaptation_pathways/graph/node/action_conversion.py @@ -3,6 +3,7 @@ This module contains the implementation of the :py:class:`ActionConversion` class. """ + from .action_period import ActionPeriod from .node import Node