Skip to content

Commit

Permalink
Added blame info feature for "cmd results" command
Browse files Browse the repository at this point in the history
Blame information for reports was only available on the GUI. Now, if we wish to check the git commit info in the cli, we can do that with "CodeChecker cmd results --details" command
We can only check blame info for runs that have a git repository. The server address and the run name should also be given, e.g.: "CodeChecker cmd results --details --url http://localhost:8001/Default test".
The syntax is different in the GUI, as there you can check the blame info for each line of a reported file. In case of the cli, it would be huge output result to print long blame info for every report. A filtered one is added to the report data, which contains only the commit data of the given section.
  • Loading branch information
cservakt committed Sep 14, 2023
1 parent 0ba087d commit 76e443e
Show file tree
Hide file tree
Showing 12 changed files with 71 additions and 23 deletions.
3 changes: 2 additions & 1 deletion web/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ container so `docker` needs to be installed to generate the stubs.
- [`py/codechecker_api/setup.py`](py/codechecker_api/setup.py)
- [`py/codechecker_api_shared/setup.py`](py/codechecker_api_shared/setup.py)
- [`js/codechecker-api-node/package.json`](js/codechecker-api-node/package.json)
- [`/web/server/vue-cli/package.json`](/web/server/vue-cli/package.json)
- Let's assume that the current API version is `6.39.0`. Run the
[change-api-version.sh](change-api-version.sh) script to increment the API
version: `change-api-version.sh 6.40.0`.
- Update the supported api versions to `6.40` in the server files:
- `web/codechecker_web/shared/version.py`
- `/web/codechecker_web/shared/version.py`
- Run the command `make build` to generate the Thrift API stubs and to create
new pypi and npm packages. It will modify the following files:
- [`py/codechecker_api/dist/codechecker_api.tar.gz`](py/codechecker_api/dist/codechecker_api.tar.gz)
Expand Down
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/js/codechecker-api-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codechecker-api",
"version": "6.53.0",
"version": "6.54.0",
"description": "Generated node.js compatible API stubs for CodeChecker server.",
"main": "lib",
"homepage": "https://github.com/Ericsson/codechecker",
Expand Down
Binary file modified web/api/py/codechecker_api/dist/codechecker_api.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/py/codechecker_api/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
with open('README.md', encoding='utf-8', errors="ignore") as f:
long_description = f.read()

api_version = '6.53.0'
api_version = '6.54.0'

