Skip to content
This repository was archived by the owner on Nov 12, 2024. It is now read-only.

Commit d3d83bd

Browse files
authored
Merge pull request #32 from alexrhein/ts/33505_ignore_submodules
TS-33505 allow ignoring submodules in precommit
2 parents 1d51344 + 158683e commit d3d83bd

2 files changed

Lines changed: 34 additions & 16 deletions

File tree

teamscale_precommit_client/git_utils.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import os
77
from io import open
88

9-
from git import Repo, InvalidGitRepositoryError
9+
from git import Repo, InvalidGitRepositoryError, Diffable
1010

1111
# [M]odified, [A]dded, [C]opied, [T]ype changed, [R]enamed (R092 should be R according to
1212
# https://gitpython.readthedocs.io/en/stable/reference.html#git.diff.DiffIndex, but testing it locally gave R092)
@@ -74,6 +74,9 @@ def filter_changed_files(changed_files, path_to_repository, file_encoding):
7474
filtered_files = []
7575
for changed_file in changed_files:
7676
file_is_valid = True
77+
if (os.path.isdir(os.path.join(path_to_repository, changed_file))):
78+
#ignore directories (e.g., git submodule folders)
79+
continue
7780
if os.path.getsize(os.path.join(path_to_repository, changed_file)) > 1 * 1024 * 1024:
7881
print('File too large for precommit analysis. Ignoring: %s' % changed_file)
7982
file_is_valid = False
@@ -97,7 +100,7 @@ def filter_changed_files(changed_files, path_to_repository, file_encoding):
97100
return filtered_files
98101

99102

100-
def get_changed_files_and_content(path_to_repository, file_encoding):
103+
def get_changed_files_and_content(path_to_repository, file_encoding, ignore_subrepositories):
101104
"""Utility method for getting the currently changed files from a Git repository.
102105
103106
Filters the changed files using `filter_changed_files`.
@@ -108,13 +111,15 @@ def get_changed_files_and_content(path_to_repository, file_encoding):
108111
109112
Returns:
110113
dict: Mapping of filename to file content for all changed files in the provided repository.
114+
:param ignore_subrepositories:
111115
"""
112-
changed_files = filter_changed_files(get_changed_files(path_to_repository), path_to_repository, file_encoding)
116+
changed_files = filter_changed_files(get_changed_files(path_to_repository, ignore_subrepositories),
117+
path_to_repository, file_encoding)
113118
return {filename: open(os.path.join(path_to_repository, filename), encoding=file_encoding).read() for filename in
114119
changed_files}
115120

116121

117-
def get_changed_files(path_to_repository):
122+
def get_changed_files(path_to_repository, ignore_subrepositories):
118123
"""Utility method for getting the currently changed files from a Git repository.
119124
120125
Args:
@@ -123,11 +128,11 @@ def get_changed_files(path_to_repository):
123128
Returns:
124129
List(str): List of filenames of all changed files in the provided repository.
125130
"""
126-
diff = _get_diff_to_last_commit(path_to_repository)
131+
diff = _get_diff_to_last_commit(path_to_repository, ignore_subrepositories)
127132
return [item.b_path for item in diff if item.change_type in _CHANGE_TYPES_CONSIDERED_FOR_PRECOMMIT]
128133

129134

130-
def get_deleted_files(path_to_repository):
135+
def get_deleted_files(path_to_repository, ignore_subrepositories):
131136
"""Utility method for getting the deleted files from a Git repository.
132137
133138
Args:
@@ -136,11 +141,11 @@ def get_deleted_files(path_to_repository):
136141
Returns:
137142
List(str): List of filenames of all deleted files in the provided repository.
138143
"""
139-
diff = _get_diff_to_last_commit(path_to_repository)
144+
diff = _get_diff_to_last_commit(path_to_repository, ignore_subrepositories)
140145
return [item.b_path for item in diff if item.change_type == _CHANGE_TYPE_DELETED]
141146

142147

