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

pantsbuild / pants / 21378504907

26 Jan 2026 11:48PM UTC coverage: 43.218% (-37.1%) from 80.269%
21378504907

Pull #23038

github

web-flow
Merge a9ec5051e into 09b8ecaa1
Pull Request #23038: remote cache logger - new plugin to help debug the remote cache

0 of 45 new or added lines in 1 file covered. (0.0%)

17212 existing lines in 540 files now uncovered.

26144 of 60493 relevant lines covered (43.22%)

0.86 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