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: normalize sdist names #434

Merged
merged 7 commits into from
Aug 2, 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
10 changes: 10 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ probably keep in sync with your build-system requirements.
minimum-version = "0.2"
```

:::{warning}

The following behaviors are affected by `minimum-version`:

- `minimum-version` 0.5+ (or unset) provides the original name in metadata and
properly normalized SDist names.
- `minimum-version` 0.5+ (or unset) strips binaries by default.

:::

## CMake and Ninja minimum versions

You can select a different minimum version for CMake and Ninja.
Expand Down
22 changes: 21 additions & 1 deletion src/scikit_build_core/build/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import tarfile
from pathlib import Path

from packaging.utils import canonicalize_name
from packaging.version import Version

from .. import __version__
from .._compat import tomllib
from .._logging import rich_print
from ..settings.metadata import get_standard_metadata
from ..settings.skbuild_read_settings import SettingsReader
from ._file_processor import each_unignored_file
Expand Down Expand Up @@ -68,6 +73,11 @@ def build_sdist(
sdist_directory: str,
config_settings: dict[str, list[str] | str] | None = None,
) -> str:
rich_print(
f"[green]***[/green] [bold][green]scikit-build-core {__version__}[/green]",
"[red](sdist)[/red]",
)

with Path("pyproject.toml").open("rb") as f:
pyproject = tomllib.load(f)

Expand All @@ -87,7 +97,17 @@ def build_sdist(
# https://github.com/FFY00/python-pyproject-metadata/pull/49
pkg_info = bytes(copy.deepcopy(metadata).as_rfc822())

srcdirname = f"{metadata.name}-{metadata.version}"
# Only normalize SDist name if 0.5+ is requested for backwards compat
should_normalize_name = settings.minimum_version is None or Version(
settings.minimum_version
) >= Version("0.5")

sdist_name = (
canonicalize_name(metadata.name).replace("-", "_")
if should_normalize_name
else metadata.name
)
srcdirname = f"{sdist_name}-{metadata.version}"
filename = f"{srcdirname}.tar.gz"

sdist_dir.mkdir(parents=True, exist_ok=True)
Expand Down
10 changes: 9 additions & 1 deletion src/scikit_build_core/settings/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from typing import Any

from packaging.version import Version
from pyproject_metadata import StandardMetadata

from ..settings.skbuild_model import ScikitBuildSettings
Expand Down Expand Up @@ -44,4 +45,11 @@ def get_standard_metadata(
for field in fields:
pyproject_dict["project"]["dynamic"].remove(field)

return StandardMetadata.from_pyproject(pyproject_dict)
metadata = StandardMetadata.from_pyproject(pyproject_dict)
# pyproject-metadata normalizes the name - see https://github.com/FFY00/python-pyproject-metadata/pull/65
# For scikit-build-core 0.5+, we keep the un-normalized name, and normalize it when using it for filenames
if settings.minimum_version is None or Version(settings.minimum_version) >= Version(
"0.5"
):
metadata.name = pyproject_dict["project"]["name"]
return metadata
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ def package_simple_pyproject_ext(
) -> PackageInfo:
package = PackageInfo(
"simple_pyproject_ext",
"cbf3102cf86f709dfd3f244b69e5ee3faff9e3c94c53ef85f146d9bad96660b3",
"538a8221e10c5029c78127e4169d2df622b9a88dfce12a8b63eeaaa98cda8a09",
"0dab37b48497f95c044781204b7d49c752739b32a0ef7a7a02ec987b5c4a210b",
"feeedcb0070a211d93b967fe083aa31e448842eb9b93d5e428807348e40e44e8",
"c75641407303f3f3a0fd76d24e3d12447b31286fa5d0f687c0f8f8eb804d839f",
"dc4921bdf694b1b88cb27c8e6128513e174689625447d18c1dd3353348824946",
"2a135ce826265c5c1c73ebcb603989d8e2f4bca4605ad04c6c82871b5f75840e",
"7558e1db89e62b0941671796e1a35983a0b50a0701736566ca3ae5dd9ba09846",
)
process_package(package, tmp_path, monkeypatch)
return package
Expand Down
2 changes: 1 addition & 1 deletion tests/packages/simple_pyproject_ext/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ requires = [
build-backend = "scikit_build_core.build"

[project]
name = "cmake_example"
name = "CMake.Example"
version = "0.0.1"
requires-python = ">=3.7"

Expand Down
2 changes: 1 addition & 1 deletion tests/packages/simple_pyproject_source_dir/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ build-backend = "scikit_build_core.build"
cmake.source-dir = "src"

[project]
name = "cmake_example"
name = "CMake.Example"
version = "0.0.1"
requires-python = ">=3.7"

Expand Down
14 changes: 7 additions & 7 deletions tests/test_pyproject_pep517.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"""
METADATA = """\
Metadata-Version: 2.1
Name: cmake-example
Name: CMake.Example
Version: 0.0.1
Requires-Python: >=3.7
Provides-Extra: test
Expand All @@ -43,13 +43,13 @@ def test_pep517_sdist():
out = build_sdist("dist")

(sdist,) = dist.iterdir()
assert sdist.name == "cmake-example-0.0.1.tar.gz"
assert sdist.name == "cmake_example-0.0.1.tar.gz"
assert sdist == dist / out

with tarfile.open(sdist) as f:
file_names = set(f.getnames())
assert file_names == {
f"cmake-example-0.0.1/{x}"
f"cmake_example-0.0.1/{x}"
for x in (
"CMakeLists.txt",
"pyproject.toml",
Expand All @@ -58,7 +58,7 @@ def test_pep517_sdist():
"LICENSE",
)
}
pkg_info = f.extractfile("cmake-example-0.0.1/PKG-INFO")
pkg_info = f.extractfile("cmake_example-0.0.1/PKG-INFO")
assert pkg_info
pkg_info_contents = pkg_info.read().decode()
assert pkg_info_contents == METADATA
Expand Down Expand Up @@ -173,7 +173,7 @@ def test_pep517_wheel(virtualenv):
print(entry_points == ENTRYPOINTS)
assert 'Requires-Dist: pytest>=6.0; extra == "test"' in metadata
assert "Metadata-Version: 2.1" in metadata
assert "Name: cmake-example" in metadata
assert "Name: CMake.Example" in metadata
assert "Version: 0.0.1" in metadata
assert "Requires-Python: >=3.7" in metadata
assert "Provides-Extra: test" in metadata
Expand Down Expand Up @@ -221,7 +221,7 @@ def test_pep517_wheel_source_dir(virtualenv):
print(entry_points == ENTRYPOINTS)
assert 'Requires-Dist: pytest>=6.0; extra == "test"' in metadata
assert "Metadata-Version: 2.1" in metadata
assert "Name: cmake-example" in metadata
assert "Name: CMake.Example" in metadata
assert "Version: 0.0.1" in metadata
assert "Requires-Python: >=3.7" in metadata
assert "Provides-Extra: test" in metadata
Expand Down Expand Up @@ -268,7 +268,7 @@ def test_prepare_metdata_for_build_wheel():
metadata = build.util.project_wheel_metadata(str(Path.cwd()), isolated=False)
answer = {
"Metadata-Version": "2.1",
"Name": "cmake-example",
"Name": "CMake.Example",
"Version": "0.0.1",
"Requires-Python": ">=3.7",
"Provides-Extra": "test",
Expand Down
14 changes: 7 additions & 7 deletions tests/test_pyproject_pep518.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import hashlib
import shutil
import subprocess
import sys
import tarfile
import textwrap
Expand All @@ -12,21 +11,22 @@

@pytest.mark.network()
@pytest.mark.integration()
def test_pep518_sdist(package_simple_pyproject_ext):
def test_pep518_sdist(isolated, package_simple_pyproject_ext):
correct_metadata = textwrap.dedent(
"""\
Metadata-Version: 2.1
Name: cmake-example
Name: CMake.Example
Version: 0.0.1
Requires-Python: >=3.7
Provides-Extra: test
Requires-Dist: pytest>=6.0; extra == "test"
"""
)

subprocess.run([sys.executable, "-m", "build", "--sdist"], check=True)
isolated.install("build[virtualenv]")
isolated.module("build", "--sdist")
(sdist,) = Path("dist").iterdir()
assert sdist.name == "cmake-example-0.0.1.tar.gz"
assert sdist.name == "cmake_example-0.0.1.tar.gz"

if not sys.platform.startswith(("win", "cygwin")):
hash = hashlib.sha256(sdist.read_bytes()).hexdigest()
Expand All @@ -35,7 +35,7 @@ def test_pep518_sdist(package_simple_pyproject_ext):
with tarfile.open(sdist) as f:
file_names = set(f.getnames())
assert file_names == {
f"cmake-example-0.0.1/{x}"
f"cmake_example-0.0.1/{x}"
for x in (
"CMakeLists.txt",
"pyproject.toml",
Expand All @@ -44,7 +44,7 @@ def test_pep518_sdist(package_simple_pyproject_ext):
"LICENSE",
)
}
pkg_info = f.extractfile("cmake-example-0.0.1/PKG-INFO")
pkg_info = f.extractfile("cmake_example-0.0.1/PKG-INFO")
assert pkg_info
pkg_info_contents = pkg_info.read().decode()
assert correct_metadata == pkg_info_contents
Expand Down
Loading