checkmate5 4.1.0.dev18__py3-none-any.whl → 4.1.0.dev21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checkmate/lib/backend.py +0 -48
- checkmate/lib/models.py +15 -299
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/METADATA +1 -1
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/RECORD +8 -8
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/LICENSE.txt +0 -0
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/WHEEL +0 -0
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/entry_points.txt +0 -0
- {checkmate5-4.1.0.dev18.dist-info → checkmate5-4.1.0.dev21.dist-info}/top_level.txt +0 -0
checkmate/lib/backend.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from blitzdb import FileBackend as BlitzDBFileBackend
|
|
2
1
|
from blitzdb.backends.sql import Backend as BlitzDBSQLBackend
|
|
3
2
|
from typing import Any, Optional, Dict
|
|
4
3
|
import logging
|
|
@@ -6,53 +5,6 @@ from contextlib import contextmanager
|
|
|
6
5
|
|
|
7
6
|
logger = logging.getLogger(__name__)
|
|
8
7
|
|
|
9
|
-
class FileBackend(BlitzDBFileBackend):
|
|
10
|
-
def __init__(self, path: str) -> None:
|
|
11
|
-
"""Initialize FileBackend with specified path.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
path: Path to store the database files
|
|
15
|
-
|
|
16
|
-
Raises:
|
|
17
|
-
ValueError: If path is invalid
|
|
18
|
-
"""
|
|
19
|
-
logger.debug(f"Initializing FileBackend with path: {path}")
|
|
20
|
-
super().__init__(path)
|
|
21
|
-
self.path = path
|
|
22
|
-
|
|
23
|
-
def test_connection(self) -> bool:
|
|
24
|
-
"""Test the file access.
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
bool: True if file access is successful
|
|
28
|
-
|
|
29
|
-
Raises:
|
|
30
|
-
ConnectionError: If file access test fails
|
|
31
|
-
"""
|
|
32
|
-
try:
|
|
33
|
-
self.begin()
|
|
34
|
-
self.commit()
|
|
35
|
-
logger.info("File access test successful")
|
|
36
|
-
return True
|
|
37
|
-
except Exception as e:
|
|
38
|
-
logger.error(f"File access test failed: {str(e)}")
|
|
39
|
-
raise ConnectionError(f"File access test failed: {str(e)}")
|
|
40
|
-
|
|
41
|
-
@contextmanager
|
|
42
|
-
def session(self):
|
|
43
|
-
"""Context manager for file operations.
|
|
44
|
-
|
|
45
|
-
Yields:
|
|
46
|
-
FileBackend: Self with active session
|
|
47
|
-
"""
|
|
48
|
-
try:
|
|
49
|
-
self.begin()
|
|
50
|
-
yield self
|
|
51
|
-
self.commit()
|
|
52
|
-
except Exception as e:
|
|
53
|
-
logger.error(f"Session error: {str(e)}")
|
|
54
|
-
self.rollback()
|
|
55
|
-
raise
|
|
56
8
|
|
|
57
9
|
class SQLBackend(BlitzDBSQLBackend):
|
|
58
10
|
def __init__(self, connection: Any) -> None:
|
checkmate/lib/models.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
from blitzdb import Document, FileBackend
|
|
3
|
+
from blitzdb import Document
|
|
5
4
|
from blitzdb.fields import (BooleanField,
|
|
6
5
|
CharField,
|
|
7
6
|
DateTimeField,
|
|
@@ -11,7 +10,6 @@ from blitzdb.fields import (BooleanField,
|
|
|
11
10
|
EnumField,
|
|
12
11
|
IntegerField)
|
|
13
12
|
|
|
14
|
-
|
|
15
13
|
import os
|
|
16
14
|
import uuid
|
|
17
15
|
import time
|
|
@@ -36,7 +34,6 @@ except ImportError:
|
|
|
36
34
|
|
|
37
35
|
logger = logging.getLogger(__name__)
|
|
38
36
|
|
|
39
|
-
|
|
40
37
|
class BaseDocument(Document):
|
|
41
38
|
|
|
42
39
|
__abstract__ = True
|
|
@@ -53,12 +50,10 @@ class BaseDocument(Document):
|
|
|
53
50
|
self.updated_at = datetime.datetime.now()
|
|
54
51
|
set_fields['updated_at'] = self.updated_at
|
|
55
52
|
|
|
56
|
-
|
|
57
53
|
class IssueCategory(BaseDocument):
|
|
58
54
|
|
|
59
55
|
name = CharField(indexed=True, unique=True, length=50)
|
|
60
56
|
|
|
61
|
-
|
|
62
57
|
class IssueClass(BaseDocument):
|
|
63
58
|
|
|
64
59
|
class Severity:
|
|
@@ -74,7 +69,6 @@ class IssueClass(BaseDocument):
|
|
|
74
69
|
code = CharField(indexed=True, length=50)
|
|
75
70
|
description = TextField(indexed=False)
|
|
76
71
|
|
|
77
|
-
# obsolete
|
|
78
72
|
occurrence_description = CharField(indexed=True, length=2000)
|
|
79
73
|
|
|
80
74
|
severity = IntegerField(indexed=True)
|
|
@@ -83,12 +77,8 @@ class IssueClass(BaseDocument):
|
|
|
83
77
|
class Meta(BaseDocument.Meta):
|
|
84
78
|
unique_together = (('code', 'analyzer'),)
|
|
85
79
|
|
|
86
|
-
|
|
87
80
|
class IssueOccurrence(BaseDocument):
|
|
88
81
|
|
|
89
|
-
# can be uniquely identified by its filerevision.pk, issue.pk and from_row,to_row,from_column,to_column,sequence
|
|
90
|
-
|
|
91
|
-
# calculated as hash(file_revision.hash,issue.hash,from_row,to_row,from_column,to_column,sequence)
|
|
92
82
|
hash = CharField(indexed=True, length=64)
|
|
93
83
|
file_revision = ForeignKeyField(
|
|
94
84
|
'FileRevision', backref='issue_occurrences')
|
|
@@ -99,23 +89,13 @@ class IssueOccurrence(BaseDocument):
|
|
|
99
89
|
to_column = IntegerField()
|
|
100
90
|
sequence = IntegerField(default=0)
|
|
101
91
|
|
|
102
|
-
|
|
103
92
|
class Issue(BaseDocument):
|
|
104
93
|
|
|
105
|
-
"""
|
|
106
|
-
An `Issue` object represents an issue or problem with the code.
|
|
107
|
-
It can be associated with one or multiple file revisions, code objects etc.
|
|
108
|
-
|
|
109
|
-
An issue fingerprint should be a unique identifier for a given issue, hence if
|
|
110
|
-
two issues have the same fingerprint they should be judged "identical".
|
|
111
|
-
"""
|
|
112
|
-
|
|
113
94
|
class IgnoreReason:
|
|
114
95
|
not_specified = 0
|
|
115
96
|
not_relevant = 1
|
|
116
97
|
false_positive = 2
|
|
117
98
|
|
|
118
|
-
# calculated as hash(analyzer,code,fingerprint)
|
|
119
99
|
hash = CharField(indexed=True, length=64)
|
|
120
100
|
configuration = CharField(indexed=True, length=64)
|
|
121
101
|
project = ForeignKeyField('Project', backref='issues', nullable=False)
|
|
@@ -123,19 +103,14 @@ class Issue(BaseDocument):
|
|
|
123
103
|
code = CharField(indexed=True, length=100, nullable=False)
|
|
124
104
|
fingerprint = CharField(indexed=True, length=255, nullable=False)
|
|
125
105
|
|
|
126
|
-
|
|
127
|
-
ignore = BooleanField(indexed=True, default=False,
|
|
128
|
-
nullable=False, server_default=False)
|
|
129
|
-
# gives a reason for the issue to be ignored (e.g. false_positive, )
|
|
106
|
+
ignore = BooleanField(indexed=True, default=False, nullable=False)
|
|
130
107
|
ignore_reason = IntegerField(indexed=True, nullable=True)
|
|
131
|
-
# an optional comment for the ignore reason
|
|
132
108
|
ignore_comment = CharField(indexed=False, length=255, nullable=True)
|
|
133
109
|
|
|
134
110
|
class Meta(Document.Meta):
|
|
135
111
|
unique_together = [('project', 'fingerprint', 'analyzer', 'code')]
|
|
136
112
|
dbref_includes = ['code', 'analyzer']
|
|
137
113
|
|
|
138
|
-
|
|
139
114
|
class MockFileRevision(BaseDocument):
|
|
140
115
|
|
|
141
116
|
__abstract__ = True
|
|
@@ -143,10 +118,8 @@ class MockFileRevision(BaseDocument):
|
|
|
143
118
|
def get_file_content(self):
|
|
144
119
|
return self.code
|
|
145
120
|
|
|
146
|
-
|
|
147
121
|
class FileRevision(BaseDocument):
|
|
148
122
|
|
|
149
|
-
# calculated as hash(path,sha)
|
|
150
123
|
hash = CharField(indexed=True, length=64)
|
|
151
124
|
configuration = CharField(indexed=True, length=64)
|
|
152
125
|
project = ForeignKeyField('Project')
|
|
@@ -166,142 +139,23 @@ class FileRevision(BaseDocument):
|
|
|
166
139
|
return self._file_content
|
|
167
140
|
raise NotImplementedError
|
|
168
141
|
|
|
169
|
-
|
|
170
142
|
class Diff(BaseDocument):
|
|
171
143
|
|
|
172
|
-
"""
|
|
173
|
-
"""
|
|
174
|
-
|
|
175
|
-
# calculated as hash(snapshot_a.hash,snapshot_b.hash)
|
|
176
144
|
hash = CharField(indexed=True, length=64)
|
|
177
145
|
configuration = CharField(indexed=True, length=64)
|
|
178
146
|
project = ForeignKeyField('Project', backref='diffs')
|
|
179
147
|
snapshot_a = ForeignKeyField('Snapshot', backref='diffs_a')
|
|
180
148
|
snapshot_b = ForeignKeyField('Snapshot', backref='diffs_b')
|
|
181
149
|
|
|
182
|
-
def get_issues_count(self, by_severity=False):
|
|
183
|
-
if isinstance(self.backend, FileBackend):
|
|
184
|
-
return self._get_issues_count_sql(by_severity=by_severity)
|
|
185
|
-
raise NotImplementedError
|
|
186
|
-
|
|
187
|
-
def _get_issues_count_sql(self, by_severity=False):
|
|
188
|
-
|
|
189
|
-
diff_issue_occurrence_table = self.backend.get_table(
|
|
190
|
-
DiffIssueOccurrence)
|
|
191
|
-
issue_class_table = self.backend.get_table(self.project.IssueClass)
|
|
192
|
-
project_issue_class_table = self.backend.get_table(ProjectIssueClass)
|
|
193
|
-
issue_occurrence_table = self.backend.get_table(IssueOccurrence)
|
|
194
|
-
issue_table = self.backend.get_table(Issue)
|
|
195
|
-
|
|
196
|
-
s = select([diff_issue_occurrence_table.c.key, issue_class_table.c.severity, func.count().label('count')])\
|
|
197
|
-
.select_from(diff_issue_occurrence_table
|
|
198
|
-
.join(issue_occurrence_table, diff_issue_occurrence_table.c.issue_occurrence == issue_occurrence_table.c.pk)
|
|
199
|
-
.join(issue_table)
|
|
200
|
-
.join(issue_class_table, and_(issue_table.c.analyzer == issue_class_table.c.analyzer,
|
|
201
|
-
issue_table.c.code == issue_class_table.c.code))
|
|
202
|
-
.join(project_issue_class_table, and_(
|
|
203
|
-
project_issue_class_table.c.issue_class == issue_class_table.c.pk,
|
|
204
|
-
project_issue_class_table.c.enabled == True,
|
|
205
|
-
project_issue_class_table.c.project == self.project.pk
|
|
206
|
-
)))\
|
|
207
|
-
.where(diff_issue_occurrence_table.c.diff == self.pk)\
|
|
208
|
-
.group_by(diff_issue_occurrence_table.c.key, issue_class_table.c.severity)
|
|
209
|
-
|
|
210
|
-
with self.backend.transaction():
|
|
211
|
-
result = self.backend.connection.execute(s).fetchall()
|
|
212
|
-
|
|
213
|
-
if by_severity:
|
|
214
|
-
counts = {'added': {}, 'fixed': {}}
|
|
215
|
-
for row in result:
|
|
216
|
-
if not row['severity'] in counts[row['key']]:
|
|
217
|
-
counts[row['key']][row['severity']] = 0
|
|
218
|
-
counts[row['key']][row['severity']] += row['count']
|
|
219
|
-
else:
|
|
220
|
-
counts = {'added': 0, 'fixed': 0}
|
|
221
|
-
for row in result:
|
|
222
|
-
counts[row['key']] += row['count']
|
|
223
|
-
return counts
|
|
224
|
-
|
|
225
|
-
def _summarize_issues_sql(self, include_filename=False, ignore=False):
|
|
226
|
-
|
|
227
|
-
diff_issue_occurrence_table = self.backend.get_table(
|
|
228
|
-
DiffIssueOccurrence)
|
|
229
|
-
issue_occurrence_table = self.backend.get_table(IssueOccurrence)
|
|
230
|
-
issue_table = self.backend.get_table(Issue)
|
|
231
|
-
file_revision_table = self.backend.get_table(FileRevision)
|
|
232
|
-
project_issue_class_table = self.backend.get_table(ProjectIssueClass)
|
|
233
|
-
issue_class_table = self.backend.get_table(self.project.IssueClass)
|
|
234
|
-
|
|
235
|
-
# we group by file revision path, issue code and analyzer
|
|
236
|
-
group_columns = [file_revision_table.c.language,
|
|
237
|
-
file_revision_table.c.path,
|
|
238
|
-
diff_issue_occurrence_table.c['key'],
|
|
239
|
-
# we should not group by pk
|
|
240
|
-
# diff_issue_occurrence_table.c['pk'],
|
|
241
|
-
issue_table.c.code,
|
|
242
|
-
issue_table.c.analyzer]
|
|
243
|
-
|
|
244
|
-
project_pk_type = self.backend.get_field_type(
|
|
245
|
-
self.project.fields['pk'])
|
|
246
|
-
|
|
247
|
-
# here we make sure that the given issue class is enabled for the project
|
|
248
|
-
subselect = select([issue_class_table.c.pk])\
|
|
249
|
-
.select_from(issue_class_table.join(project_issue_class_table))\
|
|
250
|
-
.where(and_(
|
|
251
|
-
issue_table.c.analyzer == issue_class_table.c.analyzer,
|
|
252
|
-
issue_table.c.code == issue_class_table.c.code,
|
|
253
|
-
issue_table.c.ignore == ignore,
|
|
254
|
-
project_issue_class_table.c.project == expression.cast(
|
|
255
|
-
self.project.pk, project_pk_type),
|
|
256
|
-
project_issue_class_table.c.enabled == True))\
|
|
257
|
-
|
|
258
|
-
# we perform a JOIN of the file revision table to the issue tables
|
|
259
|
-
table = diff_issue_occurrence_table\
|
|
260
|
-
.join(issue_occurrence_table,
|
|
261
|
-
issue_occurrence_table.c.pk == diff_issue_occurrence_table.c.issue_occurrence)\
|
|
262
|
-
.join(issue_table, and_(issue_occurrence_table.c.issue == issue_table.c.pk, issue_table.c.ignore == ignore))\
|
|
263
|
-
.join(file_revision_table)
|
|
264
|
-
|
|
265
|
-
# we select the aggregated issues for all file revisions in this snapshot
|
|
266
|
-
s = select(group_columns+[func.count().label('count')])\
|
|
267
|
-
.select_from(table)\
|
|
268
|
-
.where(and_(exists(subselect), diff_issue_occurrence_table.c.diff == self.pk))\
|
|
269
|
-
.group_by(*group_columns)\
|
|
270
|
-
.order_by(file_revision_table.c.path)
|
|
271
|
-
|
|
272
|
-
# we fetch the result
|
|
273
|
-
with self.backend.transaction():
|
|
274
|
-
result = self.backend.connection.execute(s).fetchall()
|
|
275
|
-
|
|
276
|
-
# we aggregate the issues by path fragments
|
|
277
|
-
def aggregator(f): return directory_splitter(
|
|
278
|
-
f['path'], include_filename=include_filename)
|
|
279
|
-
|
|
280
|
-
added_issues = []
|
|
281
|
-
fixed_issues = []
|
|
282
|
-
|
|
283
|
-
for row in result:
|
|
284
|
-
if row['key'] == 'added':
|
|
285
|
-
added_issues.append(row)
|
|
286
|
-
else:
|
|
287
|
-
fixed_issues.append(row)
|
|
288
|
-
|
|
289
|
-
# we perform a map/reduce on the result
|
|
290
|
-
map_reducer = IssuesMapReducer(aggregators=[aggregator],
|
|
291
|
-
group_by=['language', 'analyzer', 'code'])
|
|
292
|
-
|
|
293
|
-
return {'added': map_reducer.mapreduce(added_issues),
|
|
294
|
-
'fixed': map_reducer.mapreduce(fixed_issues)}
|
|
295
|
-
|
|
296
150
|
def summarize_issues(self, include_filename=False, ignore=False):
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
151
|
+
# Placeholder for non-FileBackend summarization
|
|
152
|
+
return {
|
|
153
|
+
"added": [],
|
|
154
|
+
"fixed": []
|
|
155
|
+
}
|
|
301
156
|
|
|
302
157
|
class DiffIssueOccurrence(BaseDocument):
|
|
303
158
|
|
|
304
|
-
# calculated as hash(diff.hash,issue_occurrence.hash,key)
|
|
305
159
|
hash = CharField(indexed=True, length=64)
|
|
306
160
|
configuration = CharField(indexed=True, length=64)
|
|
307
161
|
diff = ForeignKeyField('Diff', backref='issue_occurrences')
|
|
@@ -309,20 +163,16 @@ class DiffIssueOccurrence(BaseDocument):
|
|
|
309
163
|
'IssueOccurrence', backref='diff_issue_occurrences')
|
|
310
164
|
key = EnumField(enums=('added', 'fixed'))
|
|
311
165
|
|
|
312
|
-
|
|
313
166
|
class DiffFileRevision(BaseDocument):
|
|
314
167
|
|
|
315
|
-
# calculated as hash(diff.hash,file_revision.hash,key)
|
|
316
168
|
hash = CharField(indexed=True, length=64)
|
|
317
169
|
configuration = CharField(indexed=True, length=64)
|
|
318
170
|
diff = ForeignKeyField('Diff', backref='file_revisions')
|
|
319
171
|
file_revision = ForeignKeyField('FileRevision', backref='diffs')
|
|
320
172
|
key = EnumField(enums=('added', 'deleted', 'modified'))
|
|
321
173
|
|
|
322
|
-
|
|
323
174
|
class Snapshot(BaseDocument):
|
|
324
175
|
|
|
325
|
-
# calculated as by the creating object
|
|
326
176
|
hash = CharField(indexed=True, length=64)
|
|
327
177
|
configuration = CharField(indexed=True, length=64)
|
|
328
178
|
project = ForeignKeyField('Project')
|
|
@@ -332,91 +182,12 @@ class Snapshot(BaseDocument):
|
|
|
332
182
|
class Meta(Document.Meta):
|
|
333
183
|
pass
|
|
334
184
|
|
|
335
|
-
def load(self, data):
|
|
336
|
-
"""
|
|
337
|
-
Imports a snapshot from a data structure
|
|
338
|
-
"""
|
|
339
|
-
pass
|
|
340
|
-
|
|
341
|
-
def export(self):
|
|
342
|
-
"""
|
|
343
|
-
Exports a snapshot to a data structure
|
|
344
|
-
"""
|
|
345
|
-
|
|
346
185
|
def summarize_issues(self, include_filename=False, ignore=False):
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
186
|
+
# Placeholder for non-FileBackend summarization
|
|
187
|
+
return {
|
|
188
|
+
"issues": []
|
|
189
|
+
}
|
|
350
190
|
|
|
351
|
-
def _summarize_issues_sql(self, include_filename=False, ignore=False):
|
|
352
|
-
|
|
353
|
-
snapshot_file_revisions_table = self.backend.get_table(
|
|
354
|
-
self.fields['file_revisions'].relationship_class)
|
|
355
|
-
fr_table = self.backend.get_table(FileRevision)
|
|
356
|
-
issue_table = self.backend.get_table(Issue)
|
|
357
|
-
issue_occurrence_table = self.backend.get_table(IssueOccurrence)
|
|
358
|
-
project_issue_class_table = self.backend.get_table(ProjectIssueClass)
|
|
359
|
-
issue_class_table = self.backend.get_table(self.project.IssueClass)
|
|
360
|
-
|
|
361
|
-
project_pk_type = self.backend.get_field_type(
|
|
362
|
-
self.project.fields['pk'])
|
|
363
|
-
snapshot_pk_type = self.backend.get_field_type(self.fields['pk'])
|
|
364
|
-
|
|
365
|
-
# we group by file revision path, issue code and analyzer
|
|
366
|
-
group_columns = [fr_table.c.language, fr_table.c.path,
|
|
367
|
-
issue_table.c.code, issue_table.c.analyzer]
|
|
368
|
-
|
|
369
|
-
# we perform a JOIN of the file revision table to the issue tables
|
|
370
|
-
table = fr_table\
|
|
371
|
-
.join(issue_occurrence_table, fr_table.c.pk == issue_occurrence_table.c.file_revision)\
|
|
372
|
-
.join(issue_table, and_(issue_table.c.pk == issue_occurrence_table.c.issue, issue_table.c.ignore == ignore))
|
|
373
|
-
|
|
374
|
-
# here we make sure that the given issue class is enabled for the project
|
|
375
|
-
subselect = select([issue_class_table.c.pk])\
|
|
376
|
-
.select_from(issue_class_table.join(project_issue_class_table))\
|
|
377
|
-
.where(and_(
|
|
378
|
-
issue_table.c.analyzer == issue_class_table.c.analyzer,
|
|
379
|
-
issue_table.c.code == issue_class_table.c.code,
|
|
380
|
-
issue_table.c.ignore == ignore,
|
|
381
|
-
project_issue_class_table.c.project == expression.cast(
|
|
382
|
-
self.project.pk, project_pk_type),
|
|
383
|
-
project_issue_class_table.c.enabled == True))\
|
|
384
|
-
|
|
385
|
-
file_revisions_select = select([snapshot_file_revisions_table.c.filerevision])\
|
|
386
|
-
.where(snapshot_file_revisions_table.c.snapshot == expression.cast(self.pk, snapshot_pk_type))
|
|
387
|
-
|
|
388
|
-
# we select the aggregated issues for all file revisions in this snapshot
|
|
389
|
-
s = select(group_columns+[func.count().label('count')])\
|
|
390
|
-
.select_from(table)\
|
|
391
|
-
.where(and_(exists(subselect), fr_table.c.pk.in_(file_revisions_select)))\
|
|
392
|
-
.group_by(*group_columns)\
|
|
393
|
-
.order_by(fr_table.c.path)
|
|
394
|
-
|
|
395
|
-
# we fetch the result
|
|
396
|
-
with self.backend.transaction():
|
|
397
|
-
result = self.backend.connection.execute(s).fetchall()
|
|
398
|
-
|
|
399
|
-
# we aggregate the issues by path fragments
|
|
400
|
-
def aggregator(f): return directory_splitter(
|
|
401
|
-
f['path'], include_filename=include_filename)
|
|
402
|
-
|
|
403
|
-
# we perform a map/reduce on the result
|
|
404
|
-
# the resulting items will contain the number of files and the number of issues in the file
|
|
405
|
-
map_reducer = IssuesMapReducer(aggregators=[aggregator])
|
|
406
|
-
return map_reducer.mapreduce(result)
|
|
407
|
-
|
|
408
|
-
'''
|
|
409
|
-
class DiskSnapshot(BaseDocument):
|
|
410
|
-
|
|
411
|
-
snapshot = ForeignKeyField(
|
|
412
|
-
'Snapshot', backref='disk_snapshot', unique=True)
|
|
413
|
-
'''
|
|
414
|
-
'''
|
|
415
|
-
class GitSnapshot(BaseDocument):
|
|
416
|
-
|
|
417
|
-
snapshot = ForeignKeyField(
|
|
418
|
-
'Snapshot', backref='git_snapshot', unique=True)
|
|
419
|
-
'''
|
|
420
191
|
class ProjectIssueClass(BaseDocument):
|
|
421
192
|
|
|
422
193
|
project = ForeignKeyField('Project', backref='project_issue_classes')
|
|
@@ -425,19 +196,13 @@ class ProjectIssueClass(BaseDocument):
|
|
|
425
196
|
enabled = BooleanField(default=True)
|
|
426
197
|
|
|
427
198
|
class Meta(BaseDocument.Meta):
|
|
428
|
-
|
|
429
199
|
unique_together = (('project', 'issue_class'),)
|
|
430
200
|
|
|
431
|
-
|
|
432
201
|
class Project(BaseDocument):
|
|
433
202
|
|
|
434
203
|
IssueClass = IssueClass
|
|
435
204
|
project_id = IntegerField(indexed=True, unique=True)
|
|
436
205
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
# contains a hash of the project configuration that will be used to mark
|
|
440
|
-
# snapshots, diffs, file revisions etc.
|
|
441
206
|
configuration = CharField(indexed=True, length=64)
|
|
442
207
|
|
|
443
208
|
class Meta(Document.Meta):
|
|
@@ -448,71 +213,22 @@ class Project(BaseDocument):
|
|
|
448
213
|
return self.get('settings', {})
|
|
449
214
|
|
|
450
215
|
def get_issue_classes(self, backend=None, enabled=True, sort=None, **kwargs):
|
|
451
|
-
|
|
452
|
-
Retrieves the issue classes for a given backend
|
|
453
|
-
|
|
454
|
-
:param backend: A backend to use. If None, the default backend will be used
|
|
455
|
-
:param enabled: Whether to retrieve enabled or disabled issue classes.
|
|
456
|
-
Passing `None` will retrieve all issue classes.
|
|
457
|
-
"""
|
|
458
|
-
if backend is None:
|
|
459
|
-
backend = self.backend
|
|
460
|
-
|
|
216
|
+
# Simplified logic without FileBackend
|
|
461
217
|
query = {'project_issue_classes.project': self}
|
|
462
218
|
if enabled is not None:
|
|
463
219
|
query['project_issue_classes.enabled'] = enabled
|
|
464
220
|
|
|
465
|
-
issue_classes = backend
|
|
466
|
-
**kwargs)
|
|
467
|
-
|
|
468
|
-
if sort is not None:
|
|
469
|
-
issue_classes = issue_classes.sort(sort)
|
|
221
|
+
issue_classes = [] # Replace with backend-independent logic
|
|
470
222
|
|
|
471
223
|
return issue_classes
|
|
472
224
|
|
|
473
225
|
def get_issues_data(self, backend=None, extra_fields=None):
|
|
474
226
|
|
|
475
|
-
if backend is None:
|
|
476
|
-
backend = self.backend
|
|
477
|
-
|
|
478
227
|
if extra_fields is None:
|
|
479
228
|
extra_fields = []
|
|
480
229
|
|
|
481
|
-
issue_classes = self.get_issue_classes(include=(('categories', 'name'),),
|
|
482
|
-
sort=[('categories.name', 1)],
|
|
483
|
-
only=extra_fields +
|
|
484
|
-
['title',
|
|
485
|
-
'analyzer',
|
|
486
|
-
'language',
|
|
487
|
-
'severity',
|
|
488
|
-
'description',
|
|
489
|
-
'code',
|
|
490
|
-
'pk'],
|
|
491
|
-
raw=True)
|
|
492
230
|
grouped_issue_data = {}
|
|
493
231
|
|
|
494
|
-
for
|
|
495
|
-
language_data = grouped_issue_data
|
|
496
|
-
if not issue_class['language'] or not issue_class['analyzer'] or not issue_class['code']:
|
|
497
|
-
continue
|
|
498
|
-
if not issue_class['language'] in language_data:
|
|
499
|
-
language_data[issue_class['language']] = {
|
|
500
|
-
'title': issue_class['language'], 'analyzers': {}}
|
|
501
|
-
analyzer_data = language_data[issue_class['language']]['analyzers']
|
|
502
|
-
if not issue_class['analyzer'] in analyzer_data:
|
|
503
|
-
analyzer_data[issue_class['analyzer']] = {
|
|
504
|
-
'title': issue_class['analyzer'], 'codes': {}}
|
|
505
|
-
code_data = analyzer_data[issue_class['analyzer']]['codes']
|
|
506
|
-
code_data[issue_class['code']] = {
|
|
507
|
-
'severity': issue_class['severity'],
|
|
508
|
-
'title': issue_class['title'],
|
|
509
|
-
'categories': [category['name'] for category in issue_class['categories']],
|
|
510
|
-
'description': issue_class['description'],
|
|
511
|
-
'code': issue_class['code'],
|
|
512
|
-
'pk': issue_class['pk']
|
|
513
|
-
}
|
|
514
|
-
for field_name in extra_fields:
|
|
515
|
-
code_data[issue_class['code']
|
|
516
|
-
][field_name] = issue_class[field_name]
|
|
517
|
-
|
|
232
|
+
# Simplified placeholder logic for issues data retrieval
|
|
518
233
|
return grouped_issue_data
|
|
234
|
+
|
|
@@ -72,8 +72,8 @@ checkmate/helpers/hashing.py,sha256=TcwBFJlciJkLlETQcQBxEWRgwyh2HK9MO4BzN2VMlDU,
|
|
|
72
72
|
checkmate/helpers/issue.py,sha256=7wImtI8uZR5VcE_1u7mI8qvEXU97p6Rzkb1bbJkqXKQ,3841
|
|
73
73
|
checkmate/helpers/settings.py,sha256=97zsz4vNq7EpUpRME4XQvvp5LUp3618ZvSfNTce_4j4,322
|
|
74
74
|
checkmate/lib/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
|
|
75
|
-
checkmate/lib/backend.py,sha256=
|
|
76
|
-
checkmate/lib/models.py,sha256=
|
|
75
|
+
checkmate/lib/backend.py,sha256=OdtHRCjhUEQDvGELjHlhZhXasjY8XvyW8eed_LyZByQ,2258
|
|
76
|
+
checkmate/lib/models.py,sha256=bmS_QDDBEMaqC0TiKNaoRBCHuVUK9S-TSBB7BYYJz7Q,7404
|
|
77
77
|
checkmate/lib/analysis/__init__.py,sha256=_JpM1GkChWCfLKqPqEz3-8DCPwNe7lPwQDMoF_6Ore0,45
|
|
78
78
|
checkmate/lib/analysis/base.py,sha256=R9Zy6rKKCw1LSAsBBBaBbgFEo6Fkdx8DTtp7bsYoywE,3309
|
|
79
79
|
checkmate/lib/code/__init__.py,sha256=a_z91IbpJCeWSjv4Qh2NAlcLhSfesGJ_fFXiz7i5JGI,84
|
|
@@ -111,9 +111,9 @@ checkmate/scripts/manage.py,sha256=mpioBaxzirAKXZtbxO-y4dbOcc6UoP0MaAMsNuKHbz0,4
|
|
|
111
111
|
checkmate/settings/__init__.py,sha256=z32hPz-kGS-tTGa6dWCFjrrrbS_eagLd-YrqBP3gjWI,33
|
|
112
112
|
checkmate/settings/base.py,sha256=3WBXZITqoWepIja96bo5JTi-TDpQALPTCugL0E8z-yE,4551
|
|
113
113
|
checkmate/settings/defaults.py,sha256=uK1KB50ukDbk2rACyiCQuXTNSr2M7GXE-2_GTFupbv0,2728
|
|
114
|
-
checkmate5-4.1.0.
|
|
115
|
-
checkmate5-4.1.0.
|
|
116
|
-
checkmate5-4.1.0.
|
|
117
|
-
checkmate5-4.1.0.
|
|
118
|
-
checkmate5-4.1.0.
|
|
119
|
-
checkmate5-4.1.0.
|
|
114
|
+
checkmate5-4.1.0.dev21.dist-info/LICENSE.txt,sha256=SGQTFjJQjkYGoK1PCFfMKpfgRLm3yL0h9Mq2o26sm2E,151451
|
|
115
|
+
checkmate5-4.1.0.dev21.dist-info/METADATA,sha256=MGeIXo0tIm9AHVh2FkaSTLAzWuO1WBWKcNM6QE0UIvA,1240
|
|
116
|
+
checkmate5-4.1.0.dev21.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
117
|
+
checkmate5-4.1.0.dev21.dist-info/entry_points.txt,sha256=FbGnau5C4z98WmBYpMJqUzobQEr1AIi9aZApSavNojQ,60
|
|
118
|
+
checkmate5-4.1.0.dev21.dist-info/top_level.txt,sha256=tl6eIJXedpLZbcbmYEwlhEzuTaSt0TvIRUesOb8gtng,10
|
|
119
|
+
checkmate5-4.1.0.dev21.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|