-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathsemgrep.py
More file actions
52 lines (49 loc) · 1.77 KB
/
semgrep.py
File metadata and controls
52 lines (49 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import subprocess
import itertools
from tempfile import NamedTemporaryFile
from typing import Iterable, Optional
from pathlib import Path
from codemodder.context import CodemodExecutionContext
from codemodder.sarifs import SarifResultSet
from codemodder.logging import logger
def run(
execution_context: CodemodExecutionContext,
yaml_files: Iterable[Path],
files_to_analyze: Optional[Iterable[Path]] = None,
) -> SarifResultSet:
"""
Runs Semgrep and outputs a dict with the results organized by rule_id.
"""
if not yaml_files:
raise ValueError("No Semgrep rules were provided")
with NamedTemporaryFile(prefix="semgrep", suffix=".sarif") as temp_sarif_file:
command = [
"semgrep",
"scan",
"--legacy",
"--no-error",
"--dataflow-traces",
"--sarif",
"-o",
temp_sarif_file.name,
]
command.extend(
itertools.chain.from_iterable(
map(lambda f: ["--config", str(f)], yaml_files)
)
)
command.extend(map(str, files_to_analyze or [execution_context.directory]))
logger.debug("semgrep command: `%s`", " ".join(command))
call = subprocess.run(
command,
shell=False,
check=False,
stdout=None if execution_context.verbose else subprocess.PIPE,
stderr=None if execution_context.verbose else subprocess.PIPE,
)
if call.returncode != 0:
if not execution_context.verbose:
logger.error("captured semgrep stderr: %s", call.stderr)
raise subprocess.CalledProcessError(call.returncode, command)
results = SarifResultSet.from_sarif(temp_sarif_file.name)
return results