diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2015-03-09 15:43:05 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2015-03-09 15:43:05 +0100 |
commit | 0de35e885e368d4f8698fb76b8138c6bf2008026 (patch) | |
tree | 9ae9c42cf431b81e1c97bccfe012da098865c7fc | |
parent | fb9f54a03332f1bdf5ffb08906e575f35a860a9c (diff) | |
parent | b62e3e85e99579a4ef56e24331296122d28f68c7 (diff) | |
download | sonarqube-0de35e885e368d4f8698fb76b8138c6bf2008026.tar.gz sonarqube-0de35e885e368d4f8698fb76b8138c6bf2008026.zip |
Merge branch 'master' into branch-5.2
Conflicts:
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
server/sonar-web/src/main/less/components.less
25 files changed, 319 insertions, 121 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb index 9e0797f8005..7811e848f0d 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb @@ -50,7 +50,7 @@ <tr> <td> <% if language_key.eql? '<null>' %> - <%= message('other') -%> + <%= message('unknown') -%> <% else %> <% language = languages.find { |l| l.getKey()==language_key.to_s } -%> <%= language ? language.getName() : language_key -%> @@ -80,7 +80,7 @@ <% language_key = ncloc_language_dist_hash.first[0] if language_key.eql? '<null>' %> - <%= message('other') -%> + <%= message('unknown') -%> <% else %> <% language = languages.find { |l| l.getKey()==language_key.to_s } -%> <%= language ? language.getName() : language_key -%> diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index df3a7b5c64e..8aa011ef873 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -20,23 +20,9 @@ package org.sonar.xoo; import org.sonar.api.SonarPlugin; -import org.sonar.xoo.lang.DependencySensor; -import org.sonar.xoo.lang.MeasureSensor; -import org.sonar.xoo.lang.SymbolReferencesSensor; -import org.sonar.xoo.lang.SyntaxHighlightingSensor; -import org.sonar.xoo.lang.XooCpdMapping; -import org.sonar.xoo.lang.XooTokenizer; -import org.sonar.xoo.rule.ChecksSensor; -import org.sonar.xoo.rule.CreateIssueByInternalKeySensor; -import org.sonar.xoo.rule.DeprecatedResourceApiSensor; -import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; -import org.sonar.xoo.rule.OneIssuePerLineSensor; -import org.sonar.xoo.rule.RandomAccessSensor; -import org.sonar.xoo.rule.XooFakeExporter; -import org.sonar.xoo.rule.XooFakeImporter; -import org.sonar.xoo.rule.XooFakeImporterWithMessages; -import org.sonar.xoo.rule.XooQualityProfile; -import org.sonar.xoo.rule.XooRulesDefinition; +import org.sonar.xoo.extensions.XooProjectBuilder; +import org.sonar.xoo.lang.*; +import org.sonar.xoo.rule.*; import org.sonar.xoo.scm.XooBlameCommand; import org.sonar.xoo.scm.XooScmProvider; @@ -81,7 +67,9 @@ public class XooPlugin extends SonarPlugin { OneIssuePerLineSensor.class, OneIssueOnDirPerFileSensor.class, - CreateIssueByInternalKeySensor.class - ); + CreateIssueByInternalKeySensor.class, + + // Other + XooProjectBuilder.class); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooProjectBuilder.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooProjectBuilder.java new file mode 100644 index 00000000000..0ec5bcd0f1e --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooProjectBuilder.java @@ -0,0 +1,55 @@ +/* + * 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.xoo.extensions; + +import org.sonar.api.batch.bootstrap.ProjectBuilder; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.config.Settings; + +import java.io.File; + +public class XooProjectBuilder extends ProjectBuilder { + + private Settings settings; + + public XooProjectBuilder(Settings settings) { + this.settings = settings; + } + + @Override + public void build(Context context) { + if (!settings.getBoolean("sonar.xoo.enableProjectBuilder")) { + return; + } + ProjectDefinition root = context.projectReactor().getRoot(); + + ProjectDefinition module = ProjectDefinition.create() + .setKey(root.getKey() + ":module1") + .setName("Module 1"); + + module.setBaseDir(new File(root.getBaseDir(), "module1")); + module.setWorkDir(new File(root.getWorkDir(), "module1")); + + module.setSources("src"); + + root.addSubProject(module); + } + +} diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/Benchmark.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/Benchmark.java index a6003b576b0..e4d7e7fa670 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/Benchmark.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/Benchmark.java @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; public class Benchmark extends ErrorCollector { private static final boolean ENABLED = "true".equals(System.getProperty("enableBenchmarkAssertions")); + public static final double DEFAULT_ERROR_MARGIN_PERCENTS = 0.08; static { if (ENABLED) { diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java index ba5a6aa4d9c..8abfd3d18d7 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java @@ -112,7 +112,7 @@ public class IssueIndexBenchmarkTest { long period = System.currentTimeMillis() - start; long throughputPerSecond = 1000 * issues.count.get() / period; LOGGER.info(String.format("%d issues indexed in %d ms (%d docs/second)", issues.count.get(), period, throughputPerSecond)); - benchmark.expectAround("Throughput to index issues", throughputPerSecond, 3400, 0.06); + benchmark.expectAround("Throughput to index issues", throughputPerSecond, 3400, Benchmark.DEFAULT_ERROR_MARGIN_PERCENTS); // be sure that physical files do not evolve during estimation of size tester.get(EsClient.class).prepareOptimize("issues").get(); diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceDbBenchmarkTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceDbBenchmarkTest.java index 479408f6745..73179f4fefa 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceDbBenchmarkTest.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceDbBenchmarkTest.java @@ -84,7 +84,7 @@ public class SourceDbBenchmarkTest { long period = end - start; long throughputPerSecond = 1000L * counter.get() / period; LOGGER.info(String.format("%d FILE_SOURCES rows scrolled in %d ms (%d rows/second)", counter.get(), period, throughputPerSecond)); - benchmark.expectAround("Throughput to scroll FILE_SOURCES", throughputPerSecond, 120, 0.08); + benchmark.expectAround("Throughput to scroll FILE_SOURCES", throughputPerSecond, 120, Benchmark.DEFAULT_ERROR_MARGIN_PERCENTS); } finally { DbUtils.closeQuietly(connection); diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceIndexBenchmarkTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceIndexBenchmarkTest.java index 6480c4ef0df..a5751ae8cb3 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceIndexBenchmarkTest.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceIndexBenchmarkTest.java @@ -88,7 +88,7 @@ public class SourceIndexBenchmarkTest { long nbLines = files.count.get() * LINES_PER_FILE; long throughputPerSecond = 1000L * nbLines / period; LOGGER.info(String.format("%d lines indexed in %d ms (%d docs/second)", nbLines, period, throughputPerSecond)); - benchmark.expectAround("Throughput to index source lines", throughputPerSecond, 7800, 0.04); + benchmark.expectAround("Throughput to index source lines", throughputPerSecond, 7800, Benchmark.DEFAULT_ERROR_MARGIN_PERCENTS); // be sure that physical files do not evolve during estimation of size tester.get(EsClient.class).prepareOptimize(SourceLineIndexDefinition.INDEX).get(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcher.java b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcher.java index be916cfdd42..16b3de6fc05 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcher.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcher.java @@ -29,17 +29,15 @@ import java.util.Collection; import java.util.Map; /** - * This dispatcher means: "notify me when someone resolves an issue as false positive". - * - * @since 3.6 + * This dispatcher means: "notify me when an issue is resolved as false positive or won't fix". */ -public class NewFalsePositiveNotificationDispatcher extends NotificationDispatcher { +public class DoNotFixNotificationDispatcher extends NotificationDispatcher { public static final String KEY = "NewFalsePositiveIssue"; private final NotificationManager notifications; - public NewFalsePositiveNotificationDispatcher(NotificationManager notifications) { + public DoNotFixNotificationDispatcher(NotificationManager notifications) { super(IssueChangeNotification.TYPE); this.notifications = notifications; } @@ -58,7 +56,7 @@ public class NewFalsePositiveNotificationDispatcher extends NotificationDispatch @Override public void dispatch(Notification notification, Context context) { String newResolution = notification.getFieldValue("new.resolution"); - if (Objects.equal(newResolution, Issue.RESOLUTION_FALSE_POSITIVE)) { + if (Objects.equal(newResolution, Issue.RESOLUTION_FALSE_POSITIVE) || Objects.equal(newResolution, Issue.RESOLUTION_WONT_FIX)) { String author = notification.getFieldValue("changeAuthor"); String projectKey = notification.getFieldValue("projectKey"); Multimap<String, NotificationChannel> subscribedRecipients = notifications.findNotificationSubscribers(this, projectKey); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcherTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcherTest.java index ac434d62372..0bc96d60002 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcherTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcherTest.java @@ -21,44 +21,29 @@ package org.sonar.server.issue.notification; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; -import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.api.notifications.*; +import org.sonar.api.issue.Issue; +import org.sonar.api.notifications.Notification; +import org.sonar.api.notifications.NotificationChannel; +import org.sonar.api.notifications.NotificationDispatcher; +import org.sonar.api.notifications.NotificationDispatcherMetadata; +import org.sonar.api.notifications.NotificationManager; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) -public class NewFalsePositiveNotificationDispatcherTest { - @Mock - NotificationManager notifications; - - @Mock - NotificationDispatcher.Context context; - - @Mock - NotificationChannel emailChannel; - - @Mock - NotificationChannel twitterChannel; - - NewFalsePositiveNotificationDispatcher dispatcher; - - @Before - public void setUp() { - dispatcher = new NewFalsePositiveNotificationDispatcher(notifications); - } +public class DoNotFixNotificationDispatcherTest { + NotificationManager notifications = mock(NotificationManager.class); + NotificationDispatcher.Context context = mock(NotificationDispatcher.Context.class); + NotificationChannel emailChannel = mock(NotificationChannel.class); + NotificationChannel twitterChannel = mock(NotificationChannel.class); + DoNotFixNotificationDispatcher sut = new DoNotFixNotificationDispatcher(notifications);; @Test public void test_metadata() throws Exception { - NotificationDispatcherMetadata metadata = NewFalsePositiveNotificationDispatcher.newMetadata(); - assertThat(metadata.getDispatcherKey()).isEqualTo(dispatcher.getKey()); + NotificationDispatcherMetadata metadata = DoNotFixNotificationDispatcher.newMetadata(); + assertThat(metadata.getDispatcherKey()).isEqualTo(sut.getKey()); assertThat(metadata.getProperty(NotificationDispatcherMetadata.GLOBAL_NOTIFICATION)).isEqualTo("true"); assertThat(metadata.getProperty(NotificationDispatcherMetadata.PER_PROJECT_NOTIFICATION)).isEqualTo("true"); } @@ -66,7 +51,7 @@ public class NewFalsePositiveNotificationDispatcherTest { @Test public void should_not_dispatch_if_other_notification_type() throws Exception { Notification notification = new Notification("other"); - dispatcher.performDispatch(notification, context); + sut.performDispatch(notification, context); verify(context, never()).addUser(any(String.class), any(NotificationChannel.class)); } @@ -77,13 +62,13 @@ public class NewFalsePositiveNotificationDispatcherTest { recipients.put("simon", emailChannel); recipients.put("freddy", twitterChannel); recipients.put("godin", twitterChannel); - when(notifications.findNotificationSubscribers(dispatcher, "struts")).thenReturn(recipients); + when(notifications.findNotificationSubscribers(sut, "struts")).thenReturn(recipients); - Notification notification = new IssueChangeNotification().setFieldValue("projectKey", "struts") + Notification fpNotif = new IssueChangeNotification().setFieldValue("projectKey", "struts") .setFieldValue("changeAuthor", "godin") - .setFieldValue("new.resolution", "FALSE-POSITIVE") + .setFieldValue("new.resolution", Issue.RESOLUTION_FALSE_POSITIVE) .setFieldValue("assignee", "freddy"); - dispatcher.performDispatch(notification, context); + sut.performDispatch(fpNotif, context); verify(context).addUser("simon", emailChannel); verify(context).addUser("freddy", twitterChannel); @@ -92,4 +77,22 @@ public class NewFalsePositiveNotificationDispatcherTest { verifyNoMoreInteractions(context); } + /** + * Only false positive and won't fix resolutions + */ + @Test + public void ignore_other_resolutions() { + Multimap<String, NotificationChannel> recipients = HashMultimap.create(); + recipients.put("simon", emailChannel); + recipients.put("freddy", twitterChannel); + when(notifications.findNotificationSubscribers(sut, "struts")).thenReturn(recipients); + + Notification fixedNotif = new IssueChangeNotification().setFieldValue("projectKey", "struts") + .setFieldValue("changeAuthor", "godin") + .setFieldValue("new.resolution", Issue.RESOLUTION_FIXED) + .setFieldValue("assignee", "freddy"); + sut.performDispatch(fixedNotif, context); + + verifyZeroInteractions(context); + } } diff --git a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-list-item.hbs b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-list-item.hbs index 75f4c415e31..b7202d164c7 100644 --- a/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-list-item.hbs +++ b/server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-list-item.hbs @@ -26,13 +26,11 @@ <span class="text-danger">{{status}}</span> {{/notEq}} - <a class="js-lang link-no-underline" data-lang="{{lang}}">{{langName}}</a> + <span class="note">{{langName}}</span> {{#notEmpty tags}} <i class="icon-tags"></i> - {{#each tags}} - <a class="js-tag link-no-underline" data-tag="{{this}}">{{this}}</a> - {{/each}} + <span class="note">{{join tags ', '}}</span> {{/notEmpty}} </div> </td> diff --git a/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js index fb6051e7a4f..e6fd7fd33c6 100644 --- a/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js +++ b/server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js @@ -82,6 +82,7 @@ define([ looper.done(function () { that.options.app.controller.fetchList(); that.$(that.ui.codingRulesSubmitBulkChange.selector).hide(); + that.$('.modal-field').hide(); that.$('.js-modal-close').focus(); }); }, diff --git a/server/sonar-web/src/main/js/coding-rules/workspace-list-view.js b/server/sonar-web/src/main/js/coding-rules/workspace-list-view.js index b9fe6643b67..da435074b7f 100644 --- a/server/sonar-web/src/main/js/coding-rules/workspace-list-view.js +++ b/server/sonar-web/src/main/js/coding-rules/workspace-list-view.js @@ -24,21 +24,12 @@ define([ 'templates/coding-rules' ], function (WorkspaceListView, WorkspaceListItemView, WorkspaceListEmptyView) { - var $ = jQuery; - return WorkspaceListView.extend({ template: Templates['coding-rules-workspace-list'], itemView: WorkspaceListItemView, itemViewContainer: '.js-list', emptyView: WorkspaceListEmptyView, - events: function () { - return { - 'click .js-tag': 'onTagClick', - 'click .js-lang': 'onLangClick' - }; - }, - bindShortcuts: function () { WorkspaceListView.prototype.bindShortcuts.apply(this, arguments); var that = this; @@ -46,24 +37,6 @@ define([ that.options.app.controller.showDetailsForSelected(); return false; }); - }, - - onTagClick: function (e) { - var tag = $(e.currentTarget).data('tag'); - this.selectTag(tag); - }, - - onLangClick: function (e) { - var lang = $(e.currentTarget).data('lang'); - this.selectLang(lang); - }, - - selectTag: function (tag) { - this.options.app.state.setQuery({ tags: tag }); - }, - - selectLang: function (lang) { - this.options.app.state.setQuery({ languages: lang }); } }); diff --git a/server/sonar-web/src/main/less/components.less b/server/sonar-web/src/main/less/components.less index 4abb2aff28d..d0747ada542 100644 --- a/server/sonar-web/src/main/less/components.less +++ b/server/sonar-web/src/main/less/components.less @@ -19,6 +19,7 @@ */ @import "components/ui"; @import "components/source"; +@import "components/bubble-popup"; @import "components/modals"; @import "components/messages"; @import "components/issues"; @@ -36,7 +37,6 @@ @import "components/select-list"; @import "components/login"; @import "components/graphics"; -@import "components/bubble-popup"; @import "components/list-groups"; @import "components/panels"; @import "components/badges"; diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/form.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/form.html.erb index 6ab9699ff01..69a41abb6ac 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/form.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/form.html.erb @@ -5,7 +5,7 @@ <h3>Important</h3> <ul> <li>The database upgrade can take several minutes.</li> - <li>It is recommended to <b>back up database</b> before upgrading.</li> + <li>It is mandatory to <b>back up database</b> before upgrading.</li> <li><b>Copy the directory /extensions</b> from previous version before upgrading.</li> </ul> <br/> diff --git a/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb index 62d3e809416..3e0fed42893 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb @@ -116,13 +116,31 @@ class ActiveRecord::Migration ActiveRecord::Base.configurations[ENV['RAILS_ENV']]['dialect'] end + def self.column_exists?(table_name, column_name) + columns(table_name).any?{ |c| c.name == column_name.to_s } + end + def self.add_index(table_name, column_name, options = {}) # ActiveRecord can generate index names longer than 30 characters, but that's # not supported by Oracle, the "Enterprise" database. # For this reason we force to set name of indexes. raise ArgumentError, 'Missing index name' unless options[:name] - super(table_name, column_name, options) + unless index_exists?(table_name, column_name, :name => options[:name]) + super(table_name, column_name, options) + end + end + + def self.remove_column(table_name, column_name) + if column_exists?(table_name, column_name) + super(table_name, column_name) + end + end + + def self.add_column(table_name, column_name, type, options = {}) + unless column_exists?(table_name, column_name) + super(table_name, column_name, type, options) + end end def self.add_varchar_index(table_name, column_name, options = {}) @@ -173,8 +191,10 @@ class ActiveRecord::Migration # Oracle constraint (see names of triggers and indices) raise ArgumentError, "Table name is too long: #{table_name}" if table_name.to_s.length>25 - super(table_name, options) - create_id_trigger(table_name) if dialect()=='oracle' && options[:id] != false + unless table_exists?(table_name) + super(table_name, options) + create_id_trigger(table_name) if dialect()=='oracle' && options[:id] != false + end end def drop_table(table_name, options = {}) diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/540_create_activities_table.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/540_create_activities_table.rb index 590dbac61b1..9402c05c765 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/540_create_activities_table.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/540_create_activities_table.rb @@ -24,7 +24,7 @@ # class CreateActivitiesTable < ActiveRecord::Migration def self.up - create_table 'activities'do |t| + create_table 'activities' do |t| t.column 'created_at', :datetime, :null => false t.column 'user_login', :string, :limit => 255 t.column 'data_field', :text diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb index bf0288c7f12..8ccb228a7df 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb @@ -18,6 +18,9 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +# +# SonarQube 5.0 +# class AddIssueLongDates < ActiveRecord::Migration def self.up diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb index e81c5659a0b..1e2cce5f22d 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb @@ -18,6 +18,9 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +# +# SonarQube 5.0 +# class RenameIssueLongDates < ActiveRecord::Migration def self.up diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/721_remove_sort_field_from_issue_filters.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/721_remove_sort_field_from_issue_filters.rb index 8978b97225c..262b9fd2c2f 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/721_remove_sort_field_from_issue_filters.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/721_remove_sort_field_from_issue_filters.rb @@ -18,6 +18,9 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +# +# SonarQube 5.0 +# class RemoveSortFieldFromIssueFilters < ActiveRecord::Migration def self.up diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java index 851417e7705..fd1020ef74f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java @@ -39,7 +39,7 @@ public class ModuleSettings extends Settings { private final ProjectRepositories projectReferentials; private DefaultAnalysisMode analysisMode; - public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition project, ProjectRepositories projectReferentials, + public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition moduleDefinition, ProjectRepositories projectReferentials, DefaultAnalysisMode analysisMode) { super(batchSettings.getDefinitions()); this.projectReferentials = projectReferentials; @@ -47,18 +47,18 @@ public class ModuleSettings extends Settings { getEncryption().setPathToSecretKey(batchSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); LoggerFactory.getLogger(ModuleSettings.class).info("Load module settings"); - init(project, batchSettings); + init(moduleDefinition, batchSettings); } - private ModuleSettings init(ProjectDefinition project, GlobalSettings batchSettings) { - addProjectProperties(project, batchSettings); - addBuildProperties(project); + private ModuleSettings init(ProjectDefinition moduleDefinition, GlobalSettings batchSettings) { + addProjectProperties(moduleDefinition, batchSettings); + addBuildProperties(moduleDefinition); return this; } - private void addProjectProperties(ProjectDefinition project, GlobalSettings batchSettings) { + private void addProjectProperties(ProjectDefinition moduleDefinition, GlobalSettings batchSettings) { addProperties(batchSettings.getProperties()); - addProperties(projectReferentials.settings(project.getKeyWithBranch())); + addProperties(projectReferentials.settings(moduleDefinition.getKeyWithBranch())); } private void addBuildProperties(ProjectDefinition project) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java new file mode 100644 index 00000000000..05c1efa99de --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java @@ -0,0 +1,144 @@ +/* + * 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.batch.mediumtest.fs; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.CoreProperties; +import org.sonar.batch.mediumtest.BatchMediumTester; +import org.sonar.batch.mediumtest.TaskResult; +import org.sonar.batch.protocol.input.ActiveRule; +import org.sonar.xoo.XooPlugin; + +import java.io.File; +import java.io.IOException; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ProjectBuilderMediumTest { + + @org.junit.Rule + public TemporaryFolder temp = new TemporaryFolder(); + + public BatchMediumTester tester = BatchMediumTester.builder() + .registerPlugin("xoo", new XooPlugin()) + .addDefaultQProfile("xoo", "Sonar Way") + .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)) + .setPreviousAnalysisDate(new Date()) + .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) + .build(); + + @Before + public void prepare() { + tester.start(); + } + + @After + public void stop() { + tester.stop(); + } + + @Test + public void testProjectBuilder() throws IOException { + + File baseDir = temp.newFolder(); + File module1Dir = new File(baseDir, "module1"); + module1Dir.mkdir(); + + File srcDir = new File(module1Dir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10"); + + TaskResult result = tester.newTask() + .properties(ImmutableMap.<String, String>builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project") + .put("sonar.sources", ".") + .put("sonar.xoo.enableProjectBuilder", "true") + .build()) + .start(); + + assertThat(result.issues()).hasSize(10); + + boolean foundIssueAtLine1 = false; + for (org.sonar.api.issue.Issue issue : result.issues()) { + if (issue.line() == 1) { + foundIssueAtLine1 = true; + assertThat(issue.componentKey()).isEqualTo("com.foo.project:module1:src/sample.xoo"); + assertThat(issue.message()).isEqualTo("This issue is generated on each line"); + assertThat(issue.effortToFix()).isNull(); + } + } + assertThat(foundIssueAtLine1).isTrue(); + } + + @Test + public void testProjectBuilderWithBranch() throws IOException { + + File baseDir = temp.newFolder(); + File module1Dir = new File(baseDir, "module1"); + module1Dir.mkdir(); + + File srcDir = new File(module1Dir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10"); + + TaskResult result = tester.newTask() + .properties(ImmutableMap.<String, String>builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project") + .put("sonar.branch", "my-branch") + .put("sonar.sources", ".") + .put("sonar.xoo.enableProjectBuilder", "true") + .build()) + .start(); + + assertThat(result.issues()).hasSize(10); + + boolean foundIssueAtLine1 = false; + for (org.sonar.api.issue.Issue issue : result.issues()) { + if (issue.line() == 1) { + foundIssueAtLine1 = true; + assertThat(issue.componentKey()).isEqualTo("com.foo.project:module1:my-branch:src/sample.xoo"); + assertThat(issue.message()).isEqualTo("This issue is generated on each line"); + assertThat(issue.effortToFix()).isNull(); + } + } + assertThat(foundIssueAtLine1).isTrue(); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java index 3d635b3f207..3daafb4af1d 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java +++ b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java @@ -55,7 +55,7 @@ public class CorePropertyDefinitions { PropertyDefinition.builder("sonar.lf.logoWidthPx") .deprecatedKey("sonar.branding.image.width") .name("Width of image in pixels") - .description("Width in pixels, according that the height of image is constrained to 30px.") + .description("Width in pixels, given that the height of the the image is constrained to 30px") .category(CoreProperties.CATEGORY_GENERAL) .subCategory(CoreProperties.SUBCATEGORY_LOOKNFEEL) .build(), diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 13e651e836c..d979e3fc24e 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -105,7 +105,6 @@ open_verb=Open operations=Operations optional=Optional order=Order -other=Other owner=Owner package=Package packages=Packages @@ -164,6 +163,7 @@ type=Type unfollow=Unfollow unit_test=Unit test unit_tests=Unit tests +unknown=Unknown unresolved=Unresolved unselect_all=Unselect all unselect_verb=Unselect @@ -1073,8 +1073,8 @@ shortcuts.section.issue.comment=comment issue shortcuts.section.issue.change_tags=change tags of issue shortcuts.section.rules=Rules Page -shortcuts.section.rules.navigate_between_rules=navigate between items in a list -shortcuts.section.rules.open_details=go from the list of items to the rule details +shortcuts.section.rules.navigate_between_rules=navigate between rules +shortcuts.section.rules.open_details=go from the list of rules to the rule details shortcuts.section.rules.return_to_list=return back to the list @@ -2038,7 +2038,7 @@ notification.dispatcher.information=Subscribe to following channels to be notifi notification.dispatcher.ChangesOnMyIssue=Changes in issues assigned to me or reported by me notification.dispatcher.NewIssues=New issues notification.dispatcher.NewAlerts=New quality gate status -notification.dispatcher.NewFalsePositiveIssue=New false positives +notification.dispatcher.NewFalsePositiveIssue=Issues resolved as false positive or won't fix #------------------------------------------------------------------------------ diff --git a/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java b/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java index b859c92bc86..d787b0e6983 100644 --- a/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java +++ b/sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java @@ -72,7 +72,7 @@ public class DefaultI18nTest { // Only in english assertThat(manager.getPropertyKeys().contains("assignee")).isTrue(); assertThat(manager.getPropertyKeys().contains("sqale.page")).isTrue(); - assertThat(manager.getPropertyKeys().contains("unknown")).isFalse(); + assertThat(manager.getPropertyKeys().contains("bla_bla_bla")).isFalse(); } @Test @@ -124,8 +124,8 @@ public class DefaultI18nTest { @Test public void return_default_value_if_missing_key() { - assertThat(manager.message(Locale.ENGLISH, "unknown", "default")).isEqualTo("default"); - assertThat(manager.message(Locale.FRENCH, "unknown", "default")).isEqualTo("default"); + assertThat(manager.message(Locale.ENGLISH, "bla_bla_bla", "default")).isEqualTo("default"); + assertThat(manager.message(Locale.FRENCH, "bla_bla_bla", "default")).isEqualTo("default"); } @Test diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java index 4822a4a89aa..20874e5553d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java @@ -28,11 +28,8 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Properties; /** * Defines project metadata (key, name, source directories, ...). It's generally used by the @@ -204,7 +201,7 @@ public class ProjectDefinition { * @since 4.5 */ public String getKeyWithBranch() { - String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY); + String branch = getBranch(); String projectKey = getKey(); if (StringUtils.isNotBlank(branch)) { projectKey = String.format("%s:%s", projectKey, branch); @@ -212,6 +209,17 @@ public class ProjectDefinition { return projectKey; } + @CheckForNull + private String getBranch() { + String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY); + if (StringUtils.isNotBlank(branch)) { + return branch; + } else if (getParent() != null) { + return getParent().getBranch(); + } + return null; + } + public String getVersion() { return properties.get(CoreProperties.PROJECT_VERSION_PROPERTY); } |