setup(
name='codechecker_api',
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion web/api/py/codechecker_api_shared/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
with open('README.md', encoding='utf-8', errors="ignore") as f:
long_description = f.read()

api_version = '6.53.0'
api_version = '6.54.0'

setup(
name='codechecker_api_shared',
Expand Down
31 changes: 16 additions & 15 deletions web/api/report_server.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -304,27 +304,28 @@ struct ReviewStatusRule {
typedef list<ReviewStatusRule> ReviewStatusRules

struct ReportData {
1: i64 runId, // Unique id of the run.
2: string checkerId, // The qualified name of the checker that reported this.
3: string bugHash, // This is unique id of the concrete report.
4: string checkedFile, // This is a filepath, the original main file the analyzer was called with.
5: string checkerMsg, // Description of the bug report.
6: i64 reportId, // id of the report in the current run in the db.
7: i64 fileId, // Unique id of the file the report refers to.
8: i64 line, // line number or the reports main section (not part of the path).
9: i64 column, // column number of the report main section (not part of the path).
10: Severity severity, // Checker severity.
11: ReviewData reviewData, // Bug review status information.
1: i64 runId, // Unique id of the run.
2: string checkerId, // The qualified name of the checker that reported this.
3: string bugHash, // This is unique id of the concrete report.
4: string checkedFile, // This is a filepath, the original main file the analyzer was called with.
5: string checkerMsg, // Description of the bug report.
6: i64 reportId, // id of the report in the current run in the db.
7: i64 fileId, // Unique id of the file the report refers to.
8: i64 line, // line number or the reports main section (not part of the path).
9: i64 column, // column number of the report main section (not part of the path).
10: Severity severity, // Checker severity.
11: ReviewData reviewData, // Bug review status information.
12: DetectionStatus detectionStatus, // State of the bug (see the enum constant values).
13: string detectedAt, // Detection date of the report.
14: string fixedAt // Date when the report was fixed.
15: i64 bugPathLength, // Length of the bug path.
16: optional ReportDetails details, // Details of the report.
17: optional string analyzerName, // Analyzer name.
15: i64 bugPathLength, // Length of the bug path.
16: optional ReportDetails details, // Details of the report.
17: optional BlameInfo blameInfo, // Blmae info.
18: optional string analyzerName, // Analyzer name.
// Report annotations are key-value pairs attached to a report. This is a set
// of custom labels that describe some properties of a report. For example the
// timestamp in case of dynamic analyzers when the report was actually emitted.
18: optional map<string, string> annotations,
19: optional map<string, string> annotations,
}
typedef list<ReportData> ReportDataList

Expand Down
2 changes: 1 addition & 1 deletion web/codechecker_web/shared/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# The newest supported minor version (value) for each supported major version
# (key) in this particular build.
SUPPORTED_VERSIONS = {
6: 53
6: 54
}

# Used by the client to automatically identify the latest major and minor
Expand Down
50 changes: 48 additions & 2 deletions web/server/codechecker_server/api/report_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1901,9 +1901,15 @@ def getRunResults(self, run_ids, limit, offset, sort_types,

# Get report details if it is required.
report_details = {}
blame_infos = {}
if get_details:
report_ids = [r[0].id for r in query_result]
report_ids, blames = zip(*[
(
r[0].id,
(r[0].id, self.getBlameInfo(r[0].file_id))
) for r in query_result])
report_details = get_report_details(session, report_ids)
blame_infos = dict(blames)

for row in query_result:
report = row[0]
Expand All @@ -1919,6 +1925,22 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
report.review_status_date,
report.review_status_is_in_source)

blame_info = blame_infos[report.id] \
if report.id in blame_infos else None
if blame_info:
blame_data = [b for b in blame_info.blame
if report.line >= b.startLine
and report.line <= b.endLine]
commitHash = blame_data[0].commitHash \
if len(blame_data) else None
commitInfo = {cHash: commit for cHash, commit
in blame_info.commits.items()
if cHash == commitHash}
blame_info = BlameInfo(
commits=commitInfo,
blame=blame_data
)

results.append(
ReportData(runId=report.run_id,
bugHash=report.bug_id,
Expand All @@ -1937,6 +1959,7 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
fixedAt=str(report.fixed_at),
bugPathLength=report.path_length,
details=report_details.get(report.id),
blameInfo=blame_info,
analyzerName=report.analyzer_name,
annotations=annotations))
else: # not is_unique
Expand Down Expand Up @@ -1986,9 +2009,15 @@ def getRunResults(self, run_ids, limit, offset, sort_types,

# Get report details if it is required.
report_details = {}
blame_infos = {}
if get_details:
report_ids = [r[0].id for r in query_result]
report_ids, blames = zip(*[
(
r[0].id,
(r[0].id, self.getBlameInfo(r[0].file_id))
) for r in query_result])
report_details = get_report_details(session, report_ids)
blame_infos = dict(blames)

for row in query_result:
report = row[0]
Expand All @@ -2004,6 +2033,22 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
report.review_status_date,
report.review_status_is_in_source)

blame_info = blame_infos[report.id] \
if report.id in blame_infos else None
if blame_info:
blame_data = [b for b in blame_info.blame
if report.line >= b.startLine
and report.line <= b.endLine]
commitHash = blame_data[0].commitHash \
if len(blame_data) else None
commitInfo = {cHash: commit for cHash, commit
in blame_info.commits.items()
if cHash == commitHash}
blame_info = BlameInfo(
commits=commitInfo,
blame=blame_data
)

results.append(
ReportData(runId=report.run_id,
bugHash=report.bug_id,
Expand All @@ -2023,6 +2068,7 @@ def getRunResults(self, run_ids, limit, offset, sort_types,
report.fixed_at else None,
bugPathLength=report.path_length,
details=report_details.get(report.id),
blameInfo=blame_info,
analyzerName=report.analyzer_name,
annotations=annotations))

Expand Down
2 changes: 1 addition & 1 deletion web/server/vue-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@mdi/font": "^6.5.95",
"chart.js": "^2.9.4",
"chartjs-plugin-datalabels": "^0.7.0",
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz",
"codechecker-api": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz",
"codemirror": "^5.65.0",
"date-fns": "^2.28.0",
"js-cookie": "^3.0.1",
Expand Down

0 comments on commit 76e443e

Please sign in to comment.