Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.

Commit 665f8cf

Browse files
committed
Moving project to a temp directory to perform git mutations
1 parent fe3be80 commit 665f8cf

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

semgrep_precommit/main.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@ def main() -> None:
2525
for argument in list(arguments):
2626
if is_file(argument):
2727
arguments.remove(argument)
28-
28+
temp_dir = make_tmp_dir()
29+
is_copied = copy_to_tmp(dest=temp_dir, src="/src")
30+
if not is_copied:
31+
print("Failed to copy files to temporary directory")
32+
sys.exit(1)
33+
else:
34+
add_safe_git_dir(temp_dir.name)
2935
current_commit, commit_before_current = None, None
30-
is_commit = commit_staged_files()
36+
is_commit = commit_staged_files(temp_dir.name)
3137
if is_commit:
32-
current_commit, commit_before_current = get_last_two_commit_ids()
38+
current_commit, commit_before_current = get_last_two_commit_ids(temp_dir.name)
3339
os.environ["SEMGREP_BASELINE_REF"] = commit_before_current
3440
exit_code = run_semgrep(arguments)
3541
if is_commit:
36-
soft_reset_to_commit(commit_before_current)
42+
soft_reset_to_commit(temp_dir.name, commit_before_current)
43+
temp_dir.cleanup()
3744
sys.exit(exit_code)
3845

3946
if __name__ == "__main__":

semgrep_precommit/utils.py

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
import os
2+
import shutil
23
import subprocess
4+
import tempfile
35
import typing
46

57

8+
def add_safe_git_dir(path: str) -> None:
9+
"""add_safe_git_dir marks the directory safe for git
10+
11+
Args:
12+
path (str): The path to directory
13+
"""
14+
try:
15+
subprocess.run(["git", "config", "--add", "safe.directory", path], cwd=path)
16+
except Exception:
17+
return
18+
619
def is_file(filename: str) -> bool:
720
"""is_file checks if a given value is valid a file.
821
@@ -16,10 +29,11 @@ def is_file(filename: str) -> bool:
1629
return True
1730
return False
1831

19-
def commit_staged_files(message: str = "Dummy commit by semgrep pre-commit hook") -> bool:
32+
def commit_staged_files(path: str, message: str = "Dummy commit by semgrep pre-commit hook") -> bool:
2033
"""commit_staged_files commits all staged files with a given message.
2134
2235
Args:
36+
path (str): The path to the git repository.
2337
message (str, optional): A commit message.
2438
Defaults to "Dummy commit by semgrep pre-commit hook".
2539
@@ -28,30 +42,34 @@ def commit_staged_files(message: str = "Dummy commit by semgrep pre-commit hook"
2842
"""
2943
try:
3044
# We use -n to avoid running the pre-commit hook again
31-
subprocess.run(["git", "commit", "-n", "-m", message], stdout=subprocess.DEVNULL)
45+
subprocess.run(["git", "commit", "-n", "-m", message], stdout=subprocess.DEVNULL,
46+
cwd=path)
3247
except Exception:
3348
return False
3449
else:
3550
return True
3651

37-
def get_last_two_commit_ids() -> typing.Tuple[str | None, str | None]:
52+
def get_last_two_commit_ids(path: str) -> typing.Tuple[str | None, str | None]:
3853
"""get_last_two_commit_ids returns the last two commit IDs of the current branch
3954
55+
Args:
56+
path (str): The path to the git repository.
57+
4058
Returns:
4159
typing.Tuple[str | None, str | None]: The last two commit IDs
4260
"""
4361
commit_ids = None, None
4462
try:
4563
proc = subprocess.run(["git", "log", "--pretty=format:%H", "-n", "2"],
46-
capture_output=True)
64+
capture_output=True, cwd=path)
4765
if proc.returncode == 0:
4866
commit_ids = proc.stdout.decode("utf-8").strip("\n").split("\n")
4967
except Exception:
5068
return None, None
5169
else:
5270
return tuple(commit_ids)
5371

54-
def soft_reset_to_commit(commit_id: str) -> bool:
72+
def soft_reset_to_commit(path: str, commit_id: str) -> bool:
5573
"""git_soft_reset_to_commit performs a soft reset to the previous commit
5674
5775
Args:
@@ -61,8 +79,39 @@ def soft_reset_to_commit(commit_id: str) -> bool:
6179
bool: True if the soft reset was successful, False otherwise
6280
"""
6381
try:
64-
subprocess.run(["git", "reset", "--soft", commit_id], stdout=subprocess.DEVNULL)
82+
subprocess.run(["git", "reset", "--soft", commit_id], stdout=subprocess.DEVNULL, cwd=path)
6583
except Exception:
6684
return False
6785
else:
6886
return True
87+
88+
def make_tmp_dir() -> tempfile.TemporaryDirectory:
89+
"""
90+
make_tmp_dir: Creates a temporary directory
91+
92+
Returns:
93+
tempfile.TemporaryDirectory: The tempfile.TemporaryDirectory object
94+
"""
95+
temp_dir = tempfile.TemporaryDirectory()
96+
return temp_dir
97+
98+
def copy_to_tmp(dest: str | tempfile.TemporaryDirectory, src: str = "/src") -> bool:
99+
"""
100+
copy_to_tmp: Copies the contents of the src directory to the dest directory
101+
102+
Args:
103+
dest (str | tempfile.TemporaryDirectory): A tempfile.TemporaryDirectory object or a string
104+
src (str, optional): The source path to be copied. Defaults to "/src".
105+
106+
Returns:
107+
bool: True if the copy was successful, False otherwise
108+
"""
109+
dest_name = dest
110+
if isinstance(dest_name, tempfile.TemporaryDirectory):
111+
dest_name = dest.name
112+
113+
try:
114+
shutil.copytree(src, dest_name, dirs_exist_ok=True)
115+
return True
116+
except Exception:
117+
return False

0 commit comments

Comments
 (0)