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

pantsbuild / pants / 20328535594

18 Dec 2025 06:46AM UTC coverage: 57.969% (-22.3%) from 80.295%
20328535594

Pull #22954

github

web-flow
Merge ccc9c5409 into 407284c67
Pull Request #22954: free up disk space in runner image

39083 of 67421 relevant lines covered (57.97%)

0.91 hits per line

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

0.0
/src/python/pants/backend/tools/semgrep/subsystem.py
1
# Copyright 2023 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
×
5

6
from collections.abc import Iterable
×
7
from dataclasses import dataclass
×
8

9
from pants.backend.python.subsystems.python_tool_base import PythonToolBase
×
10
from pants.backend.python.target_types import ConsoleScript
×
11
from pants.core.goals.resolves import ExportableTool
×
12
from pants.engine.rules import Rule, collect_rules
×
13
from pants.engine.target import Dependencies, FieldSet, SingleSourceField, Target
×
14
from pants.engine.unions import UnionRule
×
15
from pants.option.option_types import ArgsListOption, BoolOption, SkipOption, StrOption
×
16
from pants.util.strutil import softwrap
×
17

18

19
@dataclass(frozen=True)
×
20
class SemgrepFieldSet(FieldSet):
×
21
    required_fields = (SingleSourceField, Dependencies)
×
22
    source: SingleSourceField
×
23
    dependencies: Dependencies
×
24

25
    @classmethod
×
26
    def opt_out(cls, tgt: Target) -> bool:
×
27
        # FIXME: global skip_semgrep field?
28
        return False
×
29

30

31
class SemgrepSubsystem(PythonToolBase):
×
32
    name = "Semgrep"
×
33
    options_scope = "semgrep"
×
34
    help_short = softwrap(
×
35
        """
36
        Lightweight static analysis for many languages. Find bug variants with patterns that look
37
        like source code. (https://semgrep.dev/)
38

39
        Pants automatically finds config files (`.semgrep.yml`, `.semgrep.yaml`, and `.yml` or
40
        `.yaml` files within `.semgrep/` directories), and runs semgrep against all _targets_ known
41
        to Pants.
42
        """
43
    )
44

45
    default_main = ConsoleScript("semgrep")
×
46
    default_requirements = [
×
47
        "semgrep>=1.20.0,<2",
48
        # As of version 1.79.0, semgrep depends on outdated opentelemetry packages, that
49
        # themselves depend on the deprecated pkg_resources API, leading to warnings.
50
        # When semgrep updates its own requirements appropriately, we can remove these pins.
51
        # See https://github.com/semgrep/semgrep/issues/11069.
52
        "opentelemetry-api~=1.34.1",
53
        "opentelemetry-sdk~=1.34.1",
54
        "opentelemetry-exporter-otlp-proto-http~=1.34.1",
55
        "opentelemetry-instrumentation-requests~=0.55b1",
56
    ]
57

58
    register_interpreter_constraints = True
×
59

60
    register_lockfile = True
×
61
    default_lockfile_resource = ("pants.backend.tools.semgrep", "semgrep.lock")
×
62

63
    config_name = StrOption(
×
64
        default=None,
65
        help=softwrap(
66
            """
67
            The name of the semgrep config file or directory, which will be discovered and used
68
            hierarchically. If using a file, it must have the extension `.yaml` or `.yml`.
69

70
            URLs and registry names are not supported.
71
            """
72
        ),
73
    )
74

75
    args = ArgsListOption(
×
76
        example="--verbose",
77
        default=["--quiet"],
78
        extra_help="This includes --quiet by default to reduce the volume of output.",
79
    )
80

81
    skip = SkipOption("lint")
×
82

83
    force = BoolOption(
×
84
        default=False,
85
        help=softwrap(
86
            """
87
            If true, semgrep is always run, even if the input files haven't changed. This can be
88
            used to run cloud rulesets like `pants lint --semgrep-force
89
            --semgrep-args='--config=p/python' ::`. Without `--semgrep-force`, using the cloud
90
            rulesets may give inconsistent results on different machines, due to caching, because
91
            the rulesets may change.
92
            """
93
        ),
94
        advanced=True,
95
    )
96

97

98
def rules() -> Iterable[Rule | UnionRule]:
×
99
    return [
×
100
        *collect_rules(),
101
        UnionRule(ExportableTool, SemgrepSubsystem),
102
    ]
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