Skip to content

Commit

Permalink
feat: support choosing groups to lock
Browse files Browse the repository at this point in the history
Signed-off-by: Frost Ming <[email protected]>
  • Loading branch information
frostming committed Jul 9, 2024
1 parent 1c6e877 commit 017e247
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
17 changes: 17 additions & 0 deletions doc/src/plugins/backend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,20 @@ hatchling
build-backend = "hatchling.build"
[tool.hatch.metadata.hooks.build-locked]
Select groups to lock
~~~~~~~~~~~~~~~~~~~~~

By default, the default group and all optional groups will be locked, but you can specify the groups to lock by setting `lock_groups` in the configuration.

.. code-block:: toml
:caption: pyproject.toml
# for pdm-backend
[tool.pdm.build]
locked = true
lock_groups = ["default", "optional1"]
# for hatchling
[tool.hatch.metadata.hooks.build-locked]
lock_groups = ["default", "optional1"]
9 changes: 6 additions & 3 deletions src/pdm_build_locked/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ def get_locked_group_name(group: str) -> str:
return group_name


def update_metadata_with_locked(metadata: MutableMapping[str, Any], root: Path) -> None: # pragma: no cover
def update_metadata_with_locked(
metadata: MutableMapping[str, Any], root: Path, groups: list[str] | None = None
) -> None: # pragma: no cover
"""Inplace update the metadata(pyproject.toml) with the locked dependencies.
Args:
metadata (dict[str, Any]): The metadata dictionary
root (Path): The path to the project root
groups (list[str], optional): The groups to lock. Defaults to default + all optional groups.
Raises:
UnsupportedRequirement
Expand All @@ -94,10 +97,10 @@ def update_metadata_with_locked(metadata: MutableMapping[str, Any], root: Path)
)
return

groups = ["default"]
optional_groups = list(metadata.get("optional-dependencies", {}))
locked_groups = lockfile_content.get("metadata", {}).get("groups", [])
groups.extend(optional_groups)
if groups is None:
groups = ["default", *optional_groups]
for group in groups:
locked_group = get_locked_group_name(group)
if locked_group in optional_groups:
Expand Down
4 changes: 3 additions & 1 deletion src/pdm_build_locked/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ def pdm_build_hook_enabled(self, context: Context) -> bool:

def pdm_build_initialize(self, context: Context) -> None:
static_fields = list(context.config.metadata)
update_metadata_with_locked(context.config.metadata, context.root)
update_metadata_with_locked(
context.config.metadata, context.root, context.config.build_config.get("lock_groups")
)
new_fields = set(context.config.metadata) - set(static_fields)
for field in new_fields:
if field in context.config.metadata.get("dynamic", []):
Expand Down
6 changes: 5 additions & 1 deletion src/pdm_build_locked/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ def handle(self, project: Project, options: argparse.Namespace) -> None:
if dev_dependencies := project.pyproject.settings.get("dev-dependencies"):
pdm_dev_dependencies = dev_dependencies.keys()

groups = {group for group in project.all_dependencies if group not in pdm_dev_dependencies}
groups = project.pyproject.settings.get("build", {}).get("lock_groups", None)
if groups is None:
groups = {group for group in project.all_dependencies if group not in pdm_dev_dependencies}
else:
groups = set(groups)

Check warning on line 57 in src/pdm_build_locked/command.py

View check run for this annotation

Codecov / codecov/patch

src/pdm_build_locked/command.py#L57

Added line #L57 was not covered by tests

locked_groups = [get_locked_group_name(group) for group in groups]
if duplicate_groups := groups.intersection(locked_groups):
Expand Down
2 changes: 1 addition & 1 deletion src/pdm_build_locked/hatchling.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class BuildLockedMetadataHook(MetadataHookInterface):
PLUGIN_NAME = "build-locked"

def update(self, metadata: dict) -> None:
update_metadata_with_locked(metadata, Path(self.root))
update_metadata_with_locked(metadata, Path(self.root), self.config.get("lock_groups"))


@hookimpl
Expand Down

0 comments on commit 017e247

Please sign in to comment.