diff --git a/web/api/README.md b/web/api/README.md index 74c9e78359..05230eaf56 100644 --- a/web/api/README.md +++ b/web/api/README.md @@ -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) diff --git a/web/api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz b/web/api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz deleted file mode 100644 index 416c878d13..0000000000 Binary files a/web/api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz and /dev/null differ diff --git a/web/api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz b/web/api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz new file mode 100644 index 0000000000..dc73782abc Binary files /dev/null and b/web/api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz differ diff --git a/web/api/js/codechecker-api-node/package.json b/web/api/js/codechecker-api-node/package.json index e876b60239..6bdf935418 100644 --- a/web/api/js/codechecker-api-node/package.json +++ b/web/api/js/codechecker-api-node/package.json @@ -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", diff --git a/web/api/py/codechecker_api/dist/codechecker_api.tar.gz b/web/api/py/codechecker_api/dist/codechecker_api.tar.gz index fe714e89f6..16b3fb10ee 100644 Binary files a/web/api/py/codechecker_api/dist/codechecker_api.tar.gz and b/web/api/py/codechecker_api/dist/codechecker_api.tar.gz differ diff --git a/web/api/py/codechecker_api/setup.py b/web/api/py/codechecker_api/setup.py index f5627f0eed..806b546b36 100644 --- a/web/api/py/codechecker_api/setup.py +++ b/web/api/py/codechecker_api/setup.py @@ -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', diff --git a/web/api/py/codechecker_api_shared/dist/codechecker_api_shared.tar.gz b/web/api/py/codechecker_api_shared/dist/codechecker_api_shared.tar.gz index 098e124d0a..774411fe34 100644 Binary files a/web/api/py/codechecker_api_shared/dist/codechecker_api_shared.tar.gz and b/web/api/py/codechecker_api_shared/dist/codechecker_api_shared.tar.gz differ diff --git a/web/api/py/codechecker_api_shared/setup.py b/web/api/py/codechecker_api_shared/setup.py index f16016b4e3..747e74be03 100644 --- a/web/api/py/codechecker_api_shared/setup.py +++ b/web/api/py/codechecker_api_shared/setup.py @@ -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', diff --git a/web/api/report_server.thrift b/web/api/report_server.thrift index e37dcf67d6..7b81d4a063 100644 --- a/web/api/report_server.thrift +++ b/web/api/report_server.thrift @@ -325,6 +325,7 @@ struct ReportData { // 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 annotations, + 19: optional BlameInfo blameInfo, // Contains the git blame information of the report if it exists. } typedef list ReportDataList diff --git a/web/codechecker_web/shared/version.py b/web/codechecker_web/shared/version.py index 52c8d760d9..c045815196 100644 --- a/web/codechecker_web/shared/version.py +++ b/web/codechecker_web/shared/version.py @@ -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 diff --git a/web/server/codechecker_server/api/report_server.py b/web/server/codechecker_server/api/report_server.py index 0ba5189291..452541b250 100644 --- a/web/server/codechecker_server/api/report_server.py +++ b/web/server/codechecker_server/api/report_server.py @@ -1901,9 +1901,15 @@ def getRunResults(self, run_ids, limit, offset, sort_types, # Get report details if it is required. report_details = {} - if get_details: - report_ids = [r[0].id for r in query_result] + blame_infos = {} + if get_details and len(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] @@ -1919,6 +1925,21 @@ def getRunResults(self, run_ids, limit, offset, sort_types, report.review_status_date, report.review_status_is_in_source) + blame_info = blame_infos.get(report.id) + if blame_info and blame_info.commits and blame_info.blame: + 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, @@ -1937,6 +1958,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 @@ -1986,9 +2008,15 @@ def getRunResults(self, run_ids, limit, offset, sort_types, # Get report details if it is required. report_details = {} - if get_details: - report_ids = [r[0].id for r in query_result] + blame_infos = {} + if get_details and len(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] @@ -2004,6 +2032,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 and blame_info.commits and blame_info.blame: + 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, @@ -2023,6 +2067,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)) diff --git a/web/server/vue-cli/package-lock.json b/web/server/vue-cli/package-lock.json index e6ee7a3154..8d51e6e9a8 100644 --- a/web/server/vue-cli/package-lock.json +++ b/web/server/vue-cli/package-lock.json @@ -11,7 +11,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", @@ -4834,9 +4834,9 @@ } }, "node_modules/codechecker-api": { - "version": "6.53.0", - "resolved": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz", - "integrity": "sha512-156RuFb5HCRhvxVbvJDbNKUsjxuga4DdjaiC0FbIORhQlIt/Wm1RtBxx9mPVp+YTJCpWh3MxFTrvxH8JlIb6zA==", + "version": "6.54.0", + "resolved": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz", + "integrity": "sha512-8im0d/668cs4nJNvO+DS9K2eRA25+ipJHU9SU9ZfPzB8uUEPW9GAfSimYpqG7MVTg8q4RQlss+NtjWUjl8LzvA==", "license": "SEE LICENSE IN LICENSE", "dependencies": { "thrift": "0.13.0-hotfix.1" @@ -19756,8 +19756,8 @@ "dev": true }, "codechecker-api": { - "version": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.53.0.tgz", - "integrity": "sha512-156RuFb5HCRhvxVbvJDbNKUsjxuga4DdjaiC0FbIORhQlIt/Wm1RtBxx9mPVp+YTJCpWh3MxFTrvxH8JlIb6zA==", + "version": "file:../../api/js/codechecker-api-node/dist/codechecker-api-6.54.0.tgz", + "integrity": "sha512-8im0d/668cs4nJNvO+DS9K2eRA25+ipJHU9SU9ZfPzB8uUEPW9GAfSimYpqG7MVTg8q4RQlss+NtjWUjl8LzvA==", "requires": { "thrift": "0.13.0-hotfix.1" } diff --git a/web/server/vue-cli/package.json b/web/server/vue-cli/package.json index 5f4b729ef6..be33b5db19 100644 --- a/web/server/vue-cli/package.json +++ b/web/server/vue-cli/package.json @@ -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", diff --git a/web/tests/functional/report_viewer_api/test_get_run_results.py b/web/tests/functional/report_viewer_api/test_get_run_results.py index 79b5f7feda..50fd85a318 100644 --- a/web/tests/functional/report_viewer_api/test_get_run_results.py +++ b/web/tests/functional/report_viewer_api/test_get_run_results.py @@ -447,3 +447,20 @@ def test_get_checker_labels(self): self.assertEqual(len(checker_labels), 2) self.assertEqual(set(checker_labels[0]), div_zero_labels) self.assertEqual(set(checker_labels[1]), set()) + + def test_report_blame_info(self): + """ + Get run results and check that blame info exists + when get_details is set. + """ + runid = self._runid + simple_filter = ReportFilter() + run_results = self._cc_client.getRunResults([runid], + 100, + 0, + None, + simple_filter, + None, + True) + + self.assertTrue(any(res.blameInfo for res in run_results))