aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2015-03-09 15:43:05 +0100
committerStas Vilchik <vilchiks@gmail.com>2015-03-09 15:43:05 +0100
commit0de35e885e368d4f8698fb76b8138c6bf2008026 (patch)
tree9ae9c42cf431b81e1c97bccfe012da098865c7fc
parentfb9f54a03332f1bdf5ffb08906e575f35a860a9c (diff)
parentb62e3e85e99579a4ef56e24331296122d28f68c7 (diff)
downloadsonarqube-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
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/size.html.erb4
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java26
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/extensions/XooProjectBuilder.java55
-rw-r--r--server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/Benchmark.java1
-rw-r--r--server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java2
-rw-r--r--server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceDbBenchmarkTest.java2
-rw-r--r--server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/SourceIndexBenchmarkTest.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcher.java (renamed from server/sonar-server/src/main/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcher.java)10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/notification/DoNotFixNotificationDispatcherTest.java (renamed from server/sonar-server/src/test/java/org/sonar/server/issue/notification/NewFalsePositiveNotificationDispatcherTest.java)71
-rw-r--r--server/sonar-web/src/main/hbs/coding-rules/coding-rules-workspace-list-item.hbs6
-rw-r--r--server/sonar-web/src/main/js/coding-rules/bulk-change-modal-view.js1
-rw-r--r--server/sonar-web/src/main/js/coding-rules/workspace-list-view.js27
-rw-r--r--server/sonar-web/src/main/less/components.less2
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/views/setup/form.html.erb2
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb26
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/540_create_activities_table.rb2
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb3
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/db/migrate/721_remove_sort_field_from_issue_filters.rb3
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java14
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/ProjectBuilderMediumTest.java144
-rw-r--r--sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java2
-rw-r--r--sonar-core/src/main/resources/org/sonar/l10n/core.properties8
-rw-r--r--sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java18
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>
&nbsp;&nbsp;&nbsp;
{{/notEq}}
- <a class="js-lang link-no-underline" data-lang="{{lang}}">{{langName}}</a>
+ <span class="note">{{langName}}</span>
{{#notEmpty tags}}
&nbsp;&nbsp;&nbsp;
<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);
}