diff --git a/Applications/Python/ogs.callbacks/CMakeLists.txt b/Applications/Python/ogs.callbacks/CMakeLists.txt index ff4e4a19b5d5f609776418a3ce257b708bbd586e..67cc96bc550bf6a9598efb75c3cb2d9d7d396256 100644 --- a/Applications/Python/ogs.callbacks/CMakeLists.txt +++ b/Applications/Python/ogs.callbacks/CMakeLists.txt @@ -11,5 +11,5 @@ target_link_libraries( callbacks PRIVATE ProcessLibBoundaryConditionAndSourceTermPythonModule ) -# Install into root dir (in Python module, enables 'import ogs.callbacks') -install(TARGETS callbacks LIBRARY DESTINATION .) +# Install into Python module root dir (enables 'import ogs.callbacks') +install(TARGETS callbacks LIBRARY DESTINATION ogs) diff --git a/Applications/Python/ogs.simulator/CMakeLists.txt b/Applications/Python/ogs.simulator/CMakeLists.txt index dce167cd59f62621b40153457b2f477b0b094e54..f3b5c244980e46976560e811b3f7b8fe8a1b746d 100644 --- a/Applications/Python/ogs.simulator/CMakeLists.txt +++ b/Applications/Python/ogs.simulator/CMakeLists.txt @@ -17,5 +17,5 @@ target_link_libraries( ) target_include_directories(simulator PRIVATE ../../CLI) -# Install into root dir (in Python module, enables 'import ogs.simulator') -install(TARGETS simulator LIBRARY DESTINATION .) +# Install into Python module root dir (enables 'import ogs.callbacks') +install(TARGETS simulator LIBRARY DESTINATION ogs) diff --git a/Applications/Python/ogs/_internal/provide_ogs_cli_tools_via_wheel.py b/Applications/Python/ogs/_internal/provide_ogs_cli_tools_via_wheel.py index c5e231209430054884885b2c4dc3ef2be26e3056..03e35cd5043fa25698937ce65d23fb37eb18a40b 100644 --- a/Applications/Python/ogs/_internal/provide_ogs_cli_tools_via_wheel.py +++ b/Applications/Python/ogs/_internal/provide_ogs_cli_tools_via_wheel.py @@ -2,6 +2,9 @@ import os import platform import subprocess import sys +from pathlib import Path + +OGS_BIN_DIR = Path(__file__).parent.parent.parent / "bin" binaries_list = [ "addDataToRaster", @@ -69,6 +72,15 @@ binaries_list = [ ] +def pyproject_get_scripts(): + return dict( + [ + (binary, f"ogs._internal.provide_ogs_cli_tools_via_wheel:{binary}") + for binary in binaries_list + ] + ) + + def ogs(): raise SystemExit(ogs_with_args(sys.argv)) @@ -96,8 +108,6 @@ def ogs_with_args(argv): if "PEP517_BUILD_BACKEND" not in os.environ: - OGS_BIN_DIR = os.path.join(os.path.join(os.path.dirname(__file__), "..", "bin")) - if platform.system() == "Windows": os.add_dll_directory(OGS_BIN_DIR) diff --git a/Applications/Python/ogs/_internal/wrap_cli_tools.py b/Applications/Python/ogs/_internal/wrap_cli_tools.py index 8702162ab208da9471ef022f094767ce7205ebb7..6f9736cb038a29c6387c6020bca4af7edc492e81 100644 --- a/Applications/Python/ogs/_internal/wrap_cli_tools.py +++ b/Applications/Python/ogs/_internal/wrap_cli_tools.py @@ -1,8 +1,9 @@ import subprocess import os +from pathlib import Path from .provide_ogs_cli_tools_via_wheel import binaries_list, ogs_with_args -OGS_BIN_DIR = os.path.join(os.path.join(os.path.dirname(__file__), "..", "bin")) +OGS_BIN_DIR = Path(__file__).parent.parent.parent / "bin" class CLI: diff --git a/CMakePresets.json b/CMakePresets.json index c36ed7fe290276604f96bb10ad9d1f6a60b308f6..f40f3782a5dce862a5c915619550dd07b8c3e6a0 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -212,24 +212,6 @@ "OGS_USE_PIP": "OFF", "OGS_USE_MFRONT": "ON", "BUILD_SHARED_LIBS": "ON" - }, - "condition": { - "type": "notEquals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - } - }, - { - "name": "wheel-win", - "inherits": "wheel", - "cacheVariables": { - "OGS_USE_MFRONT": "OFF", - "OGS_BUILD_PROCESS_TH2M": "OFF" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" } } ], @@ -330,10 +312,6 @@ { "name": "wheel", "configurePreset": "wheel" - }, - { - "name": "wheel-win", - "configurePreset": "wheel-win" } ], "testPresets": [ diff --git a/pyproject.toml b/pyproject.toml index d81c6e0e32c18f02d7f772ebfa6d735d1533fca7..8e6c23424ff6e276181f12b1c05568fb12414341 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,23 +1,48 @@ [build-system] -requires = [ - "scikit-build-core @ https://github.com/scikit-build/scikit-build-core/archive/refs/heads/main.zip", -] +requires = ["scikit-build-core"] build-backend = "scikit_build_core.build" [project] name = "ogs" -version = "6.4.4.dev1" -# dynamic = ["version"] +dynamic = ["version", "scripts"] +description = "OpenGeoSys Python wheel" +readme = "README.md" +license = { file = "LICENSE.txt" } +authors = [{ email = "info@opengeosys.org" }, { name = "OpenGeoSys Community" }] +requires-python = ">=3.8" + +[project.urls] +homepage = "https://opengeosys.org" +documentation = "https://opengeosys.org/docs" +repository = "https://gitlab.opengeosys.org/ogs/ogs" +changelog = "https://gitlab.opengeosys.org/ogs/ogs/-/blob/master/CHANGELOG.md" + +[project.optional-dependencies] +test = ["pytest", "numpy"] [tool.scikit-build] -experimental = true +build-dir = "_skbuild/{wheel_tag}" +cmake.args = ["--preset", "wheel"] cmake.minimum-version = "3.22.0" +experimental = true +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" +minimum-version = "0.4.3" ninja.make-fallback = false -# metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" +wheel.packages = ["Applications/Python/ogs"] + +[tool.scikit-build.metadata.scripts] +provider = "scripts" +provider-path = "scripts/python/scikit-build-plugins" -[tool.cmake] -build-dir = "build/{wheel_tag}" -cmake.args = ["--preset", "wheel", "-DOGS_BUILD_PROCESSES=SteadyStateDiffusion"] +[tool.setuptools_scm] +write_to = "Applications/Python/_version.py" +write_to_template = '__version__ = "{version}"' +version_scheme = "no-guess-dev" +git_describe_command = 'git describe --dirty --tags --long --match "*[0-9]*" --abbrev=8' +# TODO neither local_scheme callable (https://github.com/pypa/setuptools_scm/issues/832) +# or env var (https://github.com/pypa/setuptools_scm/issues/455) does not work. +# Should be node-and-date by default and no-local-version in CI +local_scheme = "no-local-version" [tool.pytest.ini_options] testpaths = ["Tests"] @@ -50,3 +75,57 @@ skip = ["cp36-*", "cp37-*", "cp38-*x86_64"] [tool.cibuildwheel.windows] skip = ["cp36-*", "cp37-*"] + +# maybe this should be moved to CMake logic, i.e. disabling both features on win +[tool.cibuildwheel.windows.config-settings] +"cmake.define.OGS_USE_MFRONT" = "OFF" +"cmake.define.OGS_BUILD_PROCESS_TH2M" = "OFF" + +[tool.ruff] +select = [ + "E", + "F", + "W", # flake8 + "B", + "B904", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable + "NPY", # NumPy specific rules + "PD", # pandas-vet +] +extend-ignore = [ + "PLR", # Design related pylint codes + "E501", # Line too long + "PT004", # Use underscore for non-returning fixture (use usefixture instead) + # RUF005 should be disabled when using numpy, see + # https://github.com/charliermarsh/ruff/issues/2142: + "RUF005", +] +target-version = "py39" +typing-modules = ["mypackage._compat.typing"] +unfixable = [ + "T20", # Removes print statements + "F841", # Removes unused variables +] +exclude = [] +flake8-unused-arguments.ignore-variadic-names = true +line-length = 80 + +[tool.ruff.per-file-ignores] +"tests/**" = ["T20"] diff --git a/scripts/ci/jobs/build-wheels.yml b/scripts/ci/jobs/build-wheels.yml index 63b6ab0e3e2bfc353072f2b27f96a94092e2a22e..305644165b384fec12a2fed8cc3e259a06b32a9e 100644 --- a/scripts/ci/jobs/build-wheels.yml +++ b/scripts/ci/jobs/build-wheels.yml @@ -56,8 +56,8 @@ build wheels win: extends: - .vs2019-environment variables: - SKBUILD_BUILD_OPTIONS: "/m" - SKBUILD_GENERATOR: "Visual Studio 16 2019" + SKBUILD_BUILD_OPTIONS: "/m" # TODO not supported yet in scikit-build-core + CMAKE_GENERATOR: "Visual Studio 16 2019" # Does not work as it does not select the host64 compiler: # SKBUILD_GENERATOR: "Ninja" <<: *wheels_template diff --git a/scripts/python/scikit-build-plugins/scripts/__init__.py b/scripts/python/scikit-build-plugins/scripts/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0b47590711071390967d2dfbd48032f0991afb84 --- /dev/null +++ b/scripts/python/scikit-build-plugins/scripts/__init__.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import sys +import os + +sys.path.append(os.path.join("Applications", "Python")) +from ogs._internal.provide_ogs_cli_tools_via_wheel import pyproject_get_scripts + +__all__ = ["dynamic_metadata"] + + +def __dir__() -> list[str]: + return __all__ + + +def dynamic_metadata( + fields: frozenset[str], + settings: dict[str, object] | None = None, +) -> dict[str, str | dict[str, str | None]]: + if fields != {"scripts"}: + msg = "Only the 'scripts' field is supported" + raise ValueError(msg) + + if settings: + msg = "No inline configuration is supported" + raise ValueError(msg) + + # Structure for entry-points + # eps = { + # "console_scripts": {"ogs": "ogs._internal.provide_ogs_cli_tools_via_wheel:ogs"} + # } + # scripts = {"ogs": "ogs._internal.provide_ogs_cli_tools_via_wheel:ogs"} + + return {"scripts": pyproject_get_scripts()} diff --git a/setup.py b/setup.py deleted file mode 100644 index c06f26990052216062be0ce2080b14200bcbe3e4..0000000000000000000000000000000000000000 --- a/setup.py +++ /dev/null @@ -1,72 +0,0 @@ -from skbuild import setup -from setuptools import find_packages - -import os -import platform -import sys - -sys.path.append(os.path.join("Applications", "Python")) -from ogs._internal.provide_ogs_cli_tools_via_wheel import binaries_list - -console_scripts = [] -for b in binaries_list: - console_scripts.append(f"{b}=ogs._internal.provide_ogs_cli_tools_via_wheel:{b}") - -from pathlib import Path - -this_directory = Path(__file__).parent -long_description = (this_directory / "README.md").read_text() - -# setuptools_scm config local_scheme via env var SETUPTOOLS_SCM_LOCAL_SCHEME: -scm_local_scheme = "node-and-date" -if "SETUPTOOLS_SCM_LOCAL_SCHEME" in os.environ: - local_scheme_values = [ - "node-and-date", - "node-and-timestamp", - "dirty-tag", - "no-local-version", - ] - if os.environ["SETUPTOOLS_SCM_LOCAL_SCHEME"] in local_scheme_values: - scm_local_scheme = os.environ["SETUPTOOLS_SCM_LOCAL_SCHEME"] - -if "CMAKE_ARGS" in os.environ: - print( - "WARNING: Default CMake preset 'wheel' overridden! " - "Be sure to pass a proper preset or configuration!" - ) -else: - cmake_preset = "wheel" - if platform.system() == "Windows": - cmake_preset += "-win" - os.environ["CMAKE_ARGS"] = f"--preset {cmake_preset}" - -cmake_args = ["-B ."] -if "SKBUILD_GENERATOR" in os.environ: - cmake_args.extend(["-G", os.environ["SKBUILD_GENERATOR"]]) - -setup( - name="ogs", - description="OpenGeoSys Python Module", - long_description=long_description, - long_description_content_type="text/markdown", - author="OpenGeoSys Community", - license="BSD-3-Clause", - packages=find_packages(where="Applications/Python"), - package_dir={"": "Applications/Python"}, - cmake_install_dir="Applications/Python/ogs", - extras_require={"test": ["pytest", "numpy"]}, - cmake_args=cmake_args, - python_requires=">=3.7", - entry_points={"console_scripts": console_scripts}, - use_scm_version={ - "write_to": "Applications/Python/_version.py", - "write_to_template": '__version__ = "{version}"', - # Switching to guess-next-dev (default) would increment the version number - # This would be in line with PEP 440, switch OGS versioning too? - "version_scheme": "no-guess-dev", - "local_scheme": scm_local_scheme, - # Was in pyproject.toml but it somehow reset the version scheme. Maybe - # it is better to do all scm config here. - "git_describe_command": 'git describe --dirty --tags --long --match "*[0-9]*" --abbrev=8', - }, -)