143-
def _get_diff_to_last_commit(path_to_repository):
148+
def _get_diff_to_last_commit(path_to_repository, ignore_subrepositories):
144149
""" Utility method for getting a diff between the working copy and the HEAD commit
145150
146151
Args:
@@ -150,6 +155,11 @@ def _get_diff_to_last_commit(path_to_repository):
150155
List(git.diff.Diff): List of Diff objects for every file
151156
"""
152157
repo = Repo(path_to_repository)
153-
unstaged_diff = repo.index.diff(None)
154-
staged_diff = repo.head.commit.diff()
158+
if ignore_subrepositories==True:
159+
unstaged_diff = repo.index.diff(other=None, paths=None, create_patch=False, ignore_submodules="all")
160+
staged_diff = repo.head.commit.diff(other=Diffable.Index, paths=None, create_patch=False, ignore_submodules="all")
161+
else:
162+
unstaged_diff = repo.index.diff(other=None, paths=None, create_patch=False)
163+
staged_diff = repo.head.commit.diff(other=Diffable.Index, paths=None, create_patch=False)
164+
155165
return unstaged_diff + staged_diff

teamscale_precommit_client/precommit_client.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class PrecommitClient:
3232
def __init__(self, teamscale_config, repository_path, path_prefix=DEFAULT_PATH_PREFIX, project_subpath='',
3333
analyzed_file=None, verify=True, omit_links_to_findings=False, exclude_findings_in_changed_code=False,
3434
fetch_existing_findings=False, fetch_all_findings=False, fetch_existing_findings_in_changes=False,
35-
fail_on_red_findings=False, log_to_stderr=False, file_encoding=DEFAULT_FILE_ENCODING):
35+
fail_on_red_findings=False, log_to_stderr=False, file_encoding=DEFAULT_FILE_ENCODING,
36+
ignore_subrepositories=False):
3637
"""Constructor"""
3738
self.teamscale_client = TeamscaleClient(teamscale_config.url, teamscale_config.username,
3839
teamscale_config.access_token, teamscale_config.project_id, verify)
@@ -59,6 +60,7 @@ def __init__(self, teamscale_config, repository_path, path_prefix=DEFAULT_PATH_P
5960
self.current_branch = ''
6061
self.parent_commit_timestamp = 0
6162
self.file_encoding = file_encoding
63+
self.ignore_subrepositories = ignore_subrepositories
6264

6365
def run(self):
6466
"""Performs the precommit analysis. Depending on the modifications made and the flags provided to the client,
@@ -89,8 +91,9 @@ def _calculate_modifications(self):
8991
if not self.repository_path or not os.path.exists(self.repository_path) or not os.path.isdir(
9092
self.repository_path):
9193
raise RuntimeError('Invalid path to file in repository: %s' % self.repository_path)
92-
self.changed_files = get_changed_files_and_content(self.repository_path, self.file_encoding)
93-
self.deleted_files = get_deleted_files(self.repository_path)
94+
self.changed_files = get_changed_files_and_content(self.repository_path, self.file_encoding,
95+
self.ignore_subrepositories)
96+
self.deleted_files = get_deleted_files(self.repository_path, self.ignore_subrepositories)
9497

9598
def _retrieve_current_branch(self):
9699
"""Retrieves the current branch from the repository."""
@@ -315,8 +318,12 @@ def _parse_args():
315318
parser.add_argument('--file-encoding', metavar='FILE_ENCODING', type=str,
316319
help='The encoding of your files '
317320
'(c.f. https://docs.python.org/3/library/codecs.html#standard-encodings).'
318-
' By default, the system encoding will be used.',
319-
default=DEFAULT_FILE_ENCODING)
321+
' By default, the system encoding will be used.', default=DEFAULT_FILE_ENCODING)
322+
parser.add_argument('--ignore-subrepositories', dest='ignore_subrepositories', action='store_const', const=True, default=False,
323+
help='When this option is set, then we ignore subrepositories '
324+
'(git submodules) in the current repository when determining which files changed. This '
325+
'affects the files considered for precommit analysis. It does not affect the retrieval '
326+
'of "existing" findings from the Teamscale server.')
320327
return parser.parse_args()
321328

322329

@@ -344,7 +351,8 @@ def _configure_precommit_client(parsed_args):
344351
fetch_existing_findings_in_changes=parsed_args.fetch_existing_findings_in_changes,
345352
fail_on_red_findings=parsed_args.fail_on_red_findings,
346353
log_to_stderr=parsed_args.log_to_stderr,
347-
file_encoding=parsed_args.file_encoding)
354+
file_encoding=parsed_args.file_encoding,
355+
ignore_subrepositories=parsed_args.ignore_subrepositories)
348356

349357

350358
def run():

0 commit comments

Comments
 (0)