From 8648884813bc78112da632c951645b72cfa5702a Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 16:57:00 +0100 Subject: [PATCH 01/16] Adds server version to handle API incompatibilities The following Endpoints are removed since v6.3 - /resources - /timemachine => the widget for sonar statics of all projects and the history chart are not supported with the updated sonar API (6.7 LTS) --- src/service.js | 179 ++++++++++++++++++++++++++++++------------------- src/sonar.js | 22 ++++-- 2 files changed, 128 insertions(+), 73 deletions(-) diff --git a/src/service.js b/src/service.js index 9d6cff8..4e75d14 100644 --- a/src/service.js +++ b/src/service.js @@ -4,7 +4,39 @@ sonarADFWidget. factory('sonarApi', sonarApi); //function factory sonar -function sonarApi($http, $q) { +function sonarApi($http, $q, sonarEndpoint) { + + // make a compatibility check set requiredVersion to the last version the api is supported with + // eg. Endpoint is removed in v6.1 than set requiredServerVersion to 6.0 + function isAPISupported(requiredServerVersion){ + getServerVersion(sonarEndpoint.url).then(function(serverVersion){ + return checkVersionCompatibilityLowerThan(requiredServerVersion, String(serverVersion)); + }); + } + + function checkVersionCompatibilityLowerThan(requiredVersion, actualVersion){ + var ver1 = requiredVersion.split('.'); + var ver2 = actualVersion.split('.'); + if (ver1[0] < ver2[0]){ + return false; + }else if (ver1[0] === ver2[0] && ver1[1] <= ver2[1]){ + return false + } + return true; + } + + function getServerVersion(sonarUrl){ + var serverVersionReqUrl = sonarUrl + "/api/server/version"; + return $http({ + method: 'GET', + url: serverVersionReqUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function(response) { + return response.data; + }); + } function createApiUrlProjects(sonarUrl) { return sonarUrl + '/api/projects/index?format=json'; @@ -23,7 +55,7 @@ function sonarApi($http, $q) { } function createApiUrlQuality(sonarUrl, projectname) { - return sonarUrl + '/api/resources?resource=' + projectname + '&metrics=coverage,blocker_violations,quality_gate_details'; + return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; } function getProjectTime(projectBeginn, projectEnd) { @@ -112,7 +144,7 @@ function sonarApi($http, $q) { var apiUrlProject2 = createApiUrlMetrics(sonarUrl, projectname2); var api1 = $http.get(apiUrlProject1); var api2 = $http.get(apiUrlProject2); - var responsesArray = $q.all([api1, api2]) + return $q.all([api1, api2]) .then(function(response) { var projectLeft = response[0]; var projectRight = response[1]; @@ -120,70 +152,72 @@ function sonarApi($http, $q) { 'projectLeft': projectLeft, 'projectRight': projectRight }; - return projectMetrics; + return {resp: projectMetrics,projectLeft: projectname1, projectRight: projectname2}; }); - - return responsesArray; } function getChartData(sonarUrl, projectname, metrics, timespan) { - + var requiredAPIVersion = "6.2"; var apiUrl; var fromDateTime; var toDateTime; var metricsString = createMetricsString(metrics); - if (timespan.type === 'dynamic') { - var today = new Date(); - switch(timespan.dynamic) { - case 'week': - fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - break; - case 'month': - fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); - break; - case 'year': - fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); - break; + if(isAPISupported(requiredAPIVersion)){ + if (timespan.type === 'dynamic') { + var today = new Date(); + switch(timespan.dynamic) { + case 'week': + fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); + break; + case 'month': + fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); + break; + case 'year': + fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); + break; + } + toDateTime = today; + } else if (timespan.type === 'static') { + fromDateTime = timespan.fromDateTime; + toDateTime = timespan.toDateTime; } - toDateTime = today; - } else if (timespan.type === 'static') { - fromDateTime = timespan.fromDateTime; - toDateTime = timespan.toDateTime; - } - if ((fromDateTime && toDateTime)) { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; - } else { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' + if ((fromDateTime && toDateTime)) { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; } - }).then(function(response) { - var metricsArray = []; - var responseData = response.data[0]; - var cols = responseData.cols; - var cells = responseData.cells; - for (var x = 0; x < cols.length; x++) { - var values = []; - var dates = []; - for (var y = 0; y < cells.length; y++) { - dates[y] = cells[y].d.split("T")[0]; - values[y] = cells[y].v[x]; - + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' } - var metricsObj = { - 'metric': cols[x].metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); - } - return metricsArray; - }); + }).then(function(response) { + var metricsArray = []; + var responseData = response.data[0]; + var cols = responseData.cols; + var cells = responseData.cells; + for (var x = 0; x < cols.length; x++) { + var values = []; + var dates = []; + for (var y = 0; y < cells.length; y++) { + dates[y] = cells[y].d.split("T")[0]; + values[y] = cells[y].v[x]; + + } + var metricsObj = { + 'metric': cols[x].metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + } + return metricsArray; + }); + }else{ + return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + } } @@ -221,19 +255,26 @@ function sonarApi($http, $q) { }); } + function getAllProjectsStatistics(sonarUrl){ - var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + var requiredAPIVersion = '6.2'; - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function(response) { - var projects = response.data; - return generateArray(projects); - }); + if(isAPISupported(requiredAPIVersion)) { + var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var projects = response.data; + return generateArray(projects); + }); + }else{ + return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + } } function getAllMyIssues(sonarUrl){ @@ -252,7 +293,6 @@ function sonarApi($http, $q) { function getProjectquality(sonarUrl, project){ var apiUrl = createApiUrlQuality(sonarUrl, project); - return $http({ method: 'GET', url: apiUrl, @@ -260,7 +300,7 @@ function sonarApi($http, $q) { 'Accept': 'application/json' } }).then(function(response) { - return response.data[0]; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarUrl}; }); } @@ -271,7 +311,8 @@ function sonarApi($http, $q) { getMetrics: getMetrics, getProjectTime: getProjectTime, getAllMyIssues: getAllMyIssues, - getProjectquality: getProjectquality + getProjectquality: getProjectquality, + getServerVersion: getServerVersion }; } diff --git a/src/sonar.js b/src/sonar.js index b83015e..9b34bb0 100644 --- a/src/sonar.js +++ b/src/sonar.js @@ -2,8 +2,9 @@ //app initialisation with dependencies var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker','angular-svg-round-progressbar']) .constant("sonarEndpoint", { - "url": "https://sonarcloud.io" -}).constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", + "url": "https://192.168.56.2/sonar" +}) + .constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", "public_documented_api_density": "Public documented API density","duplicated_lines_density": "Duplicated Lines (%)", "sqale_index":"SQALE index", "coverage": "Coverage (%)", "tests": "Tests" }) .config(function(dashboardProvider) { @@ -97,6 +98,19 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. templateUrl: '{widgetsPath}/sonar/src/project-progress/edit.html' } }) + .widget('version', { + title: 'Sonar Server Version', + description: 'Displays the current sonar server version', + templateUrl: '{widgetsPath}/sonar/src/version/view.html', + resolve: { + data: function(sonarApi, sonarEndpoint) { + return sonarApi.getServerVersion(sonarEndpoint.url); + } + }, + category: 'SonarQube', + controller: 'version', + controllerAs: 'vm' + }) .widget('sonar-my-issues', { title: 'Sonar My Issues', description: 'Displays all issues of yourself', @@ -120,8 +134,8 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. } }) .widget('sonar-projectquality', { - title: 'Sonar Projectquality of a Project', - description: 'Displays Status of the Quality Gate, Code Coverage and Blocker Issues', + title: 'Sonar Project Quality', + description: 'Displays metrics of a specific project', templateUrl: '{widgetsPath}/sonar/src/projectquality/view.html', resolve: { data: function(sonarApi, config, sonarEndpoint) { From 9d5317713bc3495f5a5fff56799317693db288dc Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:01:38 +0100 Subject: [PATCH 02/16] refactors the project quality widget switches to a supported API endpoint updates UI and metrics --- src/projectquality/quality.controller.js | 23 +++++--- src/projectquality/view.html | 74 +++++++++++++----------- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/projectquality/quality.controller.js b/src/projectquality/quality.controller.js index 0db924b..9d4a587 100644 --- a/src/projectquality/quality.controller.js +++ b/src/projectquality/quality.controller.js @@ -4,15 +4,22 @@ sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.name = data.name; + vm.project = data.project; + vm.url = data.url; - angular.forEach(data.msr, function (metric) { - if (metric.key === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order - vm.coverage = metric.frmt_val; - else if (metric.key === "blocker_violations") - vm.blocker = metric.frmt_val; - else if (metric.key === "quality_gate_details") { - vm.qualityGateStatus = metric.data.split('"')[3]; //structure of quality_gate_details: "level":"OK",... + angular.forEach(data.quality_index, function (metric) { + if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order + vm.coverage = metric.value; + else if (metric.metric === "blocker_violations") + vm.blocker = metric.value; + else if (metric.metric === "alert_status") { + vm.qualityGateStatus = metric.value; + } + else if (metric.metric === "sqale_index") { + vm.technicalDept = metric.value; + } + else if (metric.metric === "vulnerabilities") { + vm.vulnerabilities = metric.value; } }); } diff --git a/src/projectquality/view.html b/src/projectquality/view.html index 3cc9210..4a4b614 100644 --- a/src/projectquality/view.html +++ b/src/projectquality/view.html @@ -1,29 +1,23 @@ -
+
Please configure the widget
-
+
-
- -

Passed

-

Quality Gate

+
+ +

OK

+
Quality Gate
-
- -

Failed

-

Quality Gate

+
+

Failed

+
Quality Gate
-
- -

Warning

-

Quality Gate

+
+

Warning

+
Quality Gate
-
- -

unknown

-

Quality Gate

+
+

unknown

+
Quality Gate
-
+ +
+ +

{{vm.vulnerabilities}}

+
Vulnerabilities
+
+ + +

{{vm.coverage||"unknown"}}

-

Code Coverage

+
Code Coverage
-
+

{{vm.blocker||"unknown"}}

-

Blocker Issues

+
Blocker Issues
- +
+ +

{{vm.technicalDept+" days" ||"unknown"}}

+
Technical Dept
+
+ about metrics
From 9b3b92d48e068b63be4b49eb2598058cf82bf981 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:07:22 +0100 Subject: [PATCH 03/16] fixes order bug with project compare widget The displayed metrics of the left and right side sometimes differ, because the order after the request is not given. --- src/compare/compare.controller.js | 25 +++++++++++++++++-------- src/compare/view.html | 17 +++++++++-------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/compare/compare.controller.js b/src/compare/compare.controller.js index 2f0a20e..bec9783 100644 --- a/src/compare/compare.controller.js +++ b/src/compare/compare.controller.js @@ -2,13 +2,22 @@ sonarADFWidget.controller('compare', compare); -function compare(data,METRIC_NAMES) { +function compare(data) { var vm = this; - - vm.METRIC_NAMES = METRIC_NAMES; - vm.projectLeft = data.projectLeft; - vm.projectRight = data.projectRight; - + vm.projectLeft = data.projectLeft.split(':')[1]; + vm.projectRight = data.projectRight.split(':')[1]; + var projectLeftMetrics = data.resp.projectLeft.data.component.measures; + var projectRightMetrics = data.resp.projectRight.data.component.measures; + var compareTable = []; + angular.forEach(projectLeftMetrics, function (metricLeft) { + angular.forEach(projectRightMetrics, function (metricRight) { + if (metricRight.metric === metricLeft.metric) { + compareTable.push({metricName: metricLeft.metric, + projectValLeft: metricLeft.value, projectValRight: metricRight.value}); + } + }); + }); + vm.compareTable = compareTable; } sonarADFWidget.controller('editController', editController); @@ -28,11 +37,11 @@ function editController($scope, $http, sonarApi, sonarEndpoint) { data.forEach(function(project) { var proj = { name: project.k - } + }; vm.projects.push(proj); }); }); - } + }; $scope.updateProjects(); } diff --git a/src/compare/view.html b/src/compare/view.html index 8ae2b16..ccfa198 100644 --- a/src/compare/view.html +++ b/src/compare/view.html @@ -1,18 +1,19 @@ -
+
Please configure the widget
-
+
+ - - + + - - - - + + + +
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}{{vm.projectLeft}}{{vm.projectRight}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
From 6e927c6ac0915e3fd39186a310081f145acf01c7 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:08:26 +0100 Subject: [PATCH 04/16] Adds simple widget to display the connected server version --- src/version/version.controller.js | 8 ++++++++ src/version/view.html | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 src/version/version.controller.js create mode 100644 src/version/view.html diff --git a/src/version/version.controller.js b/src/version/version.controller.js new file mode 100644 index 0000000..6da8bf1 --- /dev/null +++ b/src/version/version.controller.js @@ -0,0 +1,8 @@ +'use strict'; + +sonarADFWidget.controller('version', version); + +function version(data) { + var vm = this; + vm.version = data; +} diff --git a/src/version/view.html b/src/version/view.html new file mode 100644 index 0000000..8e7936a --- /dev/null +++ b/src/version/view.html @@ -0,0 +1,4 @@ + +
+

{{vm.version}}

+
From 1d4a22ccf335e09e5822bb9572c610a91e5e40e9 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:11:12 +0100 Subject: [PATCH 05/16] updates the charts widget to display incompatibilities with the API ver. --- src/chart/lineChart.controller.js | 8 +++++--- src/chart/view.html | 11 +++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/chart/lineChart.controller.js b/src/chart/lineChart.controller.js index cdc8e3e..8d8731e 100644 --- a/src/chart/lineChart.controller.js +++ b/src/chart/lineChart.controller.js @@ -6,10 +6,12 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - if (data) { - vm.chart = createChart(); - } + if (!data.support){ + vm.support = data; + }else{ + vm.chart = createChart(); + } function createChart() { var options = { legend:{ diff --git a/src/chart/view.html b/src/chart/view.html index 8d34a66..a490321 100644 --- a/src/chart/view.html +++ b/src/chart/view.html @@ -1,8 +1,15 @@ -
+
Please configure the widget
+ +
+ {{vm.support.message}} +
+
-
+ + From 7ca5a23cca8e38fbd598d730175eaf55df6130d8 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:11:30 +0100 Subject: [PATCH 06/16] updates the global widget to display incompatibilities with the API ver. --- src/allProjects/stats.controller.js | 7 ++++++- src/allProjects/view.html | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/allProjects/stats.controller.js b/src/allProjects/stats.controller.js index a3f130b..ef4683c 100644 --- a/src/allProjects/stats.controller.js +++ b/src/allProjects/stats.controller.js @@ -5,5 +5,10 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - vm.data = data; + if (!data.support){ + vm.support = data; + }else{ + vm.data = data; + } + } diff --git a/src/allProjects/view.html b/src/allProjects/view.html index ba6b39c..42e61fa 100644 --- a/src/allProjects/view.html +++ b/src/allProjects/view.html @@ -28,15 +28,19 @@
-
+ +

{{(vm.data.linesOfCode | number)||0}}

Lines of code

-
+

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

+
+ {{vm.support.message}} +
From 14289fb301ef5fd7d355bc59596e361066fe524f Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:15:18 +0100 Subject: [PATCH 07/16] update dist --- dist/adf-widget-sonar.js | 25 +++++++++++++------------ dist/adf-widget-sonar.min.js | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index 95452ca..e4ba5e9 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -3,7 +3,7 @@ //app initialisation with dependencies var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker','angular-svg-round-progressbar']) .constant("sonarEndpoint", { - "url": "https://sonarqube.com" + "url": "https://sonarcloud.io" }).constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", "public_documented_api_density": "Public documented API density","duplicated_lines_density": "Duplicated Lines (%)", "sqale_index":"SQALE index", "coverage": "Coverage (%)", "tests": "Tests" }) @@ -99,7 +99,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. } }) .widget('sonar-my-issues', { - title: 'Sonar: My Issues', + title: 'Sonar My Issues', description: 'Displays all issues of yourself', templateUrl: '{widgetsPath}/sonar/src/issues/view.html', resolve: { @@ -121,7 +121,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. } }) .widget('sonar-projectquality', { - title: 'Sonar: Projectquality of a Project', + title: 'Sonar Projectquality of a Project', description: 'Displays Status of the Quality Gate, Code Coverage and Blocker Issues', templateUrl: '{widgetsPath}/sonar/src/projectquality/view.html', resolve: { @@ -145,18 +145,18 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. }]); -angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

"); -$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); +angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

"); +$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); $templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); -$templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type | lowercase}} {{issue.severity | lowercase}}{{issue.status | lowercase}} {{issue.effort}} effort {{issue.tag}}
"); +$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/view.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); -$templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

Passed

Quality Gate

Error

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

");}]); +$templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); +$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

Passed

Quality Gate

Failed

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

");}]); sonarADFWidget.controller('qualityCtrl', qualityCtrl); @@ -382,6 +382,7 @@ function editController($scope, sonarApi, sonarEndpoint) { if (!$scope.config.timespan) { $scope.config.timespan = {}; } + vm.url = sonarEndpoint.url; // convert strings to date objects if ($scope.config.timespan.fromDateTime) { @@ -505,7 +506,7 @@ function sonarApi($http, $q) { } function createApiUrlAllMyIssues(sonarUrl) { - return sonarUrl + '/api/issues/search?assignees=pczora';//--> nur zum Testen, eigentlich ist es __me__! + return sonarUrl + '/api/issues/search?assignees=__me__'; } function createApiUrlMetrics(sonarUrl, projectname) { diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index c909c02..d479de8 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.name=e.name,angular.forEach(e.msr,function(e){"coverage"===e.key?t.coverage=e.frmt_val:"blocker_violations"===e.key?t.blocker=e.frmt_val:"quality_gate_details"===e.key&&(t.qualityGateStatus=e.data.split('"')[3])})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function r(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function l(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function p(o,n,r){var s=a(o,n),i=a(o,r),c=e.get(s),l=e.get(i),p=t.all([c,l]).then(function(e){var t=e[0],o=e[1],n={projectLeft:t,projectRight:o};return n});return p}function d(t,o,n,r){var a,s,i,c=l(n);if("dynamic"===r.type){var p=new Date;switch(r.dynamic){case"week":s=new Date(p.getTime()-6048e5);break;case"month":s=new Date(p.getFullYear(),p.getMonth()-1,p.getDay());break;case"year":s=new Date(p.getFullYear()-1,p.getMonth(),p.getDay())}i=p}else"static"===r.type&&(s=r.fromDateTime,i=r.toDateTime);return a=s&&i?t+"/api/timemachine?resource="+o+"&metrics="+c+"&fromDateTime="+s+"&toDateTime="+i:t+"/api/timemachine?resource="+o+"&metrics="+c,e({method:"GET",url:a,headers:{Accept:"application/json"}}).then(function(e){for(var t=[],o=e.data[0],n=o.cols,r=o.cells,a=0;a
"),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html","
"),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type | lowercase}} {{issue.severity | lowercase}}{{issue.status | lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

Passed

Quality Gate

Error

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

')}]),p.controller("qualityCtrl",o),o.$inject=["data"],p.controller("progress",n),n.$inject=["data","roundProgressConfig"],p.controller("sonarIssueCtrl",r),r.$inject=["data","config"],p.controller("compare",a),a.$inject=["data","METRIC_NAMES"],p.controller("editController",s),p.controller("sonarLineChart",i),i.$inject=["data","METRIC_NAMES"],p.controller("editController",s),s.$inject=["$scope","sonarApi","sonarEndpoint"],p.controller("sonarStatsCtrl",c),c.$inject=["data"],p.factory("sonarApi",l),l.$inject=["$http","$q"]}(window); \ No newline at end of file +!function(e,t){"use strict";function o(e){var t=this;t.name=e.name,angular.forEach(e.msr,function(e){"coverage"===e.key?t.coverage=e.frmt_val:"blocker_violations"===e.key?t.blocker=e.frmt_val:"quality_gate_details"===e.key&&(t.qualityGateStatus=e.data.split('"')[3])})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function r(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function c(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function p(o,n,r){var s=a(o,n),i=a(o,r),l=e.get(s),c=e.get(i),p=t.all([l,c]).then(function(e){var t=e[0],o=e[1],n={projectLeft:t,projectRight:o};return n});return p}function d(t,o,n,r){var a,s,i,l=c(n);if("dynamic"===r.type){var p=new Date;switch(r.dynamic){case"week":s=new Date(p.getTime()-6048e5);break;case"month":s=new Date(p.getFullYear(),p.getMonth()-1,p.getDay());break;case"year":s=new Date(p.getFullYear()-1,p.getMonth(),p.getDay())}i=p}else"static"===r.type&&(s=r.fromDateTime,i=r.toDateTime);return a=s&&i?t+"/api/timemachine?resource="+o+"&metrics="+l+"&fromDateTime="+s+"&toDateTime="+i:t+"/api/timemachine?resource="+o+"&metrics="+l,e({method:"GET",url:a,headers:{Accept:"application/json"}}).then(function(e){for(var t=[],o=e.data[0],n=o.cols,r=o.cells,a=0;a
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

Passed

Quality Gate

Failed

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

')}]),p.controller("qualityCtrl",o),o.$inject=["data"],p.controller("progress",n),n.$inject=["data","roundProgressConfig"],p.controller("sonarIssueCtrl",r),r.$inject=["data","config"],p.controller("compare",a),a.$inject=["data","METRIC_NAMES"],p.controller("editController",s),p.controller("sonarLineChart",i),i.$inject=["data","METRIC_NAMES"],p.controller("editController",s),s.$inject=["$scope","sonarApi","sonarEndpoint"],p.controller("sonarStatsCtrl",l),l.$inject=["data"],p.factory("sonarApi",c),c.$inject=["$http","$q"]}(window); \ No newline at end of file From 6de14cad743e6bc8486717ac62f365152b8d13ec Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Fri, 8 Mar 2019 17:52:37 +0100 Subject: [PATCH 08/16] updates dist --- dist/adf-widget-sonar.js | 289 +++++++++++++++++++++++------------ dist/adf-widget-sonar.min.js | 2 +- 2 files changed, 190 insertions(+), 101 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index e4ba5e9..501b0d7 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -3,8 +3,9 @@ //app initialisation with dependencies var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker','angular-svg-round-progressbar']) .constant("sonarEndpoint", { - "url": "https://sonarcloud.io" -}).constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", + "url": "https://192.168.56.2/sonar" +}) + .constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", "public_documented_api_density": "Public documented API density","duplicated_lines_density": "Duplicated Lines (%)", "sqale_index":"SQALE index", "coverage": "Coverage (%)", "tests": "Tests" }) .config(["dashboardProvider", function(dashboardProvider) { @@ -98,6 +99,19 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. templateUrl: '{widgetsPath}/sonar/src/project-progress/edit.html' } }) + .widget('version', { + title: 'Sonar Server Version', + description: 'Displays the current sonar server version', + templateUrl: '{widgetsPath}/sonar/src/version/view.html', + resolve: { + data: ["sonarApi", "sonarEndpoint", function(sonarApi, sonarEndpoint) { + return sonarApi.getServerVersion(sonarEndpoint.url); + }] + }, + category: 'SonarQube', + controller: 'version', + controllerAs: 'vm' + }) .widget('sonar-my-issues', { title: 'Sonar My Issues', description: 'Displays all issues of yourself', @@ -121,8 +135,8 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. } }) .widget('sonar-projectquality', { - title: 'Sonar Projectquality of a Project', - description: 'Displays Status of the Quality Gate, Code Coverage and Blocker Issues', + title: 'Sonar Project Quality', + description: 'Displays metrics of a specific project', templateUrl: '{widgetsPath}/sonar/src/projectquality/view.html', resolve: { data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { @@ -146,32 +160,50 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. }]); angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

"); +$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); $templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); +$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
{{vm.support.message}}
"); $templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
"); +$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); $templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/view.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); $templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

Passed

Quality Gate

Failed

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

");}]); +$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"unknown\"}}

Technical Dept
about metrics
"); +$templateCache.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

");}]); + + +sonarADFWidget.controller('version', version); + +function version(data) { + var vm = this; + vm.version = data; +} +version.$inject = ["data"]; + sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.name = data.name; - - angular.forEach(data.msr, function (metric) { - if (metric.key === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order - vm.coverage = metric.frmt_val; - else if (metric.key === "blocker_violations") - vm.blocker = metric.frmt_val; - else if (metric.key === "quality_gate_details") { - vm.qualityGateStatus = metric.data.split('"')[3]; //structure of quality_gate_details: "level":"OK",... + vm.project = data.project; + vm.url = data.url; + + angular.forEach(data.quality_index, function (metric) { + if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order + vm.coverage = metric.value; + else if (metric.metric === "blocker_violations") + vm.blocker = metric.value; + else if (metric.metric === "alert_status") { + vm.qualityGateStatus = metric.value; + } + else if (metric.metric === "sqale_index") { + vm.technicalDept = metric.value; + } + else if (metric.metric === "vulnerabilities") { + vm.vulnerabilities = metric.value; } }); } @@ -299,15 +331,24 @@ sonarIssueCtrl.$inject = ["data", "config"]; sonarADFWidget.controller('compare', compare); -function compare(data,METRIC_NAMES) { +function compare(data) { var vm = this; - - vm.METRIC_NAMES = METRIC_NAMES; - vm.projectLeft = data.projectLeft; - vm.projectRight = data.projectRight; - + vm.projectLeft = data.projectLeft.split(':')[1]; + vm.projectRight = data.projectRight.split(':')[1]; + var projectLeftMetrics = data.resp.projectLeft.data.component.measures; + var projectRightMetrics = data.resp.projectRight.data.component.measures; + var compareTable = []; + angular.forEach(projectLeftMetrics, function (metricLeft) { + angular.forEach(projectRightMetrics, function (metricRight) { + if (metricRight.metric === metricLeft.metric) { + compareTable.push({metricName: metricLeft.metric, + projectValLeft: metricLeft.value, projectValRight: metricRight.value}); + } + }); + }); + vm.compareTable = compareTable; } -compare.$inject = ["data", "METRIC_NAMES"]; +compare.$inject = ["data"]; sonarADFWidget.controller('editController', editController); @@ -326,11 +367,11 @@ function editController($scope, $http, sonarApi, sonarEndpoint) { data.forEach(function(project) { var proj = { name: project.k - } + }; vm.projects.push(proj); }); }); - } + }; $scope.updateProjects(); } @@ -343,10 +384,12 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - if (data) { - vm.chart = createChart(); - } + if (!data.support){ + vm.support = data; + }else{ + vm.chart = createChart(); + } function createChart() { var options = { legend:{ @@ -485,7 +528,12 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - vm.data = data; + if (!data.support){ + vm.support = data; + }else{ + vm.data = data; + } + } sonarStatsCtrl.$inject = ["data"]; @@ -495,7 +543,39 @@ sonarADFWidget. factory('sonarApi', sonarApi); //function factory sonar -function sonarApi($http, $q) { +function sonarApi($http, $q, sonarEndpoint) { + + // make a compatibility check set requiredVersion to the last version the api is supported with + // eg. Endpoint is removed in v6.1 than set requiredServerVersion to 6.0 + function isAPISupported(requiredServerVersion){ + getServerVersion(sonarEndpoint.url).then(function(serverVersion){ + return checkVersionCompatibilityLowerThan(requiredServerVersion, String(serverVersion)); + }); + } + + function checkVersionCompatibilityLowerThan(requiredVersion, actualVersion){ + var ver1 = requiredVersion.split('.'); + var ver2 = actualVersion.split('.'); + if (ver1[0] < ver2[0]){ + return false; + }else if (ver1[0] === ver2[0] && ver1[1] <= ver2[1]){ + return false + } + return true; + } + + function getServerVersion(sonarUrl){ + var serverVersionReqUrl = sonarUrl + "/api/server/version"; + return $http({ + method: 'GET', + url: serverVersionReqUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function(response) { + return response.data; + }); + } function createApiUrlProjects(sonarUrl) { return sonarUrl + '/api/projects/index?format=json'; @@ -514,7 +594,7 @@ function sonarApi($http, $q) { } function createApiUrlQuality(sonarUrl, projectname) { - return sonarUrl + '/api/resources?resource=' + projectname + '&metrics=coverage,blocker_violations,quality_gate_details'; + return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; } function getProjectTime(projectBeginn, projectEnd) { @@ -603,7 +683,7 @@ function sonarApi($http, $q) { var apiUrlProject2 = createApiUrlMetrics(sonarUrl, projectname2); var api1 = $http.get(apiUrlProject1); var api2 = $http.get(apiUrlProject2); - var responsesArray = $q.all([api1, api2]) + return $q.all([api1, api2]) .then(function(response) { var projectLeft = response[0]; var projectRight = response[1]; @@ -611,70 +691,72 @@ function sonarApi($http, $q) { 'projectLeft': projectLeft, 'projectRight': projectRight }; - return projectMetrics; + return {resp: projectMetrics,projectLeft: projectname1, projectRight: projectname2}; }); - - return responsesArray; } function getChartData(sonarUrl, projectname, metrics, timespan) { - + var requiredAPIVersion = "6.2"; var apiUrl; var fromDateTime; var toDateTime; var metricsString = createMetricsString(metrics); - if (timespan.type === 'dynamic') { - var today = new Date(); - switch(timespan.dynamic) { - case 'week': - fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - break; - case 'month': - fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); - break; - case 'year': - fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); - break; + if(isAPISupported(requiredAPIVersion)){ + if (timespan.type === 'dynamic') { + var today = new Date(); + switch(timespan.dynamic) { + case 'week': + fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); + break; + case 'month': + fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); + break; + case 'year': + fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); + break; + } + toDateTime = today; + } else if (timespan.type === 'static') { + fromDateTime = timespan.fromDateTime; + toDateTime = timespan.toDateTime; } - toDateTime = today; - } else if (timespan.type === 'static') { - fromDateTime = timespan.fromDateTime; - toDateTime = timespan.toDateTime; - } - if ((fromDateTime && toDateTime)) { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; - } else { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' + if ((fromDateTime && toDateTime)) { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; } - }).then(function(response) { - var metricsArray = []; - var responseData = response.data[0]; - var cols = responseData.cols; - var cells = responseData.cells; - for (var x = 0; x < cols.length; x++) { - var values = []; - var dates = []; - for (var y = 0; y < cells.length; y++) { - dates[y] = cells[y].d.split("T")[0]; - values[y] = cells[y].v[x]; - + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' } - var metricsObj = { - 'metric': cols[x].metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); - } - return metricsArray; - }); + }).then(function(response) { + var metricsArray = []; + var responseData = response.data[0]; + var cols = responseData.cols; + var cells = responseData.cells; + for (var x = 0; x < cols.length; x++) { + var values = []; + var dates = []; + for (var y = 0; y < cells.length; y++) { + dates[y] = cells[y].d.split("T")[0]; + values[y] = cells[y].v[x]; + + } + var metricsObj = { + 'metric': cols[x].metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + } + return metricsArray; + }); + }else{ + return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + } } @@ -712,19 +794,26 @@ function sonarApi($http, $q) { }); } + function getAllProjectsStatistics(sonarUrl){ - var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + var requiredAPIVersion = '6.2'; - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function(response) { - var projects = response.data; - return generateArray(projects); - }); + if(isAPISupported(requiredAPIVersion)) { + var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var projects = response.data; + return generateArray(projects); + }); + }else{ + return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + } } function getAllMyIssues(sonarUrl){ @@ -743,7 +832,6 @@ function sonarApi($http, $q) { function getProjectquality(sonarUrl, project){ var apiUrl = createApiUrlQuality(sonarUrl, project); - return $http({ method: 'GET', url: apiUrl, @@ -751,7 +839,7 @@ function sonarApi($http, $q) { 'Accept': 'application/json' } }).then(function(response) { - return response.data[0]; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarUrl}; }); } @@ -762,9 +850,10 @@ function sonarApi($http, $q) { getMetrics: getMetrics, getProjectTime: getProjectTime, getAllMyIssues: getAllMyIssues, - getProjectquality: getProjectquality + getProjectquality: getProjectquality, + getServerVersion: getServerVersion }; } -sonarApi.$inject = ["$http", "$q"]; +sonarApi.$inject = ["$http", "$q", "sonarEndpoint"]; })(window); \ No newline at end of file diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index d479de8..30edd22 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.name=e.name,angular.forEach(e.msr,function(e){"coverage"===e.key?t.coverage=e.frmt_val:"blocker_violations"===e.key?t.blocker=e.frmt_val:"quality_gate_details"===e.key&&(t.qualityGateStatus=e.data.split('"')[3])})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function r(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function c(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function p(o,n,r){var s=a(o,n),i=a(o,r),l=e.get(s),c=e.get(i),p=t.all([l,c]).then(function(e){var t=e[0],o=e[1],n={projectLeft:t,projectRight:o};return n});return p}function d(t,o,n,r){var a,s,i,l=c(n);if("dynamic"===r.type){var p=new Date;switch(r.dynamic){case"week":s=new Date(p.getTime()-6048e5);break;case"month":s=new Date(p.getFullYear(),p.getMonth()-1,p.getDay());break;case"year":s=new Date(p.getFullYear()-1,p.getMonth(),p.getDay())}i=p}else"static"===r.type&&(s=r.fromDateTime,i=r.toDateTime);return a=s&&i?t+"/api/timemachine?resource="+o+"&metrics="+l+"&fromDateTime="+s+"&toDateTime="+i:t+"/api/timemachine?resource="+o+"&metrics="+l,e({method:"GET",url:a,headers:{Accept:"application/json"}}).then(function(e){for(var t=[],o=e.data[0],n=o.cols,r=o.cells,a=0;a
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft.data.component.name}}{{vm.projectRight.data.component.name}}
{{vm.METRIC_NAMES[metric.metric]}}{{vm.projectLeft.data.component.measures[$index].value}}{{vm.projectRight.data.component.measures[$index].value}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

Passed

Quality Gate

Failed

Quality Gate

Warning

Quality Gate

unknown

Quality Gate

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

')}]),p.controller("qualityCtrl",o),o.$inject=["data"],p.controller("progress",n),n.$inject=["data","roundProgressConfig"],p.controller("sonarIssueCtrl",r),r.$inject=["data","config"],p.controller("compare",a),a.$inject=["data","METRIC_NAMES"],p.controller("editController",s),p.controller("sonarLineChart",i),i.$inject=["data","METRIC_NAMES"],p.controller("editController",s),s.$inject=["$scope","sonarApi","sonarEndpoint"],p.controller("sonarStatsCtrl",l),l.$inject=["data"],p.factory("sonarApi",c),c.$inject=["$http","$q"]}(window); \ No newline at end of file +!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project,t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function a(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function f(t,o,n,a){var s,i,l,c="6.2",p=m(n);if(r(c)){if("dynamic"===a.type){var u=new Date;switch(a.dynamic){case"week":i=new Date(u.getTime()-6048e5);break;case"month":i=new Date(u.getFullYear(),u.getMonth()-1,u.getDay());break;case"year":i=new Date(u.getFullYear()-1,u.getMonth(),u.getDay())}l=u}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+p+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+p,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=[],o=e.data[0],r=o.cols,n=o.cells,a=0;a
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("progress",n),n.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file From 7e0ad9cae9d501d1afdaef8cda6b18a28144781f Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 12:35:40 +0100 Subject: [PATCH 09/16] adds sonar 6.7 compatibility to charts widget --- src/chart/lineChart.controller.js | 8 ++-- src/chart/view.html | 6 +-- src/compare/view.html | 2 +- src/service.js | 77 ++++++++++++++++++++++--------- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/chart/lineChart.controller.js b/src/chart/lineChart.controller.js index 8d8731e..c2b0521 100644 --- a/src/chart/lineChart.controller.js +++ b/src/chart/lineChart.controller.js @@ -6,10 +6,11 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; + console.log(data); + console.log(METRIC_NAMES); - if (!data.support){ - vm.support = data; - }else{ + if (data){ + console.log("test123"); vm.chart = createChart(); } function createChart() { @@ -34,6 +35,7 @@ function sonarLineChart(data, METRIC_NAMES) { } chart.labels = data[0].dates; + console.log(chart); return chart; } diff --git a/src/chart/view.html b/src/chart/view.html index a490321..3cf0b0a 100644 --- a/src/chart/view.html +++ b/src/chart/view.html @@ -1,11 +1,7 @@ -
+
Please configure the widget
-
- {{vm.support.message}} -
-
diff --git a/src/compare/view.html b/src/compare/view.html index ccfa198..6b34d6b 100644 --- a/src/compare/view.html +++ b/src/compare/view.html @@ -1,7 +1,7 @@
Please configure the widget
-
+
diff --git a/src/service.js b/src/service.js index 4e75d14..20be1f0 100644 --- a/src/service.js +++ b/src/service.js @@ -162,26 +162,28 @@ function sonarApi($http, $q, sonarEndpoint) { var apiUrl; var fromDateTime; var toDateTime; + var metricsArray = []; var metricsString = createMetricsString(metrics); - if(isAPISupported(requiredAPIVersion)){ - if (timespan.type === 'dynamic') { - var today = new Date(); - switch(timespan.dynamic) { - case 'week': - fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - break; - case 'month': - fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); - break; - case 'year': - fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); - break; - } - toDateTime = today; - } else if (timespan.type === 'static') { - fromDateTime = timespan.fromDateTime; - toDateTime = timespan.toDateTime; + if (timespan.type === 'dynamic') { + var today = new Date(); + switch(timespan.dynamic) { + case 'week': + fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); + break; + case 'month': + fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); + break; + case 'year': + fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); + break; } + toDateTime = today; + } else if (timespan.type === 'static') { + fromDateTime = timespan.fromDateTime; + toDateTime = timespan.toDateTime; + } + // implementation for api version 6.2 or lower + if(isAPISupported(requiredAPIVersion)){ if ((fromDateTime && toDateTime)) { apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; } else { @@ -194,7 +196,6 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - var metricsArray = []; var responseData = response.data[0]; var cols = responseData.cols; var cells = responseData.cells; @@ -204,7 +205,6 @@ function sonarApi($http, $q, sonarEndpoint) { for (var y = 0; y < cells.length; y++) { dates[y] = cells[y].d.split("T")[0]; values[y] = cells[y].v[x]; - } var metricsObj = { 'metric': cols[x].metric, @@ -215,8 +215,41 @@ function sonarApi($http, $q, sonarEndpoint) { } return metricsArray; }); - }else{ - return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + // implementation vor api version 6.3 or higher + }else { + + if ((fromDateTime && toDateTime)) { + //convert for api request YEAR-MONTH-DAY + fromDateTime = fromDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + toDateTime = toDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; + }else{ + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + response.data.measures.forEach(function(element) { + var dates= []; + var values = []; + element.history.forEach(function(data){ + dates.push(data.date.split("T")[0]); + values.push(data.value); + }); + var metricsObj = { + 'metric': element.metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + }); + return metricsArray + }); } } From 7419d767edb0b7259933e24152048cf995ec0eb8 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 15:12:40 +0100 Subject: [PATCH 10/16] updates dist --- dist/adf-widget-sonar.js | 93 +++++++++++++++++++++++++----------- dist/adf-widget-sonar.min.js | 2 +- src/service.js | 4 +- 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index 501b0d7..216740a 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -162,9 +162,9 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); $templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
{{vm.support.message}}
"); +$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); $templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); +$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); $templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); @@ -384,10 +384,11 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; + console.log(data); + console.log(METRIC_NAMES); - if (!data.support){ - vm.support = data; - }else{ + if (data){ + console.log("test123"); vm.chart = createChart(); } function createChart() { @@ -412,6 +413,7 @@ function sonarLineChart(data, METRIC_NAMES) { } chart.labels = data[0].dates; + console.log(chart); return chart; } @@ -701,26 +703,28 @@ function sonarApi($http, $q, sonarEndpoint) { var apiUrl; var fromDateTime; var toDateTime; + var metricsArray = []; var metricsString = createMetricsString(metrics); - if(isAPISupported(requiredAPIVersion)){ - if (timespan.type === 'dynamic') { - var today = new Date(); - switch(timespan.dynamic) { - case 'week': - fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - break; - case 'month': - fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); - break; - case 'year': - fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); - break; - } - toDateTime = today; - } else if (timespan.type === 'static') { - fromDateTime = timespan.fromDateTime; - toDateTime = timespan.toDateTime; + if (timespan.type === 'dynamic') { + var today = new Date(); + switch(timespan.dynamic) { + case 'week': + fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); + break; + case 'month': + fromDateTime = new Date(today.getFullYear(), today.getMonth() - 1, today.getDay()); + break; + case 'year': + fromDateTime = new Date(today.getFullYear() - 1, today.getMonth(), today.getDay()); + break; } + toDateTime = today; + } else if (timespan.type === 'static') { + fromDateTime = timespan.fromDateTime; + toDateTime = timespan.toDateTime; + } + // implementation for api version 6.2 or lower + if(isAPISupported(requiredAPIVersion)){ if ((fromDateTime && toDateTime)) { apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; } else { @@ -733,7 +737,6 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - var metricsArray = []; var responseData = response.data[0]; var cols = responseData.cols; var cells = responseData.cells; @@ -743,7 +746,6 @@ function sonarApi($http, $q, sonarEndpoint) { for (var y = 0; y < cells.length; y++) { dates[y] = cells[y].d.split("T")[0]; values[y] = cells[y].v[x]; - } var metricsObj = { 'metric': cols[x].metric, @@ -754,8 +756,41 @@ function sonarApi($http, $q, sonarEndpoint) { } return metricsArray; }); - }else{ - return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + // implementation vor api version 6.3 or higher + }else { + + if ((fromDateTime && toDateTime)) { + //convert for api request YEAR-MONTH-DAY + fromDateTime = fromDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + toDateTime = toDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; + }else{ + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + response.data.measures.forEach(function(element) { + var dates= []; + var values = []; + element.history.forEach(function(data){ + dates.push(data.date.split("T")[0]); + values.push(data.value); + }); + var metricsObj = { + 'metric': element.metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + }); + return metricsArray + }); } } @@ -812,7 +847,7 @@ function sonarApi($http, $q, sonarEndpoint) { return generateArray(projects); }); }else{ - return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + return {support: false, message: "This widget is only compatible with sonar v"+requiredAPIVersion+ " or lower."} } } @@ -839,7 +874,7 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarUrl}; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint}; }); } diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index 30edd22..f9cd9a0 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project,t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function a(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function f(t,o,n,a){var s,i,l,c="6.2",p=m(n);if(r(c)){if("dynamic"===a.type){var u=new Date;switch(a.dynamic){case"week":i=new Date(u.getTime()-6048e5);break;case"month":i=new Date(u.getFullYear(),u.getMonth()-1,u.getDay());break;case"year":i=new Date(u.getFullYear()-1,u.getMonth(),u.getDay())}l=u}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+p+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+p,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=[],o=e.data[0],r=o.cols,n=o.cells,a=0;a
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("progress",n),n.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file +!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project,t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function a(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function f(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("progress",n),n.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file diff --git a/src/service.js b/src/service.js index 20be1f0..cc0576a 100644 --- a/src/service.js +++ b/src/service.js @@ -306,7 +306,7 @@ function sonarApi($http, $q, sonarEndpoint) { return generateArray(projects); }); }else{ - return {support: false, message: "this widget is only compatible with sonar v"+requiredAPIVersion+ " or lower"} + return {support: false, message: "This widget is only compatible with sonar v"+requiredAPIVersion+ " or lower."} } } @@ -333,7 +333,7 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarUrl}; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint}; }); } From a162b0cce56cf04dfe9185b1a22e9638fca5920b Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 15:58:29 +0100 Subject: [PATCH 11/16] fixes some small bugs --- dist/adf-widget-sonar.js | 9 +------- src/chart/lineChart.controller.js | 8 +------ src/compare/compare.controller.js | 29 +++++++++++++----------- src/projectquality/quality.controller.js | 3 ++- src/projectquality/view.html | 12 ++++++++-- src/service.js | 2 +- 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index 216740a..0301429 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -384,11 +384,8 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - console.log(data); - console.log(METRIC_NAMES); if (data){ - console.log("test123"); vm.chart = createChart(); } function createChart() { @@ -406,15 +403,11 @@ function sonarLineChart(data, METRIC_NAMES) { class: "chart-line", options: options }; - for (var i = 0; i < data.length; i++) { chart.series.push(METRIC_NAMES[data[i].metric]); chart.data.push(data[i].values); } - chart.labels = data[0].dates; - console.log(chart); - return chart; } } @@ -891,4 +884,4 @@ function sonarApi($http, $q, sonarEndpoint) { } sonarApi.$inject = ["$http", "$q", "sonarEndpoint"]; -})(window); \ No newline at end of file +})(window); diff --git a/src/chart/lineChart.controller.js b/src/chart/lineChart.controller.js index c2b0521..ccea609 100644 --- a/src/chart/lineChart.controller.js +++ b/src/chart/lineChart.controller.js @@ -6,11 +6,7 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - console.log(data); - console.log(METRIC_NAMES); - - if (data){ - console.log("test123"); + if (data != "Please Setup the Widget"){ vm.chart = createChart(); } function createChart() { @@ -35,8 +31,6 @@ function sonarLineChart(data, METRIC_NAMES) { } chart.labels = data[0].dates; - console.log(chart); - return chart; } } diff --git a/src/compare/compare.controller.js b/src/compare/compare.controller.js index bec9783..9d54f99 100644 --- a/src/compare/compare.controller.js +++ b/src/compare/compare.controller.js @@ -4,20 +4,23 @@ sonarADFWidget.controller('compare', compare); function compare(data) { var vm = this; - vm.projectLeft = data.projectLeft.split(':')[1]; - vm.projectRight = data.projectRight.split(':')[1]; - var projectLeftMetrics = data.resp.projectLeft.data.component.measures; - var projectRightMetrics = data.resp.projectRight.data.component.measures; - var compareTable = []; - angular.forEach(projectLeftMetrics, function (metricLeft) { - angular.forEach(projectRightMetrics, function (metricRight) { - if (metricRight.metric === metricLeft.metric) { - compareTable.push({metricName: metricLeft.metric, - projectValLeft: metricLeft.value, projectValRight: metricRight.value}); - } + if(data != "Please Setup the Widget"){ + vm.projectLeft = data.projectLeft.split(':')[1]; + vm.projectRight = data.projectRight.split(':')[1]; + var projectLeftMetrics = data.resp.projectLeft.data.component.measures; + var projectRightMetrics = data.resp.projectRight.data.component.measures; + var compareTable = []; + angular.forEach(projectLeftMetrics, function (metricLeft) { + angular.forEach(projectRightMetrics, function (metricRight) { + if (metricRight.metric === metricLeft.metric) { + compareTable.push({metricName: metricLeft.metric, + projectValLeft: metricLeft.value, projectValRight: metricRight.value}); + } + }); }); - }); - vm.compareTable = compareTable; + vm.compareTable = compareTable; + } + } sonarADFWidget.controller('editController', editController); diff --git a/src/projectquality/quality.controller.js b/src/projectquality/quality.controller.js index 9d4a587..9f1de77 100644 --- a/src/projectquality/quality.controller.js +++ b/src/projectquality/quality.controller.js @@ -4,9 +4,10 @@ sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.project = data.project; + vm.project = data.project.split(':')[1];; vm.url = data.url; + angular.forEach(data.quality_index, function (metric) { if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order vm.coverage = metric.value; diff --git a/src/projectquality/view.html b/src/projectquality/view.html index 4a4b614..f04d211 100644 --- a/src/projectquality/view.html +++ b/src/projectquality/view.html @@ -5,12 +5,20 @@ color: white; } + div.sonar-content h4{ + color: white; + border: 2px solid white; + padding: 8px; + text-align: center; + } + + .statusQualitygate, .codeCoverage, .blockerIssues, .technicalDept, .vulnerabilities { border: 2px solid white; margin-bottom: 2%; } - .codeCoverage, .technicalDept, .blockerIssues, .vulnerabilities{ + .codeCoverage, .technicalDept, .blockerIssues, .vulnerabilities, div.sonar-content h4{ background-color: #1B7DAA; } @@ -44,7 +52,7 @@
- +

{{vm.project}}

diff --git a/src/service.js b/src/service.js index cc0576a..b1170ea 100644 --- a/src/service.js +++ b/src/service.js @@ -333,7 +333,7 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint}; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint.url}; }); } From 966636cabd08381b9dff598538831a12253895f4 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 16:31:58 +0100 Subject: [PATCH 12/16] updates dist --- dist/adf-widget-sonar.js | 113 ++++++++++++++++++----------------- dist/adf-widget-sonar.min.js | 2 +- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index 0301429..b89254d 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -159,18 +159,18 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. }]); -angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); -$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); +angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); $templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); +$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); $templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/view.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); +$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"unknown\"}}

