diff options
author | Jean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com> | 2014-04-25 15:45:08 +0200 |
---|---|---|
committer | Jean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com> | 2014-04-25 15:45:16 +0200 |
commit | 433fc34a5a8513fe80dc6cd8ad758afde5bfd0a7 (patch) | |
tree | 38970e694ee89e140a546283bd129aac262e18c6 /plugins | |
parent | 88132bee081c22e3bad8265a3218bf853244aaa0 (diff) | |
download | sonarqube-433fc34a5a8513fe80dc6cd8ad758afde5bfd0a7.tar.gz sonarqube-433fc34a5a8513fe80dc6cd8ad758afde5bfd0a7.zip |
SONAR-4927 Add Quality Gate widget
Diffstat (limited to 'plugins')
3 files changed, 105 insertions, 64 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index b8770197f47..6268c9b7109 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -20,11 +20,7 @@ package org.sonar.plugins.core; import com.google.common.collect.ImmutableList; -import org.sonar.api.CoreProperties; -import org.sonar.api.Properties; -import org.sonar.api.Property; -import org.sonar.api.PropertyType; -import org.sonar.api.SonarPlugin; +import org.sonar.api.*; import org.sonar.api.checks.NoSonarFilter; import org.sonar.core.timemachine.Periods; import org.sonar.plugins.core.batch.IndexProjectPostJob; @@ -32,71 +28,19 @@ import org.sonar.plugins.core.charts.DistributionAreaChart; import org.sonar.plugins.core.charts.DistributionBarChart; import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; -import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard; -import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard; -import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard; -import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard; -import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard; -import org.sonar.plugins.core.issue.CountFalsePositivesDecorator; -import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator; -import org.sonar.plugins.core.issue.InitialOpenIssuesSensor; -import org.sonar.plugins.core.issue.InitialOpenIssuesStack; -import org.sonar.plugins.core.issue.IssueHandlers; -import org.sonar.plugins.core.issue.IssueTracking; -import org.sonar.plugins.core.issue.IssueTrackingDecorator; -import org.sonar.plugins.core.issue.IssuesDensityDecorator; -import org.sonar.plugins.core.issue.WeightedIssuesDecorator; -import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher; -import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate; -import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher; -import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate; -import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher; -import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob; +import org.sonar.plugins.core.dashboards.*; +import org.sonar.plugins.core.issue.*; +import org.sonar.plugins.core.issue.notification.*; import org.sonar.plugins.core.measurefilters.MyFavouritesFilter; import org.sonar.plugins.core.measurefilters.ProjectFilter; import org.sonar.plugins.core.notifications.alerts.NewAlerts; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; -import org.sonar.plugins.core.sensors.BranchCoverageDecorator; -import org.sonar.plugins.core.sensors.CommentDensityDecorator; -import org.sonar.plugins.core.sensors.CoverageDecorator; -import org.sonar.plugins.core.sensors.CoverageMeasurementFilter; -import org.sonar.plugins.core.sensors.DirectoriesDecorator; -import org.sonar.plugins.core.sensors.FileHashSensor; -import org.sonar.plugins.core.sensors.FilesDecorator; -import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator; -import org.sonar.plugins.core.sensors.ItCoverageDecorator; -import org.sonar.plugins.core.sensors.ItLineCoverageDecorator; -import org.sonar.plugins.core.sensors.LineCoverageDecorator; -import org.sonar.plugins.core.sensors.ManualMeasureDecorator; -import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator; -import org.sonar.plugins.core.sensors.OverallCoverageDecorator; -import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator; -import org.sonar.plugins.core.sensors.ProfileEventsSensor; -import org.sonar.plugins.core.sensors.ProjectLinksSensor; -import org.sonar.plugins.core.sensors.UnitTestDecorator; -import org.sonar.plugins.core.sensors.VersionEventsSensor; -import org.sonar.plugins.core.timemachine.NewCoverageAggregator; -import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer; -import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer; -import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer; -import org.sonar.plugins.core.timemachine.TendencyDecorator; -import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister; -import org.sonar.plugins.core.timemachine.VariationDecorator; +import org.sonar.plugins.core.sensors.*; +import org.sonar.plugins.core.timemachine.*; import org.sonar.plugins.core.web.TestsViewer; import org.sonar.plugins.core.widgets.*; -import org.sonar.plugins.core.widgets.issues.ActionPlansWidget; -import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget; -import org.sonar.plugins.core.widgets.issues.IssueFilterWidget; -import org.sonar.plugins.core.widgets.issues.IssuesWidget; -import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget; -import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget; -import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterAsBubbleChartWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterAsCloudWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterAsHistogramWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterAsPieChartWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterListWidget; -import org.sonar.plugins.core.widgets.measures.MeasureFilterTreemapWidget; +import org.sonar.plugins.core.widgets.issues.*; +import org.sonar.plugins.core.widgets.measures.*; import java.util.List; @@ -269,6 +213,7 @@ public final class CorePlugin extends SonarPlugin { // widgets AlertsWidget.class, + QualityGateWidget.class, CoverageWidget.class, ItCoverageWidget.class, DescriptionWidget.class, diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/QualityGateWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/QualityGateWidget.java new file mode 100644 index 00000000000..dd7e1d0cf85 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/QualityGateWidget.java @@ -0,0 +1,33 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.plugins.core.widgets; + +import org.sonar.api.web.*; + +@WidgetProperties({ + @WidgetProperty(key = "show_ok", type = WidgetPropertyType.BOOLEAN, defaultValue = "false"), +}) +@WidgetLayout(WidgetLayoutType.NONE) +public class QualityGateWidget extends CoreWidget { + + public QualityGateWidget() { + super("quality_gate", "Quality Gate Details", "/org/sonar/plugins/core/widgets/quality_gate.html.erb"); + } +} diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/quality_gate.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/quality_gate.html.erb new file mode 100644 index 00000000000..af8143e1a58 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/quality_gate.html.erb @@ -0,0 +1,63 @@ +<% m=measure(Metric::QUALITY_GATE_DETAILS) + if m && !m.measure_data.blank? + + details = JSON.parse m.measure_data.data + m.alert_status = details['level'] + + warn_message = message('measure_filter.criteria.alert.warn') + error_message = message('measure_filter.criteria.alert.error') + + css_class = "color_#{m.alert_status}" + if m.alert_status==Metric::TYPE_LEVEL_OK + label = "<b>#{message('widget.alerts.no_alert')}.</b>" + elsif m.alert_status==Metric::TYPE_LEVEL_WARN + label = "<b>#{message('widget.alerts.warnings')}</b>" + else + label = "<b>#{message('widget.alerts.errors')}</b>" + end +-%><div class="widget <%= css_class -%>" id="quality_gate_widget_<%= widget.id -%>"> + <div><%= format_measure(m) -%> <%= label -%></div> + <table class="data" style="color: black; margin-top: 10px"> + <thead> + <tr></tr> + </thead> + <tbody> + <% details['conditions'].sort_by {|condition| [ -condition['level'].length, metric(condition['metric']).short_name] }.each do |condition| + + level = condition['level'] + condition_metric = metric(condition['metric']) + operator = message("quality_gates.operator.#{condition['op']}.short") + period = condition['period'] + warning_value = condition['warning'] + error_value = condition['error'] + actual_value = condition['actual'] + + detail_measure = ProjectMeasure.new :metric => m.metric, :alert_status => level + + drilldown_url = period.blank? ? url_for_drilldown(condition_metric) : url_for_drilldown(condition_metric, :period => period) + + actual_measure = ProjectMeasure.new :metric => condition_metric, :value => actual_value + warning_measure = ProjectMeasure.new :metric => condition_metric, :value => warning_value + error_measure = ProjectMeasure.new :metric => condition_metric, :value => error_value + + + unless level == 'OK' && !widget_properties['show_ok'] + -%> + <tr> + <td><%= format_measure(detail_measure) -%></td> + <td><%= link_to "#{condition_metric.short_name} #{period_label(@snapshot, period) unless period.blank?}", drilldown_url, {:class => 'nolink'} -%></td> + <td align="right"><%= link_to format_measure(actual_measure), drilldown_url, {:class => 'nolink'} -%></td> + <td> + <% if level == 'WARN' -%><%= operator -%> <%= format_measure(warning_measure) -%><% end -%> + <% if level == 'ERROR' -%><%= operator -%> <%= format_measure(error_measure) -%><% end -%> + <% if level == 'OK' -%> + <% unless warning_value.blank? -%><%= warn_message -%> <%= operator -%> <%= format_measure(warning_measure) -%> <%= '|' unless error_value.blank? -%><% end %> + <% unless error_value.blank? -%><%= error_message -%> <%= operator -%> <%= format_measure(error_measure) -%><% end %> + <% end -%> + </tr> + <% end + end -%> + </tbody> + </table> +</div> +<% end %> |