diff --git a/docs/conf.py b/docs/conf.py index 7343676b..c1629367 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,6 +28,7 @@ "sphinxcontrib.autodoc_pydantic", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", + "sphinxcontrib.spelling", ] # Enable MyST extensions to support reStructuredText directives in Markdown @@ -54,6 +55,11 @@ # "pyproject-hooks": ("https://pyproject-hooks.readthedocs.io/en/latest/", None), } +# sphinxcontrib.spelling settings +# File references a function object. Spell checker complaints about typo in +# random object id. +spelling_exclude_patterns = ["config-reference.rst"] + # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output @@ -76,7 +82,7 @@ class FromagerHookDocumenter(FunctionDocumenter): objtype = "fromagerhook" - def format_name(self): + def format_name(self) -> str: name = super().format_name() if name.startswith("default_"): name = name[8:] diff --git a/docs/customization.md b/docs/customization.md index d5bead58..a6af38ee 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -97,7 +97,7 @@ support templating. The only supported template variable are: ### Resolver dist The source distribution index server used by the package resolver can -be overriden for a particular package. The resolver can also be told +be overridden for a particular package. The resolver can also be told to whether include wheels or sdist sources while trying to resolve the package. Templating is not supported here. diff --git a/docs/files.md b/docs/files.md index f48f8e41..af521ba8 100644 --- a/docs/files.md +++ b/docs/files.md @@ -157,7 +157,7 @@ wheels-repo └── simple ``` -* The `build` sub-directoy holds temporary builds. We use it as the output directory when building the wheel because we can't predict the filename, and so using an empty directory with a name we know gives us a way to find the file and move it into the `downloads` directory after it's built +* The `build` sub-directory holds temporary builds. We use it as the output directory when building the wheel because we can't predict the filename, and so using an empty directory with a name we know gives us a way to find the file and move it into the `downloads` directory after it's built * The `downloads` sub-directory contains the wheels in `.whl` format that fromager builds combined with the pre-built wheels so we can create a local package index in `simple` * The `prebuilt` sub-directory contains wheels that are being used as prebuilt * The `simple` sub-directory is laid out as a simple local wheel index. diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 01583051..481f3ab0 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -116,5 +116,5 @@ The output below is redacted for brevity. Missing sections are replaced with ``. 11:19:56 INFO Bootstrapping typing-extensions==4.14.0 took 0:00:01 total, 0:00:00 to resolve source, 0:00:00 to download source, 0:00:00 to prepare source, 0:00:00 to build sdist, 0:00:00 to add extra metadata to wheels, 0:00:00 to build wheels As each dependency is built, fromager will show output from the build process -and progress information. At the end of the build, fromager shows the lsit of +and progress information. At the end of the build, fromager shows the list of packages that were built and how long each step took. diff --git a/docs/how-tos/containers.rst b/docs/how-tos/containers.rst index 5d6b9882..fa972147 100644 --- a/docs/how-tos/containers.rst +++ b/docs/how-tos/containers.rst @@ -227,6 +227,6 @@ followed by the wheel being built successfully. pydantic-core: built wheel for version 2.18.4: /work/bootstrap-output/wheels-repo/downloads/pydantic_core-2.18.4-0-cp311-cp311-linux_x86_64.whl The :doc:`customization` section explains other techniques for changing the -build inputs to ensure packages build properley. The collection of wheels you +build inputs to ensure packages build properly. The collection of wheels you want to build may have different build-time issues, but you can use this iterative approach to work your way though them until they all build. diff --git a/docs/index.rst b/docs/index.rst index f0bd4e5e..71597967 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -39,6 +39,7 @@ those special cases directly into fromager. cli.rst glossary.rst develop.md + proposals/index.rst What's with the name? --------------------- diff --git a/docs/proposals/index.rst b/docs/proposals/index.rst new file mode 100644 index 00000000..ca5869a2 --- /dev/null +++ b/docs/proposals/index.rst @@ -0,0 +1,7 @@ +Fromager Enhancement Proposals +============================== + +.. toctree:: + :maxdepth: 1 + + new-patcher-config diff --git a/docs/proposals/new-patcher-config.md b/docs/proposals/new-patcher-config.md new file mode 100644 index 00000000..a9b801d4 --- /dev/null +++ b/docs/proposals/new-patcher-config.md @@ -0,0 +1,110 @@ +# New patcher configuration + +- Author: Christian Heimes +- Created: 2026-02-26 +- Status: Open + +## What + +This enhancement document proposal a new approach to patch sources and wheel +metadata through declarative configuration. + +## Why + +TODO + +## Goals + +- provide simple patching facilities with a declarative configuration approach +- support version-specific patching (e.g. patch build system requirements for + `>=1.0,<1.0`). +- make common tasks like fixing sdist metadata (`PKG-INFO`) easier +- add patching of wheel and sdist package metadata to remove or modify + installation requirements (`requires-dist` field). + +## Non-goals + +- Patch files will not be deprecated and removed. Patches are still useful + and will be supported in the future. +- CPU architecture-specific patches won't be supported, because they are a + misfeature. Patches will be + +## How + +The new system will use a new top-level configuration key `patch`, which is +an array of patch operations. Each patch operation has a title, optional +version specifier, and an action like `replace-line`, `fix-pkg-info`, or +`pyproject-build-system`. + +- The action name acts as a tag ([discriminated union](https://docs.pydantic.dev/latest/concepts/unions/#discriminated-unions)). +- The `title` is a human-readable description that explains the purpose of + the operation. +- The optional field `when_version` can be used to limit the action, + e.g. `>=1.0,<1.0`. + > **NOTE**: `when_version` is not compatible with nightly builds. +- Some actions have a `ignore_missing` boolean flag. If an action has no + effect, then it fails and stops the build unless `ignore_missing` is set. + +Example: + +```yaml +patch: + - title: Comment out 'foo' requirement for version >= 1.2 + action: replace-line + files: + - 'requirements.txt' + search: '^(foo.*)$' + replace: '# \\1' + when_version: '>=1.2' + ignore_missing: true + + - title: Remove 'bar' from constraints.txt + action: delete-line + files: + - 'constraints.txt' + search: 'bar.*' + + - title: Remove 'somepackage' installation requirement + action: remove-install-requires + requirement: somepackage + + - title: Fix PKG-INFO metadata version + action: fix-pkg-info + metadata_version: '2.4' + when_version: '<1.0' + + - title: Add missing setuptools to pyproject.toml + action: pyproject-build-system + update_build_requires: + - setuptools + + - title: Update Torch install requirement to version in build env + action: pin-install-requires-to-build + requirement: torch +``` + +### Actions + +All file names are relative to `sdist_root_dir`. + +- The `replace-line` action replaces lines in one or more files. + +- The `delete-line` action removes a line from one or more files. + +- The `pyproject-build-system` action replaces the old `project_override` + settings `update_build_requires` and `remove_build_requires`. + +- The `remove-install-requires` action removes a `requires-dist` entry from + sdist and wheel installation requirements. The requirement is matched by + name-only or by full requirement (including specifier set and markers). + +- The `pin-install-requires-to-build` pins `requires-dist` in sdist + and wheel metadata to the exact version in the build environment. The + primary use case is Torch. If a package is build with Torch 2.9.1, then + we want the wheel to depend on exactly `torch==2.9.1`. + +### Deprecations + +The old settings `project_override.update_build_requires` and +`project_override.remove_build_requires` will be deprecated and eventually +removed. diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt new file mode 100644 index 00000000..ee5b751a --- /dev/null +++ b/docs/spelling_wordlist.txt @@ -0,0 +1,81 @@ +args +backend +backends +backoff +canonicalize +canonicalized +changelog +changelogs +cheeseshop +cn +codebase +config +containerfile +cpu +csv +customizations +cython +deprecations +dir +downloader +env +environ +filesystem +fromager +frontend +frontends +graphviz +gz +installability +iterable +iteratively +json +lexicographically +linter +localhost +matcher +mypy +namespace +numpy +openssl +platlib +podman +pre +prebuilt +purelib +py +pydantic +pypi +pyproject +recurses +repo +scm +sdist +sdists +setuptools +statelessly +stderr +stdin +stdout +subcommands +subdirectory +submodule +submodules +subprocesses +templating +toml +toplevel +tos +traceback +tracebacks +txt +unshare +url +urls +vendored +vendoring +versionless +virtualenv +walkthrough +whitespace +yaml diff --git a/pyproject.toml b/pyproject.toml index 2356d2d4..2996cfcb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,7 @@ docs = [ "myst-parser", "sphinx-rtd-theme", "autodoc-pydantic", + "sphinxcontrib.spelling", ] [project.urls] diff --git a/src/fromager/__main__.py b/src/fromager/__main__.py index 437fdae5..a2d4d891 100644 --- a/src/fromager/__main__.py +++ b/src/fromager/__main__.py @@ -140,7 +140,7 @@ @click.option( "--network-isolation/--no-network-isolation", default=SUPPORTS_NETWORK_ISOLATION, - help="Build sdist and wheen with network isolation (unshare -cn)", + help="Build sdist and when with network isolation (unshare -cn)", show_default=True, ) @click.pass_context diff --git a/src/fromager/commands/build_order.py b/src/fromager/commands/build_order.py index c5f2b601..88782c4e 100644 --- a/src/fromager/commands/build_order.py +++ b/src/fromager/commands/build_order.py @@ -31,7 +31,7 @@ def as_csv(build_order_file: str, output: pathlib.Path | None) -> None: Creates a file suitable for import into a spreadsheet including the distribution name, version, original requirement, dependency type, whether the package is pre-built, the build order step number, and - a full dependency chain leading to the requirment. + a full dependency chain leading to the requirement. """ fields = [