• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 21042790249

15 Jan 2026 06:57PM UTC coverage: 43.263% (-35.4%) from 78.666%
21042790249

Pull #23021

github

web-flow
Merge cc03ad8de into d250c80fe
Pull Request #23021: WIP gh workflow scie pex

23 of 33 new or added lines in 3 files covered. (69.7%)

16147 existing lines in 521 files now uncovered.

26164 of 60477 relevant lines covered (43.26%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.45
/src/python/pants/jvm/resolve/lockfile_metadata.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
2✔
5

6
from collections.abc import Iterable
2✔
7
from dataclasses import dataclass
2✔
8
from enum import Enum
2✔
9
from typing import Any, cast
2✔
10

11
from pants.core.util_rules.lockfile_metadata import (
2✔
12
    LockfileMetadata,
13
    LockfileMetadataValidation,
14
    LockfileScope,
15
    _get_metadata,
16
    lockfile_metadata_registrar,
17
)
18
from pants.jvm.resolve.common import ArtifactRequirement
2✔
19
from pants.util.ordered_set import FrozenOrderedSet
2✔
20

21
_jvm_lockfile_metadata = lockfile_metadata_registrar(LockfileScope.JVM)
2✔
22

23

24
class InvalidJVMLockfileReason(Enum):
2✔
25
    REQUIREMENTS_MISMATCH = "requirements_mismatch"
2✔
26

27

28
class LockfileContext(Enum):
2✔
29
    USER = "user"
2✔
30
    TOOL = "tool"
2✔
31

32

33
@dataclass(frozen=True)
2✔
34
class JVMLockfileMetadata(LockfileMetadata):
2✔
35
    scope = LockfileScope.JVM
2✔
36

37
    @staticmethod
2✔
38
    def new(
2✔
39
        requirements: Iterable[ArtifactRequirement],
40
    ) -> JVMLockfileMetadata:
41
        """Call the most recent version of the `LockfileMetadata` class to construct a concrete
42
        instance.
43

44
        This static method should be used in place of the `LockfileMetadata` constructor. This gives
45
        calling sites a predictable method to call to construct a new `LockfileMetadata` for
46
        writing, while still allowing us to support _reading_ older, deprecated metadata versions.
47
        """
48

UNCOV
49
        return JVMLockfileMetadataV1.from_artifact_requirements(requirements)
×
50

51
    def is_valid_for(
2✔
52
        self,
53
        requirements: Iterable[ArtifactRequirement] | None,
54
        context: LockfileContext,
55
    ) -> LockfileMetadataValidation:
56
        """Returns Truthy if this `JVMLockfileMetadata` can be used in the current execution
57
        context."""
58

59
        raise NotImplementedError("call `is_valid_for` on subclasses only")
×
60

61

62
@_jvm_lockfile_metadata(1)
2✔
63
@dataclass(frozen=True)
2✔
64
class JVMLockfileMetadataV1(JVMLockfileMetadata):
2✔
65
    """Initial metadata version for JVM user lockfiles.
66

67
    User validity is tested by the set of user requirements strings appearing as a subset of those
68
    in the metadata requirements.
69

70
    Tool validity is tested by the set of user requirements strings being an exact match of those
71
    in the metadata requirements.
72
    """
73

74
    requirements: FrozenOrderedSet[str]
2✔
75

76
    @classmethod
2✔
77
    def from_artifact_requirements(
2✔
78
        cls, requirements: Iterable[ArtifactRequirement]
79
    ) -> JVMLockfileMetadataV1:
UNCOV
80
        return cls(FrozenOrderedSet(sorted(i.to_metadata_str() for i in requirements)))
×
81

82
    @classmethod
2✔
83
    def _from_json_dict(
2✔
84
        cls: type[JVMLockfileMetadataV1],
85
        json_dict: dict[Any, Any],
86
        lockfile_description: str,
87
        error_suffix: str,
88
    ) -> JVMLockfileMetadataV1:
UNCOV
89
        metadata = _get_metadata(json_dict, lockfile_description, error_suffix)
×
90

UNCOV
91
        requirements = metadata(
×
92
            "generated_with_requirements",
93
            FrozenOrderedSet[str],
94
            FrozenOrderedSet,
95
        )
96

UNCOV
97
        return JVMLockfileMetadataV1(requirements)
×
98

99
    @classmethod
2✔
100
    def additional_header_attrs(cls, instance: LockfileMetadata) -> dict[Any, Any]:
2✔
UNCOV
101
        instance = cast(JVMLockfileMetadataV1, instance)
×
UNCOV
102
        return {
×
103
            "generated_with_requirements": (
104
                sorted(instance.requirements) if instance.requirements is not None else None
105
            )
106
        }
107

108
    def is_valid_for(
2✔
109
        self,
110
        requirements: Iterable[ArtifactRequirement] | None,
111
        context: LockfileContext,
112
    ) -> LockfileMetadataValidation:
113
        """Returns a truthy object if the request requirements match the metadata requirements."""
114

UNCOV
115
        failure_reasons: set[InvalidJVMLockfileReason] = set()
×
UNCOV
116
        req_strings = FrozenOrderedSet(sorted(i.to_metadata_str() for i in requirements or []))
×
117

UNCOV
118
        if (context == LockfileContext.USER and not self.requirements.issuperset(req_strings)) or (
×
119
            context == LockfileContext.TOOL and self.requirements != req_strings
120
        ):
121
            failure_reasons.add(InvalidJVMLockfileReason.REQUIREMENTS_MISMATCH)
×
122

UNCOV
123
        return LockfileMetadataValidation(failure_reasons)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc