Skip to content

Commit

Permalink
feat: support vendoring with command (#5)
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
  • Loading branch information
henryiii authored Jul 18, 2024
1 parent 0dd3d28 commit bc4e2ee
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 1 deletion.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ repos:
additional_dependencies:
- pytest
- scikit-build-core
- importlib-resources

- repo: https://github.com/codespell-project/codespell
rev: "v2.3.0"
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,27 @@ requires = ["scikit-build-core", "numpy", "f2py-cmake"]
build-backend = "scikit_build_core.build"
```

## Vendoring

You can vendor UseF2Py into your package, as well. This avoids requiring a
dependency at build time and protects you against changes in this package, at
the expense of requiring manual re-vendoring to get bugfixes and/or
improvements. This mechanism is also ideal if you want to support direct builds,
outside of scikit-build-core.

You should make a CMake helper directory, such as `cmake`. Add this to your
`CMakeLists.txt` like this:

```cmake
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
```

Then, you can vendor our file into that folder:

```bash
pipx run f2py-cmake vendor cmake
```

<!-- prettier-ignore-start -->
[actions-badge]: https://github.com/scikit-build/f2py-cmake/workflows/CI/badge.svg
[actions-link]: https://github.com/scikit-build/f2py-cmake/actions
Expand Down
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ classifiers = [
"Typing :: Typed",
]
dynamic = ["version"]
dependencies = []
dependencies = [
"importlib_resources; python_version<'3.9'",
]

[project.entry-points."cmake.module"]
any = "f2py_cmake.cmake"

[project.scripts]
f2py-cmake = "f2py_cmake.__main__:main"

[project.optional-dependencies]
test = [
"pytest >=6",
Expand Down
34 changes: 34 additions & 0 deletions src/f2py_cmake/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from __future__ import annotations

import argparse
from pathlib import Path

from ._version import version as __version__
from .vendor import vendorize

__all__ = ["main"]


def __dir__() -> list[str]:
return __all__


def main() -> None:
"""
Entry point.
"""
parser = argparse.ArgumentParser(description="CMake F2Py module helper")
parser.add_argument(
"--version", action="version", version=f"%(prog)s {__version__}"
)
subparser = parser.add_subparsers(required=True)
vendor_parser = subparser.add_parser("vendor", help="Vendor CMake helpers")
vendor_parser.add_argument(
"target", type=Path, help="Directory to vendor the CMake helpers"
)
args = parser.parse_args()
vendorize(args.target)


if __name__ == "__main__":
main()
30 changes: 30 additions & 0 deletions src/f2py_cmake/vendor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from __future__ import annotations

import sys
from pathlib import Path

if sys.version_info < (3, 9):
from importlib_resources import files
else:
from importlib.resources import files

__all__ = ["vendorize"]


def __dir__() -> list[str]:
return __all__


def vendorize(target: Path) -> None:
"""
Vendorize files into a directory. Directory must exist.
"""
if not target.is_dir():
msg = f"Target directory {target} does not exist"
raise AssertionError(msg)

cmake_dir = files("f2py_cmake") / "cmake"

use = cmake_dir / "UseF2Py.cmake"
use_target = target / "UseF2Py.cmake"
use_target.write_text(use.read_text(encoding="utf-8"), encoding="utf-8")
21 changes: 21 additions & 0 deletions tests/test_vendorize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

import sys
from pathlib import Path

import pytest

from f2py_cmake.__main__ import main

DIR = Path(__file__).parent.resolve()
USE_F2PY = DIR.parent.joinpath("src/f2py_cmake/cmake/UseF2Py.cmake").read_text()


def test_copy_files(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
path = tmp_path / "copy_all"
path.mkdir()

monkeypatch.setattr(sys, "argv", [sys.executable, "vendor", str(path)])
main()

assert path.joinpath("UseF2Py.cmake").read_text() == USE_F2PY

0 comments on commit bc4e2ee

Please sign in to comment.