Technical Dept
about metrics
"); +$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"unknown\"}}

Technical Dept
about metrics
"); $templateCache.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

");}]); @@ -188,9 +188,10 @@ sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.project = data.project; + vm.project = data.project.split(':')[1];; vm.url = data.url; + angular.forEach(data.quality_index, function (metric) { if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order vm.coverage = metric.value; @@ -211,20 +212,6 @@ qualityCtrl.$inject = ["data"]; -sonarADFWidget. -controller('progress', progress); - -function progress(data, roundProgressConfig){ - var vm = this; - roundProgressConfig.max = data.maxDays; - roundProgressConfig.current = data.daysLeft; - vm.result = data; - vm.progressProperties=roundProgressConfig; -} -progress.$inject = ["data", "roundProgressConfig"]; - - - sonarADFWidget. controller('sonarIssueCtrl', sonarIssueCtrl); @@ -329,24 +316,41 @@ sonarIssueCtrl.$inject = ["data", "config"]; +sonarADFWidget. +controller('progress', progress); + +function progress(data, roundProgressConfig){ + var vm = this; + roundProgressConfig.max = data.maxDays; + roundProgressConfig.current = data.daysLeft; + vm.result = data; + vm.progressProperties=roundProgressConfig; +} +progress.$inject = ["data", "roundProgressConfig"]; + + + sonarADFWidget.controller('compare', compare); function compare(data) { var vm = this; - vm.projectLeft = data.projectLeft.split(':')[1]; - vm.projectRight = data.projectRight.split(':')[1]; - var projectLeftMetrics = data.resp.projectLeft.data.component.measures; - var projectRightMetrics = data.resp.projectRight.data.component.measures; - var compareTable = []; - angular.forEach(projectLeftMetrics, function (metricLeft) { - angular.forEach(projectRightMetrics, function (metricRight) { - if (metricRight.metric === metricLeft.metric) { - compareTable.push({metricName: metricLeft.metric, - projectValLeft: metricLeft.value, projectValRight: metricRight.value}); - } + if(data != "Please Setup the Widget"){ + vm.projectLeft = data.projectLeft.split(':')[1]; + vm.projectRight = data.projectRight.split(':')[1]; + var projectLeftMetrics = data.resp.projectLeft.data.component.measures; + var projectRightMetrics = data.resp.projectRight.data.component.measures; + var compareTable = []; + angular.forEach(projectLeftMetrics, function (metricLeft) { + angular.forEach(projectRightMetrics, function (metricRight) { + if (metricRight.metric === metricLeft.metric) { + compareTable.push({metricName: metricLeft.metric, + projectValLeft: metricLeft.value, projectValRight: metricRight.value}); + } + }); }); - }); - vm.compareTable = compareTable; + vm.compareTable = compareTable; + } + } compare.$inject = ["data"]; @@ -378,14 +382,29 @@ function editController($scope, $http, sonarApi, sonarEndpoint) { +sonarADFWidget. +controller('sonarStatsCtrl', sonarStatsCtrl); + +function sonarStatsCtrl(data){ + var vm = this; + if (!data.support){ + vm.support = data; + }else{ + vm.data = data; + } + +} +sonarStatsCtrl.$inject = ["data"]; + + + sonarADFWidget. controller('sonarLineChart', sonarLineChart); //setup controller function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - - if (data){ + if (data != "Please Setup the Widget"){ vm.chart = createChart(); } function createChart() { @@ -403,10 +422,12 @@ function sonarLineChart(data, METRIC_NAMES) { class: "chart-line", options: options }; + for (var i = 0; i < data.length; i++) { chart.series.push(METRIC_NAMES[data[i].metric]); chart.data.push(data[i].values); } + chart.labels = data[0].dates; return chart; } @@ -518,22 +539,6 @@ editController.$inject = ["$scope", "sonarApi", "sonarEndpoint"]; -sonarADFWidget. -controller('sonarStatsCtrl', sonarStatsCtrl); - -function sonarStatsCtrl(data){ - var vm = this; - if (!data.support){ - vm.support = data; - }else{ - vm.data = data; - } - -} -sonarStatsCtrl.$inject = ["data"]; - - - sonarADFWidget. factory('sonarApi', sonarApi); @@ -867,7 +872,7 @@ function sonarApi($http, $q, sonarEndpoint) { 'Accept': 'application/json' } }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint}; + return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint.url}; }); } @@ -884,4 +889,4 @@ function sonarApi($http, $q, sonarEndpoint) { } sonarApi.$inject = ["$http", "$q", "sonarEndpoint"]; -})(window); +})(window); \ No newline at end of file diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index f9cd9a0..be57246 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project,t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;t.max=e.maxDays,t.current=e.daysLeft,o.result=e,o.progressProperties=t}function a(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function f(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("progress",n),n.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file +!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function h(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/allProjects/edit.html",'
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("sonarIssueCtrl",n),n.$inject=["data","config"],u.controller("progress",a),a.$inject=["data","roundProgressConfig"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarStatsCtrl",l),l.$inject=["data"],u.controller("sonarLineChart",c),c.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file From b081a9ae4dbceb32766d9915bb2af6b7b3596123 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 16:50:20 +0100 Subject: [PATCH 13/16] fixes small bug --- src/projectquality/quality.controller.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/projectquality/quality.controller.js b/src/projectquality/quality.controller.js index 9f1de77..0226f53 100644 --- a/src/projectquality/quality.controller.js +++ b/src/projectquality/quality.controller.js @@ -4,23 +4,24 @@ sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.project = data.project.split(':')[1];; - vm.url = data.url; + if(data!="Please Setup the Widget") { + vm.project = data.project.split(':')[1]; + vm.url = data.url; - angular.forEach(data.quality_index, function (metric) { + angular.forEach(data.quality_index, function (metric) { if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order - vm.coverage = metric.value; + vm.coverage = metric.value; else if (metric.metric === "blocker_violations") - vm.blocker = metric.value; + vm.blocker = metric.value; else if (metric.metric === "alert_status") { - vm.qualityGateStatus = metric.value; - } - else if (metric.metric === "sqale_index") { + vm.qualityGateStatus = metric.value; + } else if (metric.metric === "sqale_index") { vm.technicalDept = metric.value; - } - else if (metric.metric === "vulnerabilities") { + } else if (metric.metric === "vulnerabilities") { vm.vulnerabilities = metric.value; } - }); + }); + } + } From 091bc2688a6f36348c39d8f8167f5f9029264357 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Mon, 11 Mar 2019 16:50:49 +0100 Subject: [PATCH 14/16] updates dist --- dist/adf-widget-sonar.js | 61 ++++++++++++++++++------------------ dist/adf-widget-sonar.min.js | 2 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index b89254d..ad6abb9 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -159,10 +159,10 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. }]); -angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); -$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); +angular.module("adf.widget.sonar").run(["$templateCache", function($templateCache) {$templateCache.put("{widgetsPath}/sonar/src/allProjects/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); +$templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); +$templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); $templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); @@ -188,25 +188,26 @@ sonarADFWidget.controller('qualityCtrl', qualityCtrl); function qualityCtrl(data) { var vm = this; - vm.project = data.project.split(':')[1];; - vm.url = data.url; + if(data!="Please Setup the Widget") { + vm.project = data.project.split(':')[1]; + vm.url = data.url; - angular.forEach(data.quality_index, function (metric) { + angular.forEach(data.quality_index, function (metric) { if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order - vm.coverage = metric.value; + vm.coverage = metric.value; else if (metric.metric === "blocker_violations") - vm.blocker = metric.value; + vm.blocker = metric.value; else if (metric.metric === "alert_status") { - vm.qualityGateStatus = metric.value; - } - else if (metric.metric === "sqale_index") { + vm.qualityGateStatus = metric.value; + } else if (metric.metric === "sqale_index") { vm.technicalDept = metric.value; - } - else if (metric.metric === "vulnerabilities") { + } else if (metric.metric === "vulnerabilities") { vm.vulnerabilities = metric.value; } - }); + }); + } + } qualityCtrl.$inject = ["data"]; @@ -382,22 +383,6 @@ function editController($scope, $http, sonarApi, sonarEndpoint) { -sonarADFWidget. -controller('sonarStatsCtrl', sonarStatsCtrl); - -function sonarStatsCtrl(data){ - var vm = this; - if (!data.support){ - vm.support = data; - }else{ - vm.data = data; - } - -} -sonarStatsCtrl.$inject = ["data"]; - - - sonarADFWidget. controller('sonarLineChart', sonarLineChart); //setup controller @@ -539,6 +524,22 @@ editController.$inject = ["$scope", "sonarApi", "sonarEndpoint"]; +sonarADFWidget. +controller('sonarStatsCtrl', sonarStatsCtrl); + +function sonarStatsCtrl(data){ + var vm = this; + if (!data.support){ + vm.support = data; + }else{ + vm.data = data; + } + +} +sonarStatsCtrl.$inject = ["data"]; + + + sonarADFWidget. factory('sonarApi', sonarApi); diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index be57246..a97e5c8 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)})}function n(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function h(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/allProjects/edit.html",'
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("sonarIssueCtrl",n),n.$inject=["data","config"],u.controller("progress",a),a.$inject=["data","roundProgressConfig"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarStatsCtrl",l),l.$inject=["data"],u.controller("sonarLineChart",c),c.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file +!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;"Please Setup the Widget"!=e&&(t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)}))}function n(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function h(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("sonarIssueCtrl",n),n.$inject=["data","config"],u.controller("progress",a),a.$inject=["data","roundProgressConfig"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file From a76b2257f086ad1d85c86bcb918ad9e63dff4a5b Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Tue, 12 Mar 2019 13:21:42 +0100 Subject: [PATCH 15/16] updates version check for Endpoint handling between Sonar versions --- dist/adf-widget-sonar.js | 407 +++++++++++++++------------- dist/adf-widget-sonar.min.js | 2 +- src/allProjects/stats.controller.js | 13 +- src/chart/lineChart.controller.js | 1 + src/projectquality/view.html | 24 +- src/service.js | 277 ++++++++++--------- src/sonar.js | 80 +++--- 7 files changed, 446 insertions(+), 358 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index ad6abb9..51335b2 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -1,29 +1,36 @@ (function(window, undefined) {'use strict'; //app initialisation with dependencies -var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker','angular-svg-round-progressbar']) -.constant("sonarEndpoint", { - "url": "https://192.168.56.2/sonar" -}) - .constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", -"public_documented_api_density": "Public documented API density","duplicated_lines_density": "Duplicated Lines (%)", -"sqale_index":"SQALE index", "coverage": "Coverage (%)", "tests": "Tests" }) - .config(["dashboardProvider", function(dashboardProvider) { +var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker', 'angular-svg-round-progressbar']) + .constant("sonarEndpoint", { + "url": "https://builds.apache.org/analysis" + }) + .constant("METRIC_NAMES", { + "open_issues": "Open Issues", + "ncloc": "Lines of Code", + "public_documented_api_density": "Public documented API density", + "duplicated_lines_density": "Duplicated Lines (%)", + "sqale_index": "SQALE index", + "coverage": "Coverage (%)", + "tests": "Tests" + }) + .config(["dashboardProvider", function (dashboardProvider) { dashboardProvider .widget('sonar-all-projects-statistics', { title: 'Sonar Statistics of all Projects ', description: 'Displays all SonarQube statistics', templateUrl: '{widgetsPath}/sonar/src/allProjects/view.html', - resolve: { - data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { - if (config.apiUrl) { - return sonarApi.getAllProjectsStatistics(config.apiUrl); - } - else if (sonarEndpoint.url){ - return sonarApi.getAllProjectsStatistics(sonarEndpoint.url); - } - return 'Please Setup the Widget'; - }] + reload: true, + resolve: { + data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { + if (config.apiUrl) { + return sonarApi.getAllProjectsStatistics(config.apiUrl); + } + else if (sonarEndpoint.url){ + return sonarApi.getAllProjectsStatistics(sonarEndpoint.url); + } + return 'Please Setup the Widget'; + }] }, category: 'SonarQube', controller: 'sonarStatsCtrl', @@ -37,16 +44,16 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays a linechart with different metrics', templateUrl: '{widgetsPath}/sonar/src/chart/view.html', resolve: { - data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { + data: ["sonarApi", "config", "sonarEndpoint", function (sonarApi, config, sonarEndpoint) { var apiUrl; if (config.apiUrl) { apiUrl = config.apiUrl; } else { apiUrl = sonarEndpoint.url; } - if (apiUrl && config.project && config.metrics){ + if (apiUrl && config.project && config.metrics) { return sonarApi.getChartData(apiUrl, config.project, config.metrics, config.timespan); - } else{ + } else { return 'Please Setup the Widget'; } }] @@ -63,13 +70,12 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays a table to compare two projects', templateUrl: '{widgetsPath}/sonar/src/compare/view.html', resolve: { - data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { + data: ["sonarApi", "config", "sonarEndpoint", function (sonarApi, config, sonarEndpoint) { - if (config.apiUrl){ + if (config.apiUrl) { return sonarApi.getMetrics(config.apiUrl, config.projectname1, config.projectname2); - } - else if (sonarEndpoint.url && config.projectname1 && config.projectname2){ - return sonarApi.getMetrics(sonarEndpoint.url, config.projectname1,config.projectname2); + } else if (sonarEndpoint.url && config.projectname1 && config.projectname2) { + return sonarApi.getMetrics(sonarEndpoint.url, config.projectname1, config.projectname2); } return 'Please Setup the Widget'; }] @@ -86,8 +92,8 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Visualizes the progress of a project', templateUrl: '{widgetsPath}/sonar/src/project-progress/view.html', resolve: { - data: ["sonarApi", "config", function(sonarApi, config) { - if (config.projectBeginn){ + data: ["sonarApi", "config", function (sonarApi, config) { + if (config.projectBeginn) { return sonarApi.getProjectTime(config.projectBeginn, config.projectEnd); } return 'Please Setup the Widget'; @@ -104,9 +110,9 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays the current sonar server version', templateUrl: '{widgetsPath}/sonar/src/version/view.html', resolve: { - data: ["sonarApi", "sonarEndpoint", function(sonarApi, sonarEndpoint) { - return sonarApi.getServerVersion(sonarEndpoint.url); - }] + data: ["sonarApi", "sonarEndpoint", function (sonarApi, sonarEndpoint) { + return sonarApi.getServerVersion(sonarEndpoint.url); + }] }, category: 'SonarQube', controller: 'version', @@ -117,11 +123,10 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays all issues of yourself', templateUrl: '{widgetsPath}/sonar/src/issues/view.html', resolve: { - data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { + data: ["sonarApi", "config", "sonarEndpoint", function (sonarApi, config, sonarEndpoint) { if (config.apiUrl) { return sonarApi.getAllMyIssues(config.apiUrl); - } - else if (sonarEndpoint.url){ + } else if (sonarEndpoint.url) { return sonarApi.getAllMyIssues(sonarEndpoint.url); } return 'Please Setup the Widget'; @@ -131,7 +136,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. controller: 'sonarIssueCtrl', controllerAs: 'vm', edit: { - templateUrl: '{widgetsPath}/sonar/src/issues/edit.html' + templateUrl: '{widgetsPath}/sonar/src/issues/edit.html' } }) .widget('sonar-projectquality', { @@ -139,11 +144,10 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays metrics of a specific project', templateUrl: '{widgetsPath}/sonar/src/projectquality/view.html', resolve: { - data: ["sonarApi", "config", "sonarEndpoint", function(sonarApi, config, sonarEndpoint) { + data: ["sonarApi", "config", "sonarEndpoint", function (sonarApi, config, sonarEndpoint) { if (config.apiUrl && config.project) { return sonarApi.getProjectquality(config.apiUrl, config.project); - } - else if (sonarEndpoint.url && config.project){ + } else if (sonarEndpoint.url && config.project) { return sonarApi.getProjectquality(sonarEndpoint.url, config.project); } return 'Please Setup the Widget'; @@ -153,7 +157,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. controller: 'qualityCtrl', controllerAs: 'vm', edit: { - templateUrl: '{widgetsPath}/sonar/src/projectquality/edit.html' + templateUrl: '{widgetsPath}/sonar/src/projectquality/edit.html' } }); @@ -165,12 +169,12 @@ $templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); $templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); $templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); +$templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); +$templateCache.put("{widgetsPath}/sonar/src/project-progress/view.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); $templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); -$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"unknown\"}}

Code Coverage

{{vm.blocker||\"unknown\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"unknown\"}}

Technical Dept
about metrics
"); +$templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"/\"}}

Code Coverage

{{vm.blocker||\"/\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"/\"}}

Technical Dept
about metrics
"); $templateCache.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

");}]); @@ -213,6 +217,20 @@ qualityCtrl.$inject = ["data"]; +sonarADFWidget. +controller('progress', progress); + +function progress(data, roundProgressConfig){ + var vm = this; + roundProgressConfig.max = data.maxDays; + roundProgressConfig.current = data.daysLeft; + vm.result = data; + vm.progressProperties=roundProgressConfig; +} +progress.$inject = ["data", "roundProgressConfig"]; + + + sonarADFWidget. controller('sonarIssueCtrl', sonarIssueCtrl); @@ -317,20 +335,6 @@ sonarIssueCtrl.$inject = ["data", "config"]; -sonarADFWidget. -controller('progress', progress); - -function progress(data, roundProgressConfig){ - var vm = this; - roundProgressConfig.max = data.maxDays; - roundProgressConfig.current = data.daysLeft; - vm.result = data; - vm.progressProperties=roundProgressConfig; -} -progress.$inject = ["data", "roundProgressConfig"]; - - - sonarADFWidget.controller('compare', compare); function compare(data) { @@ -389,6 +393,7 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; + console.log(data); if (data != "Please Setup the Widget"){ vm.chart = createChart(); } @@ -529,43 +534,43 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - if (!data.support){ - vm.support = data; - }else{ - vm.data = data; + console.log(data); + if (data){ + console.log(data); + if (data.support){ + vm.support = data; + }else{ + vm.data = data; + } } + } sonarStatsCtrl.$inject = ["data"]; -sonarADFWidget. -factory('sonarApi', sonarApi); +sonarADFWidget.factory('sonarApi', sonarApi); //function factory sonar function sonarApi($http, $q, sonarEndpoint) { - // make a compatibility check set requiredVersion to the last version the api is supported with - // eg. Endpoint is removed in v6.1 than set requiredServerVersion to 6.0 - function isAPISupported(requiredServerVersion){ - getServerVersion(sonarEndpoint.url).then(function(serverVersion){ - return checkVersionCompatibilityLowerThan(requiredServerVersion, String(serverVersion)); - }); - } - function checkVersionCompatibilityLowerThan(requiredVersion, actualVersion){ - var ver1 = requiredVersion.split('.'); - var ver2 = actualVersion.split('.'); - if (ver1[0] < ver2[0]){ + function checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) { + if (requiredAPIVersion && serverVersion) { + var ver1 = requiredAPIVersion.split('.'); + var ver2 = serverVersion.split('.'); + if (ver1[0] > ver2[0]) { + return true; + } else if (ver1[0] === ver2[0] && ver1[1] >= ver2[1]) { + return true; + } return false; - }else if (ver1[0] === ver2[0] && ver1[1] <= ver2[1]){ - return false } - return true; + } - function getServerVersion(sonarUrl){ + function getServerVersion(sonarUrl) { var serverVersionReqUrl = sonarUrl + "/api/server/version"; return $http({ method: 'GET', @@ -573,7 +578,7 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data; }); } @@ -595,7 +600,7 @@ function sonarApi($http, $q, sonarEndpoint) { } function createApiUrlQuality(sonarUrl, projectname) { - return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; + return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; } function getProjectTime(projectBeginn, projectEnd) { @@ -616,7 +621,7 @@ function sonarApi($http, $q, sonarEndpoint) { function workingDaysBetweenDates(startDate, endDate) { // Validate input - if (endDate < startDate){ + if (endDate < startDate) { return 0; } @@ -636,19 +641,17 @@ function sonarApi($http, $q, sonarEndpoint) { var endDay = endDate.getDay(); // Remove weekend not previously removed. - if (startDay - endDay > 1) - { + if (startDay - endDay > 1) { days = days - 2; } // Remove start day if span starts on Sunday but ends before Saturday - if (startDay === 0 && endDay != 6){ + if (startDay === 0 && endDay != 6) { days = days - 1; } // Remove end day if span ends on Saturday but starts after Sunday - if (endDay === 6 && startDay != 0) - { + if (endDay === 6 && startDay != 0) { days = days - 1; } @@ -685,20 +688,19 @@ function sonarApi($http, $q, sonarEndpoint) { var api1 = $http.get(apiUrlProject1); var api2 = $http.get(apiUrlProject2); return $q.all([api1, api2]) - .then(function(response) { + .then(function (response) { var projectLeft = response[0]; var projectRight = response[1]; var projectMetrics = { 'projectLeft': projectLeft, 'projectRight': projectRight }; - return {resp: projectMetrics,projectLeft: projectname1, projectRight: projectname2}; + return {resp: projectMetrics, projectLeft: projectname1, projectRight: projectname2}; }); } function getChartData(sonarUrl, projectname, metrics, timespan) { - var requiredAPIVersion = "6.2"; var apiUrl; var fromDateTime; var toDateTime; @@ -706,7 +708,7 @@ function sonarApi($http, $q, sonarEndpoint) { var metricsString = createMetricsString(metrics); if (timespan.type === 'dynamic') { var today = new Date(); - switch(timespan.dynamic) { + switch (timespan.dynamic) { case 'week': fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); break; @@ -722,75 +724,94 @@ function sonarApi($http, $q, sonarEndpoint) { fromDateTime = timespan.fromDateTime; toDateTime = timespan.toDateTime; } - // implementation for api version 6.2 or lower - if(isAPISupported(requiredAPIVersion)){ - if ((fromDateTime && toDateTime)) { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; - } else { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function(response) { - var responseData = response.data[0]; - var cols = responseData.cols; - var cells = responseData.cells; - for (var x = 0; x < cols.length; x++) { - var values = []; - var dates = []; - for (var y = 0; y < cells.length; y++) { - dates[y] = cells[y].d.split("T")[0]; - values[y] = cells[y].v[x]; - } - var metricsObj = { - 'metric': cols[x].metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); - } - return metricsArray; - }); - // implementation vor api version 6.3 or higher - }else { - if ((fromDateTime && toDateTime)) { - //convert for api request YEAR-MONTH-DAY - fromDateTime = fromDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); - toDateTime = toDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + var requiredAPIVersion = '6.2'; + return new Promise( + function (resolve) { - apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; - }else{ - apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function (response) { - response.data.measures.forEach(function(element) { - var dates= []; - var values = []; - element.history.forEach(function(data){ - dates.push(data.date.split("T")[0]); - values.push(data.value); - }); - var metricsObj = { - 'metric': element.metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); + var serverVersion = getServerVersion(sonarUrl).then(function (response) { + return response; + }); + + var isAPISupported = serverVersion.then(function (serverVersion) { + return checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) + }); + + var responseData = isAPISupported.then(function (isAPISupported) { + // implementation for api version 6.2 or lower + if (isAPISupported) { + if ((fromDateTime && toDateTime)) { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var responseData = response.data[0]; + var cols = responseData.cols; + var cells = responseData.cells; + for (var x = 0; x < cols.length; x++) { + var values = []; + var dates = []; + for (var y = 0; y < cells.length; y++) { + dates[y] = cells[y].d.split("T")[0]; + values[y] = cells[y].v[x]; + } + var metricsObj = { + 'metric': cols[x].metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + } + return metricsArray; + }); + // implementation vor api version 6.3 or higher + } else { + + if ((fromDateTime && toDateTime)) { + //convert for api request YEAR-MONTH-DAY + fromDateTime = fromDateTime.toISOString().replace(/T.*/, '').split('-').join('-'); + toDateTime = toDateTime.toISOString().replace(/T.*/, '').split('-').join('-'); + + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + response.data.measures.forEach(function (element) { + var dates = []; + var values = []; + element.history.forEach(function (data) { + dates.push(data.date.split("T")[0]); + values.push(data.value); + }); + var metricsObj = { + 'metric': element.metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + }); + return metricsArray + }); + } + }); + setTimeout(function () { + resolve(responseData) }); - return metricsArray }); - } } @@ -798,13 +819,15 @@ function sonarApi($http, $q, sonarEndpoint) { var linesOfCodeSum = 0; var avarageCoverage = 0; for (var i = 0; i < projects.length; i++) { - if (projects[i].msr[0]) { - var linesOfCode = projects[i].msr[0].val; - linesOfCodeSum += linesOfCode; - } - if (projects[i].msr[1]) { - var coverage = projects[i].msr[1].val; - avarageCoverage += coverage; + if (projects[i].msr) { + if (projects[i].msr[0]) { + var linesOfCode = projects[i].msr[0].val; + linesOfCodeSum += linesOfCode; + } + if (projects[i].msr[1]) { + var coverage = projects[i].msr[1].val; + avarageCoverage += coverage; + } } } avarageCoverage = avarageCoverage / projects.length; @@ -823,34 +846,54 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data; }); } - function getAllProjectsStatistics(sonarUrl){ + function getAllProjectsStatistics(sonarUrl) { var requiredAPIVersion = '6.2'; + return new Promise( + function (resolve) { + + var serverVersion = getServerVersion(sonarUrl).then(function (data) { + return data; + }); - if(isAPISupported(requiredAPIVersion)) { - var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + var isAPISupported = serverVersion.then(function (serverVersion) { + return checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) + }); - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function (response) { - var projects = response.data; - return generateArray(projects); + var responseData = isAPISupported.then(function (isAPISupported) { + if (isAPISupported) { + var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var projects = response.data; + return generateArray(projects); + }); + } else { + return { + support: true, + message: "This widget is only compatible with sonar v" + requiredAPIVersion + " or lower." + } + } + }); + setTimeout(function () { + resolve(responseData) + }); }); - }else{ - return {support: false, message: "This widget is only compatible with sonar v"+requiredAPIVersion+ " or lower."} - } + + } - function getAllMyIssues(sonarUrl){ + function getAllMyIssues(sonarUrl) { var apiUrl = createApiUrlAllMyIssues(sonarUrl); return $http({ @@ -859,12 +902,12 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data.issues; }); } - function getProjectquality(sonarUrl, project){ + function getProjectquality(sonarUrl, project) { var apiUrl = createApiUrlQuality(sonarUrl, project); return $http({ method: 'GET', @@ -872,8 +915,8 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint.url}; + }).then(function (response) { + return {"project": project, "quality_index": response.data.component.measures, "url": sonarEndpoint.url}; }); } diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index a97e5c8..8c723cb 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function o(e){var t=this;t.version=e}function r(e){var t=this;"Please Setup the Widget"!=e&&(t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)}))}function n(e,t){var o=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;t1&&(n-=2),0===s&&6!=i&&(n-=1),6===i&&0!=s&&(n-=1),n}function m(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function g(o,r,n){var a=c(o,r),s=c(o,n),i=e.get(a),l=e.get(s);return t.all([i,l]).then(function(e){var t=e[0],o=e[1],a={projectLeft:t,projectRight:o};return{resp:a,projectLeft:r,projectRight:n}})}function h(t,o,n,a){var s,i,l,c="6.2",p=[],u=m(n);if("dynamic"===a.type){var d=new Date;switch(a.dynamic){case"week":i=new Date(d.getTime()-6048e5);break;case"month":i=new Date(d.getFullYear(),d.getMonth()-1,d.getDay());break;case"year":i=new Date(d.getFullYear()-1,d.getMonth(),d.getDay())}l=d}else"static"===a.type&&(i=a.fromDateTime,l=a.toDateTime);return r(c)?(s=i&&l?t+"/api/timemachine?resource="+o+"&metrics="+u+"&fromDateTime="+i+"&toDateTime="+l:t+"/api/timemachine?resource="+o+"&metrics="+u,e({method:"GET",url:s,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],o=t.cols,r=t.cells,n=0;n
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"unknown"}}

Code Coverage

{{vm.blocker||"unknown"}}

Blocker Issues

{{vm.technicalDept+" days" ||"unknown"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",o),o.$inject=["data"],u.controller("qualityCtrl",r),r.$inject=["data"],u.controller("sonarIssueCtrl",n),n.$inject=["data","config"],u.controller("progress",a),a.$inject=["data","roundProgressConfig"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file +!function(e,t){"use strict";function n(e){var t=this;t.version=e}function o(e){var t=this;"Please Setup the Widget"!=e&&(t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)}))}function r(e,t){var n=this;t.max=e.maxDays,t.current=e.daysLeft,n.result=e,n.progressProperties=t}function a(e,t){var n=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;to[0]||n[0]===o[0]&&n[1]>=o[1]}}function r(t){var n=t+"/api/server/version";return e({method:"GET",url:n,headers:{Accept:"application/json"}}).then(function(e){return e.data})}function a(e){return e+"/api/projects/index?format=json"}function s(e){return e+"/api/resources?metrics=ncloc,coverage"}function i(e){return e+"/api/issues/search?assignees=__me__"}function l(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=open_issues,ncloc,public_documented_api_density,duplicated_lines_density,sqale_index"}function c(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities"}function p(e,t){var n=new Date(e),o=new Date(t),r=new Date,a=u(n,o),s=u(r,o);return{maxDays:a,daysLeft:s}}function u(e,t){if(t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function d(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function m(n,o,r){var a=l(n,o),s=l(n,r),i=e.get(a),c=e.get(s);return t.all([i,c]).then(function(e){var t=e[0],n=e[1],a={projectLeft:t,projectRight:n};return{resp:a,projectLeft:o,projectRight:r}})}function g(t,n,a,s){var i,l,c,p=[],u=d(a);if("dynamic"===s.type){var m=new Date;switch(s.dynamic){case"week":l=new Date(m.getTime()-6048e5);break;case"month":l=new Date(m.getFullYear(),m.getMonth()-1,m.getDay());break;case"year":l=new Date(m.getFullYear()-1,m.getMonth(),m.getDay())}c=m}else"static"===s.type&&(l=s.fromDateTime,c=s.toDateTime);var g="6.2";return new Promise(function(a){var s=r(t).then(function(e){return e}),d=s.then(function(e){return o(g,e)}),m=d.then(function(o){return o?(i=l&&c?t+"/api/timemachine?resource="+n+"&metrics="+u+"&fromDateTime="+l+"&toDateTime="+c:t+"/api/timemachine?resource="+n+"&metrics="+u,e({method:"GET",url:i,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],n=t.cols,o=t.cells,r=0;r
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"/"}}

Code Coverage

{{vm.blocker||"/"}}

Blocker Issues

{{vm.technicalDept+" days" ||"/"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",n),n.$inject=["data"],u.controller("qualityCtrl",o),o.$inject=["data"],u.controller("progress",r),r.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file diff --git a/src/allProjects/stats.controller.js b/src/allProjects/stats.controller.js index ef4683c..efa4e63 100644 --- a/src/allProjects/stats.controller.js +++ b/src/allProjects/stats.controller.js @@ -5,10 +5,15 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - if (!data.support){ - vm.support = data; - }else{ - vm.data = data; + console.log(data); + if (data){ + console.log(data); + if (data.support){ + vm.support = data; + }else{ + vm.data = data; + } } + } diff --git a/src/chart/lineChart.controller.js b/src/chart/lineChart.controller.js index ccea609..ed5b9b6 100644 --- a/src/chart/lineChart.controller.js +++ b/src/chart/lineChart.controller.js @@ -6,6 +6,7 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; + console.log(data); if (data != "Please Setup the Widget"){ vm.chart = createChart(); } diff --git a/src/projectquality/view.html b/src/projectquality/view.html index f04d211..daa5c3b 100644 --- a/src/projectquality/view.html +++ b/src/projectquality/view.html @@ -5,7 +5,7 @@ color: white; } - div.sonar-content h4{ + h4#headline{ color: white; border: 2px solid white; padding: 8px; @@ -13,12 +13,14 @@ } - .statusQualitygate, .codeCoverage, .blockerIssues, .technicalDept, .vulnerabilities { + div.sonar-content .statusQualitygate,div.sonar-content > .codeCoverage, + div.sonar-content > .blockerIssues,div.sonar-content >.technicalDept,div.sonar-content >.vulnerabilities { border: 2px solid white; margin-bottom: 2%; } - .codeCoverage, .technicalDept, .blockerIssues, .vulnerabilities, div.sonar-content h4{ + div.sonar-content >.codeCoverage,div.sonar-content >.technicalDept,div.sonar-content >.blockerIssues, + div.sonar-content >.vulnerabilities, div.sonar-content>h4{ background-color: #1B7DAA; } @@ -52,7 +54,7 @@
-

{{vm.project}}

+

{{vm.project}}

@@ -86,24 +88,24 @@
Quality Gate

{{vm.vulnerabilities}}

-
Vulnerabilities
+
Vulnerabilities
-

{{vm.coverage||"unknown"}}

-
Code Coverage
+

{{vm.coverage||"/"}}

+
Code Coverage
-

{{vm.blocker||"unknown"}}

-
Blocker Issues
+

{{vm.blocker||"/"}}

+
Blocker Issues
-

{{vm.technicalDept+" days" ||"unknown"}}

-
Technical Dept
+

{{vm.technicalDept+" days" ||"/"}}

+
Technical Dept
about metrics
diff --git a/src/service.js b/src/service.js index b1170ea..6d50e89 100644 --- a/src/service.js +++ b/src/service.js @@ -1,31 +1,26 @@ 'use strict'; -sonarADFWidget. -factory('sonarApi', sonarApi); +sonarADFWidget.factory('sonarApi', sonarApi); //function factory sonar function sonarApi($http, $q, sonarEndpoint) { - // make a compatibility check set requiredVersion to the last version the api is supported with - // eg. Endpoint is removed in v6.1 than set requiredServerVersion to 6.0 - function isAPISupported(requiredServerVersion){ - getServerVersion(sonarEndpoint.url).then(function(serverVersion){ - return checkVersionCompatibilityLowerThan(requiredServerVersion, String(serverVersion)); - }); - } - function checkVersionCompatibilityLowerThan(requiredVersion, actualVersion){ - var ver1 = requiredVersion.split('.'); - var ver2 = actualVersion.split('.'); - if (ver1[0] < ver2[0]){ + function checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) { + if (requiredAPIVersion && serverVersion) { + var ver1 = requiredAPIVersion.split('.'); + var ver2 = serverVersion.split('.'); + if (ver1[0] > ver2[0]) { + return true; + } else if (ver1[0] === ver2[0] && ver1[1] >= ver2[1]) { + return true; + } return false; - }else if (ver1[0] === ver2[0] && ver1[1] <= ver2[1]){ - return false } - return true; + } - function getServerVersion(sonarUrl){ + function getServerVersion(sonarUrl) { var serverVersionReqUrl = sonarUrl + "/api/server/version"; return $http({ method: 'GET', @@ -33,7 +28,7 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data; }); } @@ -55,7 +50,7 @@ function sonarApi($http, $q, sonarEndpoint) { } function createApiUrlQuality(sonarUrl, projectname) { - return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; + return sonarUrl + '/api/measures/component?componentKey=' + projectname + '&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities'; } function getProjectTime(projectBeginn, projectEnd) { @@ -76,7 +71,7 @@ function sonarApi($http, $q, sonarEndpoint) { function workingDaysBetweenDates(startDate, endDate) { // Validate input - if (endDate < startDate){ + if (endDate < startDate) { return 0; } @@ -96,19 +91,17 @@ function sonarApi($http, $q, sonarEndpoint) { var endDay = endDate.getDay(); // Remove weekend not previously removed. - if (startDay - endDay > 1) - { + if (startDay - endDay > 1) { days = days - 2; } // Remove start day if span starts on Sunday but ends before Saturday - if (startDay === 0 && endDay != 6){ + if (startDay === 0 && endDay != 6) { days = days - 1; } // Remove end day if span ends on Saturday but starts after Sunday - if (endDay === 6 && startDay != 0) - { + if (endDay === 6 && startDay != 0) { days = days - 1; } @@ -145,20 +138,19 @@ function sonarApi($http, $q, sonarEndpoint) { var api1 = $http.get(apiUrlProject1); var api2 = $http.get(apiUrlProject2); return $q.all([api1, api2]) - .then(function(response) { + .then(function (response) { var projectLeft = response[0]; var projectRight = response[1]; var projectMetrics = { 'projectLeft': projectLeft, 'projectRight': projectRight }; - return {resp: projectMetrics,projectLeft: projectname1, projectRight: projectname2}; + return {resp: projectMetrics, projectLeft: projectname1, projectRight: projectname2}; }); } function getChartData(sonarUrl, projectname, metrics, timespan) { - var requiredAPIVersion = "6.2"; var apiUrl; var fromDateTime; var toDateTime; @@ -166,7 +158,7 @@ function sonarApi($http, $q, sonarEndpoint) { var metricsString = createMetricsString(metrics); if (timespan.type === 'dynamic') { var today = new Date(); - switch(timespan.dynamic) { + switch (timespan.dynamic) { case 'week': fromDateTime = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); break; @@ -182,75 +174,94 @@ function sonarApi($http, $q, sonarEndpoint) { fromDateTime = timespan.fromDateTime; toDateTime = timespan.toDateTime; } - // implementation for api version 6.2 or lower - if(isAPISupported(requiredAPIVersion)){ - if ((fromDateTime && toDateTime)) { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; - } else { - apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function(response) { - var responseData = response.data[0]; - var cols = responseData.cols; - var cells = responseData.cells; - for (var x = 0; x < cols.length; x++) { - var values = []; - var dates = []; - for (var y = 0; y < cells.length; y++) { - dates[y] = cells[y].d.split("T")[0]; - values[y] = cells[y].v[x]; - } - var metricsObj = { - 'metric': cols[x].metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); - } - return metricsArray; - }); - // implementation vor api version 6.3 or higher - }else { - if ((fromDateTime && toDateTime)) { - //convert for api request YEAR-MONTH-DAY - fromDateTime = fromDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); - toDateTime = toDateTime.toISOString().replace(/T.*/,'').split('-').join('-'); + var requiredAPIVersion = '6.2'; + return new Promise( + function (resolve) { - apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; - }else{ - apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; - } - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function (response) { - response.data.measures.forEach(function(element) { - var dates= []; - var values = []; - element.history.forEach(function(data){ - dates.push(data.date.split("T")[0]); - values.push(data.value); - }); - var metricsObj = { - 'metric': element.metric, - 'values': values, - 'dates': dates - }; - metricsArray.push(metricsObj); + var serverVersion = getServerVersion(sonarUrl).then(function (response) { + return response; + }); + + var isAPISupported = serverVersion.then(function (serverVersion) { + return checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) + }); + + var responseData = isAPISupported.then(function (isAPISupported) { + // implementation for api version 6.2 or lower + if (isAPISupported) { + if ((fromDateTime && toDateTime)) { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString + '&fromDateTime=' + fromDateTime + '&toDateTime=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/timemachine?resource=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var responseData = response.data[0]; + var cols = responseData.cols; + var cells = responseData.cells; + for (var x = 0; x < cols.length; x++) { + var values = []; + var dates = []; + for (var y = 0; y < cells.length; y++) { + dates[y] = cells[y].d.split("T")[0]; + values[y] = cells[y].v[x]; + } + var metricsObj = { + 'metric': cols[x].metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + } + return metricsArray; + }); + // implementation vor api version 6.3 or higher + } else { + + if ((fromDateTime && toDateTime)) { + //convert for api request YEAR-MONTH-DAY + fromDateTime = fromDateTime.toISOString().replace(/T.*/, '').split('-').join('-'); + toDateTime = toDateTime.toISOString().replace(/T.*/, '').split('-').join('-'); + + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString + '&from=' + fromDateTime + '&to=' + toDateTime; + } else { + apiUrl = sonarUrl + '/api/measures/search_history?component=' + projectname + '&metrics=' + metricsString; + } + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + response.data.measures.forEach(function (element) { + var dates = []; + var values = []; + element.history.forEach(function (data) { + dates.push(data.date.split("T")[0]); + values.push(data.value); + }); + var metricsObj = { + 'metric': element.metric, + 'values': values, + 'dates': dates + }; + metricsArray.push(metricsObj); + }); + return metricsArray + }); + } + }); + setTimeout(function () { + resolve(responseData) }); - return metricsArray }); - } } @@ -258,13 +269,15 @@ function sonarApi($http, $q, sonarEndpoint) { var linesOfCodeSum = 0; var avarageCoverage = 0; for (var i = 0; i < projects.length; i++) { - if (projects[i].msr[0]) { - var linesOfCode = projects[i].msr[0].val; - linesOfCodeSum += linesOfCode; - } - if (projects[i].msr[1]) { - var coverage = projects[i].msr[1].val; - avarageCoverage += coverage; + if (projects[i].msr) { + if (projects[i].msr[0]) { + var linesOfCode = projects[i].msr[0].val; + linesOfCodeSum += linesOfCode; + } + if (projects[i].msr[1]) { + var coverage = projects[i].msr[1].val; + avarageCoverage += coverage; + } } } avarageCoverage = avarageCoverage / projects.length; @@ -283,34 +296,54 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data; }); } - function getAllProjectsStatistics(sonarUrl){ + function getAllProjectsStatistics(sonarUrl) { var requiredAPIVersion = '6.2'; + return new Promise( + function (resolve) { - if(isAPISupported(requiredAPIVersion)) { - var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + var serverVersion = getServerVersion(sonarUrl).then(function (data) { + return data; + }); - return $http({ - method: 'GET', - url: apiUrl, - headers: { - 'Accept': 'application/json' - } - }).then(function (response) { - var projects = response.data; - return generateArray(projects); + var isAPISupported = serverVersion.then(function (serverVersion) { + return checkVersionCompatibilityLowerThan(requiredAPIVersion, serverVersion) + }); + + var responseData = isAPISupported.then(function (isAPISupported) { + if (isAPISupported) { + var apiUrl = createApiUrlAllProjectsStatistics(sonarUrl); + return $http({ + method: 'GET', + url: apiUrl, + headers: { + 'Accept': 'application/json' + } + }).then(function (response) { + var projects = response.data; + return generateArray(projects); + }); + } else { + return { + support: true, + message: "This widget is only compatible with sonar v" + requiredAPIVersion + " or lower." + } + } + }); + setTimeout(function () { + resolve(responseData) + }); }); - }else{ - return {support: false, message: "This widget is only compatible with sonar v"+requiredAPIVersion+ " or lower."} - } + + } - function getAllMyIssues(sonarUrl){ + function getAllMyIssues(sonarUrl) { var apiUrl = createApiUrlAllMyIssues(sonarUrl); return $http({ @@ -319,12 +352,12 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { + }).then(function (response) { return response.data.issues; }); } - function getProjectquality(sonarUrl, project){ + function getProjectquality(sonarUrl, project) { var apiUrl = createApiUrlQuality(sonarUrl, project); return $http({ method: 'GET', @@ -332,8 +365,8 @@ function sonarApi($http, $q, sonarEndpoint) { headers: { 'Accept': 'application/json' } - }).then(function(response) { - return {"project":project,"quality_index":response.data.component.measures, "url":sonarEndpoint.url}; + }).then(function (response) { + return {"project": project, "quality_index": response.data.component.measures, "url": sonarEndpoint.url}; }); } diff --git a/src/sonar.js b/src/sonar.js index 9b34bb0..f9b2b80 100644 --- a/src/sonar.js +++ b/src/sonar.js @@ -1,28 +1,35 @@ 'use strict'; //app initialisation with dependencies -var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker','angular-svg-round-progressbar']) -.constant("sonarEndpoint", { - "url": "https://192.168.56.2/sonar" -}) - .constant("METRIC_NAMES", {"open_issues":"Open Issues","ncloc":"Lines of Code", -"public_documented_api_density": "Public documented API density","duplicated_lines_density": "Duplicated Lines (%)", -"sqale_index":"SQALE index", "coverage": "Coverage (%)", "tests": "Tests" }) - .config(function(dashboardProvider) { +var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart.js', 'ui.bootstrap', 'ui.bootstrap.datepicker', 'angular-svg-round-progressbar']) + .constant("sonarEndpoint", { + "url": "https://builds.apache.org/analysis" + }) + .constant("METRIC_NAMES", { + "open_issues": "Open Issues", + "ncloc": "Lines of Code", + "public_documented_api_density": "Public documented API density", + "duplicated_lines_density": "Duplicated Lines (%)", + "sqale_index": "SQALE index", + "coverage": "Coverage (%)", + "tests": "Tests" + }) + .config(function (dashboardProvider) { dashboardProvider .widget('sonar-all-projects-statistics', { title: 'Sonar Statistics of all Projects ', description: 'Displays all SonarQube statistics', templateUrl: '{widgetsPath}/sonar/src/allProjects/view.html', - resolve: { - data: function(sonarApi, config, sonarEndpoint) { - if (config.apiUrl) { - return sonarApi.getAllProjectsStatistics(config.apiUrl); - } - else if (sonarEndpoint.url){ - return sonarApi.getAllProjectsStatistics(sonarEndpoint.url); + reload: true, + resolve: { + data: function(sonarApi, config, sonarEndpoint) { + if (config.apiUrl) { + return sonarApi.getAllProjectsStatistics(config.apiUrl); + } + else if (sonarEndpoint.url){ + return sonarApi.getAllProjectsStatistics(sonarEndpoint.url); + } + return 'Please Setup the Widget'; } - return 'Please Setup the Widget'; - } }, category: 'SonarQube', controller: 'sonarStatsCtrl', @@ -36,16 +43,16 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays a linechart with different metrics', templateUrl: '{widgetsPath}/sonar/src/chart/view.html', resolve: { - data: function(sonarApi, config, sonarEndpoint) { + data: function (sonarApi, config, sonarEndpoint) { var apiUrl; if (config.apiUrl) { apiUrl = config.apiUrl; } else { apiUrl = sonarEndpoint.url; } - if (apiUrl && config.project && config.metrics){ + if (apiUrl && config.project && config.metrics) { return sonarApi.getChartData(apiUrl, config.project, config.metrics, config.timespan); - } else{ + } else { return 'Please Setup the Widget'; } } @@ -62,13 +69,12 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays a table to compare two projects', templateUrl: '{widgetsPath}/sonar/src/compare/view.html', resolve: { - data: function(sonarApi, config, sonarEndpoint) { + data: function (sonarApi, config, sonarEndpoint) { - if (config.apiUrl){ + if (config.apiUrl) { return sonarApi.getMetrics(config.apiUrl, config.projectname1, config.projectname2); - } - else if (sonarEndpoint.url && config.projectname1 && config.projectname2){ - return sonarApi.getMetrics(sonarEndpoint.url, config.projectname1,config.projectname2); + } else if (sonarEndpoint.url && config.projectname1 && config.projectname2) { + return sonarApi.getMetrics(sonarEndpoint.url, config.projectname1, config.projectname2); } return 'Please Setup the Widget'; } @@ -85,8 +91,8 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Visualizes the progress of a project', templateUrl: '{widgetsPath}/sonar/src/project-progress/view.html', resolve: { - data: function(sonarApi, config) { - if (config.projectBeginn){ + data: function (sonarApi, config) { + if (config.projectBeginn) { return sonarApi.getProjectTime(config.projectBeginn, config.projectEnd); } return 'Please Setup the Widget'; @@ -103,9 +109,9 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays the current sonar server version', templateUrl: '{widgetsPath}/sonar/src/version/view.html', resolve: { - data: function(sonarApi, sonarEndpoint) { - return sonarApi.getServerVersion(sonarEndpoint.url); - } + data: function (sonarApi, sonarEndpoint) { + return sonarApi.getServerVersion(sonarEndpoint.url); + } }, category: 'SonarQube', controller: 'version', @@ -116,11 +122,10 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays all issues of yourself', templateUrl: '{widgetsPath}/sonar/src/issues/view.html', resolve: { - data: function(sonarApi, config, sonarEndpoint) { + data: function (sonarApi, config, sonarEndpoint) { if (config.apiUrl) { return sonarApi.getAllMyIssues(config.apiUrl); - } - else if (sonarEndpoint.url){ + } else if (sonarEndpoint.url) { return sonarApi.getAllMyIssues(sonarEndpoint.url); } return 'Please Setup the Widget'; @@ -130,7 +135,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. controller: 'sonarIssueCtrl', controllerAs: 'vm', edit: { - templateUrl: '{widgetsPath}/sonar/src/issues/edit.html' + templateUrl: '{widgetsPath}/sonar/src/issues/edit.html' } }) .widget('sonar-projectquality', { @@ -138,11 +143,10 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. description: 'Displays metrics of a specific project', templateUrl: '{widgetsPath}/sonar/src/projectquality/view.html', resolve: { - data: function(sonarApi, config, sonarEndpoint) { + data: function (sonarApi, config, sonarEndpoint) { if (config.apiUrl && config.project) { return sonarApi.getProjectquality(config.apiUrl, config.project); - } - else if (sonarEndpoint.url && config.project){ + } else if (sonarEndpoint.url && config.project) { return sonarApi.getProjectquality(sonarEndpoint.url, config.project); } return 'Please Setup the Widget'; @@ -152,7 +156,7 @@ var sonarADFWidget = angular.module('adf.widget.sonar', ['adf.provider', 'chart. controller: 'qualityCtrl', controllerAs: 'vm', edit: { - templateUrl: '{widgetsPath}/sonar/src/projectquality/edit.html' + templateUrl: '{widgetsPath}/sonar/src/projectquality/edit.html' } }); From 0cdf385cedcf5f64e203267cb010de890331a6f4 Mon Sep 17 00:00:00 2001 From: Christoph Wolfes Date: Tue, 12 Mar 2019 13:44:07 +0100 Subject: [PATCH 16/16] removes logging and updates dist --- dist/adf-widget-sonar.js | 149 ++++++++++++++-------------- dist/adf-widget-sonar.min.js | 2 +- src/allProjects/stats.controller.js | 2 - src/chart/lineChart.controller.js | 1 - 4 files changed, 74 insertions(+), 80 deletions(-) diff --git a/dist/adf-widget-sonar.js b/dist/adf-widget-sonar.js index 51335b2..6309fdd 100644 --- a/dist/adf-widget-sonar.js +++ b/dist/adf-widget-sonar.js @@ -167,14 +167,14 @@ angular.module("adf.widget.sonar").run(["$templateCache", function($templateCach $templateCache.put("{widgetsPath}/sonar/src/allProjects/view.html","

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
"); $templateCache.put("{widgetsPath}/sonar/src/chart/edit.html","

(*Required)

"); $templateCache.put("{widgetsPath}/sonar/src/chart/view.html","
Please configure the widget
"); -$templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); -$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/edit.html","

"); $templateCache.put("{widgetsPath}/sonar/src/project-progress/view.html","
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

"); $templateCache.put("{widgetsPath}/sonar/src/projectquality/edit.html","

(*Required)

"); $templateCache.put("{widgetsPath}/sonar/src/projectquality/view.html","
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||\"/\"}}

Code Coverage

{{vm.blocker||\"/\"}}

Blocker Issues

{{vm.technicalDept+\" days\" ||\"/\"}}

Technical Dept
about metrics
"); +$templateCache.put("{widgetsPath}/sonar/src/issues/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/issues/view.html","
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
"); +$templateCache.put("{widgetsPath}/sonar/src/compare/edit.html","
"); +$templateCache.put("{widgetsPath}/sonar/src/compare/view.html","
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
"); $templateCache.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

");}]); @@ -188,46 +188,55 @@ version.$inject = ["data"]; -sonarADFWidget.controller('qualityCtrl', qualityCtrl); - -function qualityCtrl(data) { - var vm = this; - if(data!="Please Setup the Widget") { - - vm.project = data.project.split(':')[1]; - vm.url = data.url; +sonarADFWidget.controller('compare', compare); - angular.forEach(data.quality_index, function (metric) { - if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order - vm.coverage = metric.value; - else if (metric.metric === "blocker_violations") - vm.blocker = metric.value; - else if (metric.metric === "alert_status") { - vm.qualityGateStatus = metric.value; - } else if (metric.metric === "sqale_index") { - vm.technicalDept = metric.value; - } else if (metric.metric === "vulnerabilities") { - vm.vulnerabilities = metric.value; +function compare(data) { + var vm = this; + if(data != "Please Setup the Widget"){ + vm.projectLeft = data.projectLeft.split(':')[1]; + vm.projectRight = data.projectRight.split(':')[1]; + var projectLeftMetrics = data.resp.projectLeft.data.component.measures; + var projectRightMetrics = data.resp.projectRight.data.component.measures; + var compareTable = []; + angular.forEach(projectLeftMetrics, function (metricLeft) { + angular.forEach(projectRightMetrics, function (metricRight) { + if (metricRight.metric === metricLeft.metric) { + compareTable.push({metricName: metricLeft.metric, + projectValLeft: metricLeft.value, projectValRight: metricRight.value}); } }); - } + }); + vm.compareTable = compareTable; + } } -qualityCtrl.$inject = ["data"]; +compare.$inject = ["data"]; +sonarADFWidget.controller('editController', editController); +function editController($scope, $http, sonarApi, sonarEndpoint) { + var vm = this; -sonarADFWidget. -controller('progress', progress); + $scope.updateProjects = function() { + var url; + if ($scope.config.apiUrl) { + url = $scope.config.apiUrl; + } else { + url = sonarEndpoint.url; + } + vm.projects = []; + sonarApi.getProjects(url).then(function(data) { + data.forEach(function(project) { + var proj = { + name: project.k + }; + vm.projects.push(proj); + }); + }); + }; + $scope.updateProjects(); -function progress(data, roundProgressConfig){ - var vm = this; - roundProgressConfig.max = data.maxDays; - roundProgressConfig.current = data.daysLeft; - vm.result = data; - vm.progressProperties=roundProgressConfig; } -progress.$inject = ["data", "roundProgressConfig"]; @@ -335,55 +344,46 @@ sonarIssueCtrl.$inject = ["data", "config"]; -sonarADFWidget.controller('compare', compare); +sonarADFWidget.controller('qualityCtrl', qualityCtrl); -function compare(data) { - var vm = this; - if(data != "Please Setup the Widget"){ - vm.projectLeft = data.projectLeft.split(':')[1]; - vm.projectRight = data.projectRight.split(':')[1]; - var projectLeftMetrics = data.resp.projectLeft.data.component.measures; - var projectRightMetrics = data.resp.projectRight.data.component.measures; - var compareTable = []; - angular.forEach(projectLeftMetrics, function (metricLeft) { - angular.forEach(projectRightMetrics, function (metricRight) { - if (metricRight.metric === metricLeft.metric) { - compareTable.push({metricName: metricLeft.metric, - projectValLeft: metricLeft.value, projectValRight: metricRight.value}); +function qualityCtrl(data) { + var vm = this; + if(data!="Please Setup the Widget") { + + vm.project = data.project.split(':')[1]; + vm.url = data.url; + + angular.forEach(data.quality_index, function (metric) { + if (metric.metric === "coverage") //going through all entries with if/elseif since there could miss some entries. So there is no special order + vm.coverage = metric.value; + else if (metric.metric === "blocker_violations") + vm.blocker = metric.value; + else if (metric.metric === "alert_status") { + vm.qualityGateStatus = metric.value; + } else if (metric.metric === "sqale_index") { + vm.technicalDept = metric.value; + } else if (metric.metric === "vulnerabilities") { + vm.vulnerabilities = metric.value; } }); - }); - vm.compareTable = compareTable; - } + } } -compare.$inject = ["data"]; +qualityCtrl.$inject = ["data"]; -sonarADFWidget.controller('editController', editController); -function editController($scope, $http, sonarApi, sonarEndpoint) { - var vm = this; - $scope.updateProjects = function() { - var url; - if ($scope.config.apiUrl) { - url = $scope.config.apiUrl; - } else { - url = sonarEndpoint.url; - } - vm.projects = []; - sonarApi.getProjects(url).then(function(data) { - data.forEach(function(project) { - var proj = { - name: project.k - }; - vm.projects.push(proj); - }); - }); - }; - $scope.updateProjects(); +sonarADFWidget. +controller('progress', progress); +function progress(data, roundProgressConfig){ + var vm = this; + roundProgressConfig.max = data.maxDays; + roundProgressConfig.current = data.daysLeft; + vm.result = data; + vm.progressProperties=roundProgressConfig; } +progress.$inject = ["data", "roundProgressConfig"]; @@ -393,7 +393,6 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - console.log(data); if (data != "Please Setup the Widget"){ vm.chart = createChart(); } @@ -534,9 +533,7 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - console.log(data); if (data){ - console.log(data); if (data.support){ vm.support = data; }else{ diff --git a/dist/adf-widget-sonar.min.js b/dist/adf-widget-sonar.min.js index 8c723cb..f150854 100644 --- a/dist/adf-widget-sonar.min.js +++ b/dist/adf-widget-sonar.min.js @@ -1 +1 @@ -!function(e,t){"use strict";function n(e){var t=this;t.version=e}function o(e){var t=this;"Please Setup the Widget"!=e&&(t.project=e.project.split(":")[1],t.url=e.url,angular.forEach(e.quality_index,function(e){"coverage"===e.metric?t.coverage=e.value:"blocker_violations"===e.metric?t.blocker=e.value:"alert_status"===e.metric?t.qualityGateStatus=e.value:"sqale_index"===e.metric?t.technicalDept=e.value:"vulnerabilities"===e.metric&&(t.vulnerabilities=e.value)}))}function r(e,t){var n=this;t.max=e.maxDays,t.current=e.daysLeft,n.result=e,n.progressProperties=t}function a(e,t){var n=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;to[0]||n[0]===o[0]&&n[1]>=o[1]}}function r(t){var n=t+"/api/server/version";return e({method:"GET",url:n,headers:{Accept:"application/json"}}).then(function(e){return e.data})}function a(e){return e+"/api/projects/index?format=json"}function s(e){return e+"/api/resources?metrics=ncloc,coverage"}function i(e){return e+"/api/issues/search?assignees=__me__"}function l(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=open_issues,ncloc,public_documented_api_density,duplicated_lines_density,sqale_index"}function c(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities"}function p(e,t){var n=new Date(e),o=new Date(t),r=new Date,a=u(n,o),s=u(r,o);return{maxDays:a,daysLeft:s}}function u(e,t){if(t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function d(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function m(n,o,r){var a=l(n,o),s=l(n,r),i=e.get(a),c=e.get(s);return t.all([i,c]).then(function(e){var t=e[0],n=e[1],a={projectLeft:t,projectRight:n};return{resp:a,projectLeft:o,projectRight:r}})}function g(t,n,a,s){var i,l,c,p=[],u=d(a);if("dynamic"===s.type){var m=new Date;switch(s.dynamic){case"week":l=new Date(m.getTime()-6048e5);break;case"month":l=new Date(m.getFullYear(),m.getMonth()-1,m.getDay());break;case"year":l=new Date(m.getFullYear()-1,m.getMonth(),m.getDay())}c=m}else"static"===s.type&&(l=s.fromDateTime,c=s.toDateTime);var g="6.2";return new Promise(function(a){var s=r(t).then(function(e){return e}),d=s.then(function(e){return o(g,e)}),m=d.then(function(o){return o?(i=l&&c?t+"/api/timemachine?resource="+n+"&metrics="+u+"&fromDateTime="+l+"&toDateTime="+c:t+"/api/timemachine?resource="+n+"&metrics="+u,e({method:"GET",url:i,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],n=t.cols,o=t.cells,r=0;r
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"/"}}

Code Coverage

{{vm.blocker||"/"}}

Blocker Issues

{{vm.technicalDept+" days" ||"/"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",n),n.$inject=["data"],u.controller("qualityCtrl",o),o.$inject=["data"],u.controller("progress",r),r.$inject=["data","roundProgressConfig"],u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("compare",s),s.$inject=["data"],u.controller("editController",i),u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",i),i.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file +!function(e,t){"use strict";function n(e){var t=this;t.version=e}function o(e){var t=this;if("Please Setup the Widget"!=e){t.projectLeft=e.projectLeft.split(":")[1],t.projectRight=e.projectRight.split(":")[1];var n=e.resp.projectLeft.data.component.measures,o=e.resp.projectRight.data.component.measures,r=[];angular.forEach(n,function(e){angular.forEach(o,function(t){t.metric===e.metric&&r.push({metricName:e.metric,projectValLeft:e.value,projectValRight:t.value})})}),t.compareTable=r}}function r(e,t,n,o){var r=this;e.updateProjects=function(){var t;t=e.config.apiUrl?e.config.apiUrl:o.url,r.projects=[],n.getProjects(t).then(function(e){e.forEach(function(e){var t={name:e.k};r.projects.push(t)})})},e.updateProjects()}function a(e,t){var n=this;if(0!=e.length){angular.forEach(e,function(e){e.subProject&&(e.subProject=e.subProject.slice(e.component.search(":")+1).replace(":"," ")),e.project&&(e.project=e.project.slice(e.component.search(":")+1).replace(":"," ")),e.component&&(e.component=e.component.slice(e.component.lastIndexOf(":")+1)),e.type&&(e.type=e.type.replace("_"," "));for(var t=0;to[0]||n[0]===o[0]&&n[1]>=o[1]}}function r(t){var n=t+"/api/server/version";return e({method:"GET",url:n,headers:{Accept:"application/json"}}).then(function(e){return e.data})}function a(e){return e+"/api/projects/index?format=json"}function s(e){return e+"/api/resources?metrics=ncloc,coverage"}function i(e){return e+"/api/issues/search?assignees=__me__"}function l(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=open_issues,ncloc,public_documented_api_density,duplicated_lines_density,sqale_index"}function c(e,t){return e+"/api/measures/component?componentKey="+t+"&metricKeys=coverage,blocker_violations,alert_status,sqale_index,vulnerabilities"}function p(e,t){var n=new Date(e),o=new Date(t),r=new Date,a=u(n,o),s=u(r,o);return{maxDays:a,daysLeft:s}}function u(e,t){if(t1&&(r-=2),0===s&&6!=i&&(r-=1),6===i&&0!=s&&(r-=1),r}function d(e){var t="";return e.linesOfCode&&(t+="ncloc,"),e.technicalDebt&&(t+="sqale_index,"),e.amountTest&&(t+="tests,"),e.testCoverage&&(t+="coverage,"),e.issues&&(t+="open_issues,"),e.rulesviolations&&(t+="duplicated_lines_density,"),t.slice(0,-1)}function m(n,o,r){var a=l(n,o),s=l(n,r),i=e.get(a),c=e.get(s);return t.all([i,c]).then(function(e){var t=e[0],n=e[1],a={projectLeft:t,projectRight:n};return{resp:a,projectLeft:o,projectRight:r}})}function g(t,n,a,s){var i,l,c,p=[],u=d(a);if("dynamic"===s.type){var m=new Date;switch(s.dynamic){case"week":l=new Date(m.getTime()-6048e5);break;case"month":l=new Date(m.getFullYear(),m.getMonth()-1,m.getDay());break;case"year":l=new Date(m.getFullYear()-1,m.getMonth(),m.getDay())}c=m}else"static"===s.type&&(l=s.fromDateTime,c=s.toDateTime);var g="6.2";return new Promise(function(a){var s=r(t).then(function(e){return e}),d=s.then(function(e){return o(g,e)}),m=d.then(function(o){return o?(i=l&&c?t+"/api/timemachine?resource="+n+"&metrics="+u+"&fromDateTime="+l+"&toDateTime="+c:t+"/api/timemachine?resource="+n+"&metrics="+u,e({method:"GET",url:i,headers:{Accept:"application/json"}}).then(function(e){for(var t=e.data[0],n=t.cols,o=t.cells,r=0;r
'),e.put("{widgetsPath}/sonar/src/allProjects/view.html",'

{{(vm.data.linesOfCode | number)||0}}

Lines of code

{{(vm.data.coverage | number:2)||0}}%

Average test coverage

{{vm.support.message}}
'),e.put("{widgetsPath}/sonar/src/chart/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/chart/view.html",'
Please configure the widget
'),e.put("{widgetsPath}/sonar/src/project-progress/edit.html",'

'),e.put("{widgetsPath}/sonar/src/project-progress/view.html",'
Please configure the widget

{{config.projectname}}

{{vm.result.daysLeft}}/{{vm.result.maxDays}}

Days left

'),e.put("{widgetsPath}/sonar/src/projectquality/edit.html",'

(*Required)

'),e.put("{widgetsPath}/sonar/src/projectquality/view.html",'
Please configure the widget

{{vm.project}}

{{vm.vulnerabilities}}

Vulnerabilities

{{vm.coverage||"/"}}

Code Coverage

{{vm.blocker||"/"}}

Blocker Issues

{{vm.technicalDept+" days" ||"/"}}

Technical Dept
about metrics
'),e.put("{widgetsPath}/sonar/src/issues/edit.html",'
'),e.put("{widgetsPath}/sonar/src/issues/view.html",'
You don\'t have any issues.
{{project.project}} {{project.subProject}} {{project.component}}
{{issue.message}}L{{issue.line}}
{{issue.type| lowercase}} {{issue.severity| lowercase}}{{issue.status| lowercase}} {{issue.effort}} effort {{issue.tag}}
'),e.put("{widgetsPath}/sonar/src/compare/edit.html",'
'),e.put("{widgetsPath}/sonar/src/compare/view.html",'
Please configure the widget
Metric{{vm.projectLeft}}{{vm.projectRight}}
{{entry.metricName}}{{entry.projectValLeft}}{{entry.projectValRight}}
'),e.put("{widgetsPath}/sonar/src/version/view.html","

{{vm.version}}

")}]),u.controller("version",n),n.$inject=["data"],u.controller("compare",o),o.$inject=["data"],u.controller("editController",r),u.controller("sonarIssueCtrl",a),a.$inject=["data","config"],u.controller("qualityCtrl",s),s.$inject=["data"],u.controller("progress",i),i.$inject=["data","roundProgressConfig"],u.controller("sonarLineChart",l),l.$inject=["data","METRIC_NAMES"],u.controller("editController",r),r.$inject=["$scope","sonarApi","sonarEndpoint"],u.controller("sonarStatsCtrl",c),c.$inject=["data"],u.factory("sonarApi",p),p.$inject=["$http","$q","sonarEndpoint"]}(window); \ No newline at end of file diff --git a/src/allProjects/stats.controller.js b/src/allProjects/stats.controller.js index efa4e63..89c248f 100644 --- a/src/allProjects/stats.controller.js +++ b/src/allProjects/stats.controller.js @@ -5,9 +5,7 @@ controller('sonarStatsCtrl', sonarStatsCtrl); function sonarStatsCtrl(data){ var vm = this; - console.log(data); if (data){ - console.log(data); if (data.support){ vm.support = data; }else{ diff --git a/src/chart/lineChart.controller.js b/src/chart/lineChart.controller.js index ed5b9b6..ccea609 100644 --- a/src/chart/lineChart.controller.js +++ b/src/chart/lineChart.controller.js @@ -6,7 +6,6 @@ sonarADFWidget. function sonarLineChart(data, METRIC_NAMES) { //initialize controller variable var vm = this; - console.log(data); if (data != "Please Setup the Widget"){ vm.chart = createChart(); }