From f4f2e074de3cc343f341a9cf64cde533ef06505e Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Tue, 27 Aug 2024 20:36:44 +0100 Subject: [PATCH] build working with uv.sources table --- plugins/hatch/hatch_una/hatch_build.py | 32 +++++++++++--------------- plugins/hatch/hatch_una/hatch_meta.py | 24 +++++++++---------- plugins/hatch/hatch_una/util.py | 13 +++++++++-- una/una/files.py | 9 ++++---- una/una/types.py | 1 + 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/plugins/hatch/hatch_una/hatch_build.py b/plugins/hatch/hatch_una/hatch_build.py index 1425e9b..24ac52f 100644 --- a/plugins/hatch/hatch_una/hatch_build.py +++ b/plugins/hatch/hatch_una/hatch_build.py @@ -17,13 +17,19 @@ class UnaBuildHook(BuildHookInterface[BuilderConfig]): PLUGIN_NAME = "una-build" def initialize(self, version: str, build_data: dict[str, Any]) -> None: - print("una: Injecting internal dependencies") + via_sdist = Path("PKG-INFO").exists() + if via_sdist: + print("una-build: In sdist, do nothing") + return + + print("una-build: Injecting internal dependencies") # load the config for this package path = Path(self.root) - conf = util.load_conf(path) + root = util.get_workspace_root() + root_conf = util.load_conf(root) members: list[str] = ( - conf.get("tool", {}).get("uv", {}).get("workspace", {}).get("members", []) # pyright:ignore[reportAny] + root_conf.get("tool", {}).get("uv", {}).get("workspace", {}).get("members", []) # pyright:ignore[reportAny] ) _, int_deps = util.get_dependencies(path) @@ -31,29 +37,17 @@ def initialize(self, version: str, build_data: dict[str, Any]) -> None: # this is fine, the package doesn't import anything internally return - via_sdist = Path("PKG-INFO").exists() - if via_sdist: - # nothing to do as everything should already be included in sdist... - return - add_dep_files: dict[str, str] = {} - for d in int_deps: - package_dir = util.find_package_dir(d, members) + package_dirs = [util.find_package_dir(d, members) for d in int_deps] + for package_dir in package_dirs: finder = SdistBuilder(str(package_dir)) files = [Path(f.path) for f in finder.recurse_selected_project_files()] for f in files: add_dep_files[str(f)] = str(f.relative_to(package_dir)) - # make sure all int_deps exist - found = [Path(k) for k in int_deps if (path / k).exists()] - missing = set(int_deps) - set(str(p) for p in found) - if len(missing) > 0: - missing_str = ", ".join(missing) - raise ValueError(f"Could not find these paths: {missing_str}") - add_packages_pyproj = { - str(f.parents[1] / util.PYPROJ): str(util.EXTRA_PYPROJ / f.name / util.PYPROJ) - for f in found + str(p / util.PYPROJ): str(util.EXTRA_PYPROJ / p.name / util.PYPROJ) + for p in package_dirs } build_data["force_include"] = { diff --git a/plugins/hatch/hatch_una/hatch_meta.py b/plugins/hatch/hatch_una/hatch_meta.py index fc7ac2d..9e9228f 100644 --- a/plugins/hatch/hatch_una/hatch_meta.py +++ b/plugins/hatch/hatch_una/hatch_meta.py @@ -15,29 +15,29 @@ class UnaMetaHook(MetadataHookInterface): PLUGIN_NAME = "una-meta" def update(self, metadata: dict[str, Any]) -> None: - print("una: Injecting transitive external dependencies") + print("una-meta: Injecting transitive external dependencies") - # load the config for this package path = Path(self.root) ext_deps, int_deps = util.get_dependencies(path) + via_sdist = Path("PKG-INFO").exists() + members: list[str] = [] if via_sdist else util.get_members() + add_deps: list[str] = [] - for dep_path in int_deps: + for dep_name in int_deps: # In builds that do src -> sdist -> wheel, the needed pyproject.toml files # will have been copied into the sdist so they're available for the wheel build. # Here we check for both in order. - dep_project_path = Path(dep_path).parents[1] - extra_path = util.EXTRA_PYPROJ / Path(dep_path).name - if dep_project_path.exists(): - use_path = dep_project_path - elif extra_path.exists(): - use_path = extra_path - else: - raise ValueError(f"Could not find internal dependency at '{dep_path}'") + + dep_path = ( + util.EXTRA_PYPROJ / Path(dep_name).name + if via_sdist + else util.find_package_dir(dep_name, members) + ) # load all third-party dependencies from this internal dependency into the # project.dependencies table - dep_deps, _ = util.get_dependencies(use_path) + dep_deps, _ = util.get_dependencies(dep_path) dep_deps = [d.strip().replace(" ", "") for d in dep_deps] add_deps.extend(dep_deps) diff --git a/plugins/hatch/hatch_una/util.py b/plugins/hatch/hatch_una/util.py index 5249328..5fefedc 100644 --- a/plugins/hatch/hatch_una/util.py +++ b/plugins/hatch/hatch_una/util.py @@ -11,6 +11,15 @@ def load_conf(path: Path) -> dict[str, Any]: return tomllib.load(fp) +def get_members() -> list[str]: + root = get_workspace_root() + root_conf = load_conf(root) + members: list[str] = ( + root_conf.get("tool", {}).get("uv", {}).get("workspace", {}).get("members", []) # pyright:ignore[reportAny] + ) + return members + + def get_dependencies(path: Path) -> tuple[list[str], list[str]]: conf = load_conf(path) all_deps: list[str] = conf["project"].get("dependencies", []) # pyright:ignore[reportAny] @@ -31,7 +40,7 @@ def get_dependencies(path: Path) -> tuple[list[str], list[str]]: def find_package_dir(name: str, members: list[str]) -> Path: - root = _get_workspace_root() + root = get_workspace_root() for glob in members: packages = sorted(root.glob(glob)) for p in packages: @@ -40,7 +49,7 @@ def find_package_dir(name: str, members: list[str]) -> Path: raise ValueError(f"Couldn't find package '{name}'") -def _get_workspace_root() -> Path: +def get_workspace_root() -> Path: root = _find_upwards(Path.cwd()) if not root: raise ValueError("Didn't find the workspace root. Expected to find a .git directory.") diff --git a/una/una/files.py b/una/una/files.py index 2668f92..234b7bb 100644 --- a/una/una/files.py +++ b/una/una/files.py @@ -16,7 +16,7 @@ description = "" authors = [] dependencies = [{dependencies}] -requires-python = "{python_version}" +requires-python = "{requires_python}" dynamic = ["una"] # needed for hatch-una metadata hook to work [build-system] @@ -99,7 +99,7 @@ def create_package( internal_deps: str, ) -> None: conf = config.load_conf(path) - python_version = conf.project.requires_python + requires_python = conf.tool.una.requires_python or ">= 3.11" package_dir = _create_dir(path, f"{top_dir}/{name}") ns_dir = _create_dir(path, f"{top_dir}/{name}/{ns}") @@ -116,7 +116,7 @@ def create_package( ) pyproj_content = _TEMPLATE_PYPROJ.format( name=name, - python_version=python_version, + requires_python=requires_python, dependencies=dependencies, sources=internal_deps, ) @@ -151,10 +151,11 @@ def _update_root_pyproj(path: Path, dependencies: str) -> str: toml = tomlkit.parse(f.read()) ns: str = toml["project"]["name"] # pyright:ignore[reportIndexIssue,reportAssignmentType] + requires_python: str = toml["project"]["requires-python"] # pyright:ignore[reportIndexIssue,reportAssignmentType] toml.pop("project") # pyright:ignore[reportUnknownMemberType] toml.pop("build-system") # pyright:ignore[reportUnknownMemberType] toml["tool"]["uv"]["workspace"] = {"members": _EXAMPLE_MEMBERS} # pyright:ignore[reportIndexIssue] - toml["tool"]["una"] = {"namespace": ns} # pyright:ignore[reportIndexIssue] + toml["tool"]["una"] = {"namespace": ns, "requires_python": requires_python} # pyright:ignore[reportIndexIssue] with pyproj.open("w") as f: f.write(tomlkit.dumps(toml)) # pyright:ignore[reportUnknownMemberType] return ns diff --git a/una/una/types.py b/una/una/types.py index d3610af..1be3650 100644 --- a/una/una/types.py +++ b/una/una/types.py @@ -87,6 +87,7 @@ class Uv: @dataclass(frozen=True) class Una: namespace: str | None = None + requires_python: str | None = None @dataclass_json