From aa72980dbb78f9e9fdd0b75238e2182e008fcfbc Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 16 Apr 2014 15:42:16 +0600 Subject: [PATCH] Component Viewer: source code, coverage --- sonar-server/Gruntfile.coffee | 7 ++ .../main/coffee/component-viewer/app.coffee | 32 +++++++++ .../main/coffee/component-viewer/main.coffee | 67 +++++++++++++++++ .../coffee/component-viewer/source.coffee | 42 +++++++++++ .../src/main/hbs/component-viewer/layout.hbs | 1 + .../src/main/hbs/component-viewer/source.hbs | 20 ++++++ .../main/js/common/handlebars-extensions.js | 5 ++ .../src/main/less/component-viewer.less | 72 +++++++++++++++++++ .../src/main/less/navigator/config.less | 6 +- sonar-server/src/main/less/variables.less | 4 ++ .../component_viewer_controller.rb | 27 +++++++ .../app/views/component_viewer/index.html.erb | 3 + 12 files changed, 283 insertions(+), 3 deletions(-) create mode 100644 sonar-server/src/main/coffee/component-viewer/app.coffee create mode 100644 sonar-server/src/main/coffee/component-viewer/main.coffee create mode 100644 sonar-server/src/main/coffee/component-viewer/source.coffee create mode 100644 sonar-server/src/main/hbs/component-viewer/layout.hbs create mode 100644 sonar-server/src/main/hbs/component-viewer/source.hbs create mode 100644 sonar-server/src/main/less/component-viewer.less create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/controllers/component_viewer_controller.rb create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/component_viewer/index.html.erb diff --git a/sonar-server/Gruntfile.coffee b/sonar-server/Gruntfile.coffee index 88c18c56369..5a5d14c69b5 100644 --- a/sonar-server/Gruntfile.coffee +++ b/sonar-server/Gruntfile.coffee @@ -161,6 +161,10 @@ module.exports = (grunt) -> name: 'common/select-list' out: '<%= pkg.assets %>build/js/common/select-list.js' + componentViewer: options: + name: 'component-viewer/app' + out: '<%= pkg.assets %>build/js/component-viewer/app.js' + handlebars: options: @@ -184,6 +188,9 @@ module.exports = (grunt) -> '<%= pkg.assets %>js/templates/quality-gates.js': [ '<%= pkg.sources %>hbs/quality-gates/**/*.hbs' ] + '<%= pkg.assets %>js/templates/component-viewer.js': [ + '<%= pkg.sources %>hbs/component-viewer/**/*.hbs' + ] clean: diff --git a/sonar-server/src/main/coffee/component-viewer/app.coffee b/sonar-server/src/main/coffee/component-viewer/app.coffee new file mode 100644 index 00000000000..85ec0f9026d --- /dev/null +++ b/sonar-server/src/main/coffee/component-viewer/app.coffee @@ -0,0 +1,32 @@ +requirejs.config + baseUrl: "#{baseUrl}/js" + + paths: + 'backbone': 'third-party/backbone' + 'backbone.marionette': 'third-party/backbone.marionette' + 'handlebars': 'third-party/handlebars' + 'jquery.mockjax': 'third-party/jquery.mockjax' + + shim: + 'backbone.marionette': + deps: ['backbone'] + exports: 'Marionette' + 'backbone': + exports: 'Backbone' + 'handlebars': + exports: 'Handlebars' + + +requirejs [ + 'component-viewer/main', +], ( + ComponentViewer +) -> + + TEST_RESOURCE_KEY = 'org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/resources/ResourceTypeTree.java' + + + @componentViewer = new ComponentViewer() + @componentViewer.render().$el.appendTo '#body' + + @componentViewer.open TEST_RESOURCE_KEY \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/main.coffee b/sonar-server/src/main/coffee/component-viewer/main.coffee new file mode 100644 index 00000000000..e89ff2ac96f --- /dev/null +++ b/sonar-server/src/main/coffee/component-viewer/main.coffee @@ -0,0 +1,67 @@ +define [ + 'backbone' + 'backbone.marionette' + 'templates/component-viewer' + 'component-viewer/source' +], ( + Backbone + Marionette + Templates + SourceView +) -> + + $ = jQuery + API_SOURCES = "#{baseUrl}/api/sources" + API_RESOURCES = "#{baseUrl}/api/resources" + + + + class ComponentViewer extends Marionette.Layout + className: 'component-viewer' + template: Templates['layout'] + + + regions: + sourceRegion: '.component-viewer-source' + + + initialize: -> + @source = new Backbone.Model() + @sourceView = new SourceView model: @source + + + onRender: -> + @sourceRegion.show @sourceView + + + requestSource: (key) -> + $.get API_SOURCES, resource: key, (data) => + @source.set { source: data[0] }, { silent: true } + + + requestCoverage: (key) -> + metrics = 'coverage_line_hits_data,covered_conditions_by_line,conditions_by_line' + + toObj = (data) -> + q = {} + data.split(';').forEach (item) -> + tokens = item.split '=' + q[tokens[0]] = tokens[1] + q + + + $.get API_RESOURCES, resource: key, metrics: metrics, (data) => + msr = data[0].msr + coverage = toObj _.findWhere(msr, key: 'coverage_line_hits_data').data + coverageConditions = toObj _.findWhere(msr, key: 'covered_conditions_by_line').data + conditions = toObj _.findWhere(msr, key: 'conditions_by_line').data + @source.set { + coverage: coverage, + coverageConditions: coverageConditions + conditions: conditions + }, { silent: true } + + + open: (key) -> + $.when(@requestSource(key), @requestCoverage(key)).done => + @sourceView.render() \ No newline at end of file diff --git a/sonar-server/src/main/coffee/component-viewer/source.coffee b/sonar-server/src/main/coffee/component-viewer/source.coffee new file mode 100644 index 00000000000..b6c25ba860d --- /dev/null +++ b/sonar-server/src/main/coffee/component-viewer/source.coffee @@ -0,0 +1,42 @@ +define [ + 'backbone.marionette' + 'templates/component-viewer' + 'common/handlebars-extensions' +], ( + Marionette + Templates +) -> + + class SourceView extends Marionette.ItemView + template: Templates['source'] + + + modelEvents: + 'change': 'render' + + + serializeData: -> + source = @model.get 'source' + coverage = @model.get 'coverage' + coverageConditions = @model.get 'coverageConditions' + conditions = @model.get 'conditions' + source = _.map source, (code, line) -> + lineCoverage = coverage? && coverage[line]? && coverage[line] + lineCoverageConditions = coverageConditions? && coverageConditions[line]? && coverageConditions[line] + lineConditions = conditions? && conditions[line]? && conditions[line] + lineCoverageStatus = lineCoverage? && if lineCoverage > 0 then 'green' else 'red' + lineCoverageConditionsStatus = null + if lineCoverageConditions? && conditions? + lineCoverageConditionsStatus = 'red' if lineCoverageConditions == 0 + lineCoverageConditionsStatus = 'orange' if lineCoverageConditions > 0 && lineCoverageConditions < lineConditions + lineCoverageConditionsStatus = 'green' if lineCoverageConditions == lineConditions + + + lineNumber: line + code: code + coverage: lineCoverage + coverageStatus: lineCoverageStatus + coverageConditions: lineCoverageConditions + conditions: lineConditions + coverageConditionsStatus: lineCoverageConditionsStatus + source: source \ No newline at end of file diff --git a/sonar-server/src/main/hbs/component-viewer/layout.hbs b/sonar-server/src/main/hbs/component-viewer/layout.hbs new file mode 100644 index 00000000000..27a90824099 --- /dev/null +++ b/sonar-server/src/main/hbs/component-viewer/layout.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/sonar-server/src/main/hbs/component-viewer/source.hbs b/sonar-server/src/main/hbs/component-viewer/source.hbs new file mode 100644 index 00000000000..c473d5a10d2 --- /dev/null +++ b/sonar-server/src/main/hbs/component-viewer/source.hbs @@ -0,0 +1,20 @@ + + {{#each source}} + + + + + + + {{/each}} +
+ {{#if coverage}}{{coverage}}{{/if}} + + {{#if coverageConditions}} + {{#if conditions}} + + {{coverageConditions}}/{{conditions}} + + {{/if}} + {{/if}} + {{lineNumber}}
{{{code}}}
\ No newline at end of file diff --git a/sonar-server/src/main/js/common/handlebars-extensions.js b/sonar-server/src/main/js/common/handlebars-extensions.js index 47ff219f704..2a8f5747b50 100644 --- a/sonar-server/src/main/js/common/handlebars-extensions.js +++ b/sonar-server/src/main/js/common/handlebars-extensions.js @@ -144,6 +144,11 @@ define(['handlebars'], function (Handlebars) { }); Handlebars.registerHelper('sources', function(source, scm, options) { + if (options == null) { + options = scm; + scm = null; + } + var sources = _.map(source, function(code, line) { return { lineNumber: line, diff --git a/sonar-server/src/main/less/component-viewer.less b/sonar-server/src/main/less/component-viewer.less new file mode 100644 index 00000000000..7bfd425373f --- /dev/null +++ b/sonar-server/src/main/less/component-viewer.less @@ -0,0 +1,72 @@ +@import "variables"; +@import "mixins"; + + +.component-viewer { + width: 100%; + min-width: 600px; +} + + +.component-viewer-source { + + .sources2 td.line { + padding: 1px 5px; + + pre { + padding: 0; + font-family: 'inconsolata', monospace; + font-size: 13px; + } + } + + .sources2 td.lid { + padding: 1px 5px; + border-color: @barBorderColor; + background-color: @barBackgroundColor; + color: #888; + font-size: 11px; + } + + .sources2 td.coverage { + padding: 1px 5px; + background-color: @barBackgroundColor; + color: #fff; + + &.coverage-green { background-color: @green;} + &.coverage-red { background-color: @red; } + &.coverage-orange { background-color: @orange; } + } + + .sources2 .row:hover { + td.lid { background-color: darken(@barBackgroundColor, 5%); } + td.line { background-color: @barBackgroundColor; } + td.coverage { background-color: darken(@barBackgroundColor, 5%); } + td.coverage.coverage-green { background-color: darken(@green, 5%); } + td.coverage.coverage-red { background-color: darken(@red, 5%); } + td.coverage.coverage-orange { background-color: darken(@orange, 5%); } + } + +} + + +@font-face { + font-family: 'inconsolata-bold'; + src: url('../fonts/inconsolata-bold-webfont.woff') format('woff'), + url('../fonts/inconsolata-bold-webfont.svg#inconsolatabold') format('svg'); + font-weight: normal; + font-style: normal; + +} + + + + +@font-face { + font-family: 'inconsolata'; + src: url('../fonts/inconsolata-regular-webfont.woff') format('woff'), + url('../fonts/inconsolata-regular-webfont.svg#inconsolataregular') format('svg'); + font-weight: normal; + font-style: normal; + +} \ No newline at end of file diff --git a/sonar-server/src/main/less/navigator/config.less b/sonar-server/src/main/less/navigator/config.less index 4ad5424b817..805359a554d 100644 --- a/sonar-server/src/main/less/navigator/config.less +++ b/sonar-server/src/main/less/navigator/config.less @@ -18,9 +18,9 @@ // Colors -@navigatorBarBackground: #f3f3f3; -@navigatorBorderColor: darken(@navigatorBarBackground, 5%); -@navigatorBorderLightColor: @navigatorBorderColor; +@navigatorBarBackground: @barBackgroundColor; +@navigatorBorderColor: @barBorderColor; +@navigatorBorderLightColor: @barBorderColor; @navigatorHeaderColor: darken(@blue, 10%); diff --git a/sonar-server/src/main/less/variables.less b/sonar-server/src/main/less/variables.less index b1effcb9415..659091e4ba4 100644 --- a/sonar-server/src/main/less/variables.less +++ b/sonar-server/src/main/less/variables.less @@ -34,6 +34,10 @@ @contextBorder: lighten(@purple, 30%); +@barBackgroundColor: #f3f3f3; +@barBorderColor: darken(@barBackgroundColor, 5%); + + /* * Icons */ diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/component_viewer_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/component_viewer_controller.rb new file mode 100644 index 00000000000..fdff4bfdff5 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/component_viewer_controller.rb @@ -0,0 +1,27 @@ +# +# 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. +# + +class ComponentViewerController < ApplicationController + + def index + + end + +end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/component_viewer/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/component_viewer/index.html.erb new file mode 100644 index 00000000000..f5f2f0940a0 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/component_viewer/index.html.erb @@ -0,0 +1,3 @@ +<% content_for :script do %> + +<% end %> \ No newline at end of file -- 2.39.5