Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add License-file metadata entry #329

Merged
merged 2 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ wheel.expand-macos-universal-tags = false
wheel.install-dir = "."

# The licence file(s) to include in the wheel metadata directory.
wheel.license-files = ["LICENSE*", "COPYING*", "COPYRIGHT*"]
wheel.license-files = ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]

# This will backport an internal copy of FindPython if CMake is less than this
# value. Set to 0 or the empty string to disable. The default will be kept in
Expand Down
8 changes: 4 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ for now.

:::

By default, any `LICENSE*`, `COPYING*`, or `COPYRIGHT*` file in the root of the
build directory will be picked up. You can specify an exact list of files if you
prefer, or if you your license file is in a different directory. The files must
have unique names. Globbing patterns are supported.
By default, any `LICEN[CS]E*`, `COPYING*`, `NOTICE*`, or `AUTHORS*` file in the
root of the build directory will be picked up. You can specify an exact list of
files if you prefer, or if your license file is in a different directory.
Globbing patterns are supported.

```toml
[tool.scikit-build]
Expand Down
15 changes: 13 additions & 2 deletions src/scikit_build_core/build/_wheelfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import stat
import time
import zipfile
from collections.abc import Set
from collections.abc import Mapping, Set
from email.message import Message
from email.policy import EmailPolicy
from pathlib import Path, PurePosixPath
Expand Down Expand Up @@ -73,6 +73,7 @@ class WheelWriter:
wheel_metadata = WheelMetadata(root_is_purelib=False)
buildver: str = ""
zipfile: zipfile.ZipFile | None = None
license_files: Mapping[Path, bytes] = dataclasses.field(default_factory=dict)

@property
def name_ver(self) -> str:
Expand Down Expand Up @@ -117,12 +118,22 @@ def dist_info_contents(self) -> dict[str, bytes]:
entry_points.write("\n")

self.wheel_metadata.tags = self.tags

# Using deepcopy here because of a bug in pyproject-metadata
# https://github.com/FFY00/python-pyproject-metadata/pull/49
rfc822 = copy.deepcopy(self.metadata).as_rfc822()
for fp in self.license_files:
rfc822["License-File"] = f"{fp}"

license_entries = {
f"licenses/{fp}": data for fp, data in self.license_files.items()
}

return {
"METADATA": bytes(copy.deepcopy(self.metadata).as_rfc822()),
"METADATA": bytes(rfc822),
"WHEEL": self.wheel_metadata.as_bytes(),
"entry_points.txt": entry_points.getvalue().encode("utf-8"),
**license_entries,
}

def build(self, wheel_dirs: dict[str, Path]) -> None:
Expand Down
41 changes: 24 additions & 17 deletions src/scikit_build_core/build/wheel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import dataclasses
import glob
import os
import shutil
import sys
Expand Down Expand Up @@ -146,6 +145,16 @@ def _build_wheel_impl(
else:
install_dir = wheel_dirs["platlib"] / settings.wheel.install_dir

license_files = {
x: x.read_bytes()
for y in settings.wheel.license_files
for x in Path().glob(y)
}
if settings.wheel.license_files and not license_files:
logger.warning(
"No license files found, set wheel.license-files to [] to suppress this warning"
)

config = CMaker(
cmake,
source_dir=Path(settings.cmake.source_dir or "."),
Expand All @@ -162,12 +171,19 @@ def _build_wheel_impl(
if metadata_directory is None:
msg = "metadata_directory must be specified if wheel_directory is None"
raise AssertionError(msg)
wheel = WheelWriter(metadata, Path(metadata_directory), tags.as_tags_set())
wheel = WheelWriter(
metadata,
Path(metadata_directory),
tags.as_tags_set(),
license_files=license_files,
)
dist_info_contents = wheel.dist_info_contents()
dist_info = Path(metadata_directory) / f"{wheel.name_ver}.dist-info"
dist_info.mkdir(parents=True)
for key, data in dist_info_contents.items():
path = dist_info / key
if not path.parent.is_dir():
path.parent.mkdir(exist_ok=True, parents=True)
path.write_bytes(data)
return WheelImplReturn(wheel_filename=dist_info.name)

Expand Down Expand Up @@ -215,22 +231,13 @@ def _build_wheel_impl(

process_script_dir(wheel_dirs["scripts"])

license_files = [
Path(x)
for y in settings.wheel.license_files
for x in glob.glob(y, recursive=True)
]
if settings.wheel.license_files and not license_files:
logger.warning(
"No license files found, set wheel.license-files to [] to suppress this warning"
)

with WheelWriter(metadata, Path(wheel_directory), tags.as_tags_set()) as wheel:
with WheelWriter(
metadata,
Path(wheel_directory),
tags.as_tags_set(),
license_files=license_files,
) as wheel:
wheel.build(wheel_dirs)
for license_file in license_files:
wheel.write(
str(license_file), f"{wheel.dist_info}/licenses/{license_file.name}"
)

if editable:
modules = {
Expand Down
2 changes: 1 addition & 1 deletion src/scikit_build_core/settings/skbuild_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class WheelSettings:

#: A list of license files to include in the wheel. Supports glob patterns.
license_files: List[str] = dataclasses.field(
default_factory=lambda: ["LICENSE*", "COPYING*", "COPYRIGHT*"]
default_factory=lambda: ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]
)


Expand Down
1 change: 1 addition & 0 deletions tests/test_pyproject_pep517.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def test_prepare_metdata_for_build_wheel():
"Requires-Python": ">=3.7",
"Provides-Extra": "test",
"Requires-Dist": 'pytest>=6.0; extra == "test"',
"License-File": "LICENSE",
}

for k, b in answer.items():
Expand Down
7 changes: 6 additions & 1 deletion tests/test_skbuild_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ def test_skbuild_settings_default(tmp_path):
assert settings.wheel.packages is None
assert settings.wheel.py_api == ""
assert not settings.wheel.expand_macos_universal_tags
assert settings.wheel.license_files == ["LICENSE*", "COPYING*", "COPYRIGHT*"]
assert settings.wheel.license_files == [
"LICEN[CS]E*",
"COPYING*",
"NOTICE*",
"AUTHORS*",
]
assert settings.backport.find_python == "3.26.1"
assert settings.strict_config
assert not settings.experimental
Expand Down