From 90f65c869c857e5f548bc67ed779aeb465e2cb2f Mon Sep 17 00:00:00 2001 From: David Gageot Date: Fri, 21 Sep 2012 10:23:37 +0200 Subject: [PATCH] SONAR-3750 Add ability to share Exclusion rules between several projects --- .../org/sonar/plugins/core/CorePlugin.java | 8 ++ .../resources/org/sonar/l10n/core.properties | 77 ++++++++++++ .../java/org/sonar/api/CoreProperties.java | 8 ++ .../DefaultProjectFileSystemTest.java | 25 ++-- .../org/sonar/api/resources/ProjectTest.java | 2 +- .../app/controllers/project_controller.rb | 32 ----- .../app/views/layouts/_layout.html.erb | 7 +- .../app/views/project/exclusions.html.erb | 118 ------------------ 8 files changed, 108 insertions(+), 169 deletions(-) delete mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/project/exclusions.html.erb 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 af0279a478d..5fcbd453d73 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 @@ -130,6 +130,14 @@ import java.util.List; project = false, global = true, category = CoreProperties.CATEGORY_GENERAL), + @Property( + key = CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, + name = "Exclusions", + description = "Exclude sources from code analysis. Changes will be applied during next code analysis.", + project = true, + global = false, + multiValues = true, + category = CoreProperties.CATEGORY_EXCLUSIONS), @Property( key = CoreProperties.CORE_COVERAGE_PLUGIN_PROPERTY, defaultValue = "jacoco", diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index d684f7b7e59..4c32642d609 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -576,6 +576,83 @@ property.category.codeCoverage=Code Coverage property.category.duplications=Duplications property.category.localization=Localization property.category.server_id=Server ID +property.category.exclusions=Exclusions +property.sonar.exclusions.name=Exclusions +property.sonar.exclusions.description=Exclude sources from code analysis. Changes will be applied during next code analysis. +property.sonar.exclusions.help=

Wildcards

\ +

Following rules are applied:

\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
*Match zero or more characters
**Match zero or more directories
?Match a single character
\ +

Examples:

\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
FilterDescriptionMatches
org/mycompany/*.javamatches all .java files in the org/mycompany directory\ +
    \ +
  • org/mycompany/Foo.java
  • \ +
  • org/mycompany/Bar.java
  • \ +
\ +
org/*Model*.javamatches all .java files with Model in filename and in theorg directory\ +
    \ +
  • org/Model.java
  • \ +
  • org/FirstModel.java
  • \ +
  • org/ModelTest.java
  • \ +
\ +
org/**matches all files underneath the org directory\ +
    \ +
  • org/Foo.java
  • \ +
  • org/foo/bar.jsp
  • \ +
\ +
org/**/Dummy.javamatches all Dummy.java files underneath the org directory\ +
    \ +
  • org/Dummy.java
  • \ +
  • org/foo/Dummy.java
  • \ +
  • org/foo/bar/Dummy.java
  • \ +
\ +
org/**/*.javamatches all .java files underneath the org directory\ +
    \ +
  • org/Foo.java
  • \ +
  • org/foo/Bar.java
  • \ +
  • org/foo/bar/Baz.java
  • \ +
\ +
property.error.notBoolean=Valid options are "true" and "false" property.error.notInteger=Only digits are allowed diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index 17e0c48776e..b3b55b5ab03 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -67,6 +67,11 @@ public interface CoreProperties { */ String CATEGORY_DIFFERENTIAL_VIEWS = "differentialViews"; + /** + * @since 3.3 + */ + String CATEGORY_EXCLUSIONS = "exclusions"; + /* Global settings */ String SONAR_HOME = "SONAR_HOME"; String PROJECT_BRANCH_PROPERTY = "sonar.branch"; @@ -98,8 +103,11 @@ public interface CoreProperties { * Value format is yyyy-MM-dd */ String PROJECT_DATE_PROPERTY = "sonar.projectDate"; + String PROJECT_LANGUAGE_PROPERTY = "sonar.language"; String DYNAMIC_ANALYSIS_PROPERTY = "sonar.dynamicAnalysis"; + + /* Exclusions */ String PROJECT_EXCLUSIONS_PROPERTY = "sonar.exclusions"; /** diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java index f3cc76ba934..fd8f9304d53 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java @@ -19,14 +19,6 @@ */ package org.sonar.api.resources; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; @@ -37,6 +29,7 @@ import org.hamcrest.Matchers; import org.hamcrest.TypeSafeMatcher; import org.junit.Before; import org.junit.Test; +import org.sonar.api.CoreProperties; import org.sonar.api.batch.FileFilter; import org.sonar.api.test.MavenTestUtils; @@ -45,6 +38,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + public class DefaultProjectFileSystemTest { private Project project = null; @@ -81,7 +80,7 @@ public class DefaultProjectFileSystemTest { assertThat(fs.hasJavaSourceFiles(), is(true)); PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.exclusions", "**/*.java"); + conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*.java"); project.setConfiguration(conf); assertThat(fs.hasJavaSourceFiles(), is(false)); } @@ -97,7 +96,7 @@ public class DefaultProjectFileSystemTest { @Test public void applyExclusionPatternsToSourceFiles() { PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.exclusions", "**/B*.java"); + conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/B*.java"); project.setConfiguration(conf); final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project); @@ -112,7 +111,7 @@ public class DefaultProjectFileSystemTest { @Test public void exclusionPatternOnAjFiles() { PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.exclusions", "**/*.aj"); + conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*.aj"); project.setConfiguration(conf); final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project); @@ -125,7 +124,7 @@ public class DefaultProjectFileSystemTest { @Test public void doNotApplyExclusionPatternsToTestFiles() { PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.exclusions", "**/B*.java"); + conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/B*.java"); project.setConfiguration(conf); final DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project); @@ -220,7 +219,7 @@ public class DefaultProjectFileSystemTest { @Test public void testSelectiveFileFilter() { DefaultProjectFileSystem.FileSelectionFilter filter = new DefaultProjectFileSystem.FileSelectionFilter( - Arrays.asList(new File("foo/Bar.java"), new File("hello/Bar.java"), new File("hello/World.java"))); + Arrays.asList(new File("foo/Bar.java"), new File("hello/Bar.java"), new File("hello/World.java"))); assertThat(filter.accept(new File("foo/Bar.java")), Matchers.is(true)); assertThat(filter.accept(new File("hello/Bar.java")), Matchers.is(true)); assertThat(filter.accept(new File("hello/World.java")), Matchers.is(true)); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java index d88ea57e211..6bc15f8f79c 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java @@ -59,7 +59,7 @@ public class ProjectTest { @Test public void shouldTrimExclusionPatterns() { Configuration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.exclusions", " **/*Foo.java , **/Bar.java "); + conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, " **/*Foo.java , **/Bar.java "); Project project = new Project("foo").setConfiguration(conf); String[] exclusions = project.getExclusionPatterns(); diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb index 76918622d64..e4eb8537e9f 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb @@ -272,38 +272,6 @@ class ProjectController < ApplicationController render :action => 'events', :layout => !request.xhr? end - - def exclusions - @project = get_current_project(params[:id]) - - @snapshot=@project.last_snapshot - if !@project.project? && !@project.module? - redirect_to :action => 'index', :id => params[:id] - end - end - - def set_exclusions - @project = get_current_project(params[:id]) - - patterns=params['patterns'].reject { |p| p.blank? }.uniq - if patterns.empty? - Property.clear('sonar.exclusions', @project.id) - else - # Trim spaces in patterns before merging into one String - see http://jira.codehaus.org/browse/SONAR-2261 - Property.set('sonar.exclusions', patterns.collect { |x| x.strip }.join(','), @project.id) - end - flash[:notice]='Filters added' - redirect_to :action => 'exclusions', :id => @project.id - end - - def delete_exclusions - @project = get_current_project(params[:id]) - - Property.clear('sonar.exclusions', @project.id) - flash[:notice]='Filters deleted' - redirect_to :action => 'exclusions', :id => @project.id - end - def update_version snapshot=Snapshot.find(params[:sid]) not_found("Snapshot not found") unless snapshot diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 77295ad8bf2..f3c886790be 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -97,11 +97,8 @@ <% end %> <% if (@project.project? || @project.module?) %>
  • - <%= message('project_settings.page') -%>
  • - <% end %> - <% if (@project.project? || @project.module?) %> -
  • - <%= message('project_exclusions.page') -%>
  • + <%= message('project_settings.page') -%> + <% end %> <% if (@project.project?) %>
  • diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/exclusions.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/exclusions.html.erb deleted file mode 100644 index 8941c3fff64..00000000000 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/project/exclusions.html.erb +++ /dev/null @@ -1,118 +0,0 @@ -

    <%= message('project_exclusions.page') -%>

    - -

    - Exclude sources from code analysis. Changes will be applied during next code analysis. -

    - -
    - -
    - <% form_for( 'set_exclusions', :url => { :action => 'set_exclusions', :id => @project.id } ) do |form| - pattern_index=0 - %> - - <% patterns = Property.value('sonar.exclusions', @project.id, '').split(',') - patterns.each do |pattern| - %> - - - - <% pattern_index += 1 - end - %> - - - -
    - -
    - -
    -
    -
    - <%= submit_tag( "Save exclusion filters", :id => 'submit_exclusions') %> - @project.id -%>';f.submit(); };return false;"> -
    - <% end %> -
    - -
    -
    -

    Wildcards

    -

    - Following rules are applied: - - - - - - - - - - - - - - -
    *Match zero or more characters
    **Match zero or more directories
    ?Match a single character
    -

    -

    - Examples: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FilterDescriptionMatches
    org/mycompany/*.javamatches all .java files in the org/mycompany directory
      -
    • org/mycompany/Foo.java
    • -
    • org/mycompany/Bar.java
    • -
    org/*Model*.javamatches all .java files with Model in filename and in the org directory
      -
    • org/Model.java
    • -
    • org/FirstModel.java
    • -
    • org/ModelTest.java
    • -
    org/**matches all files underneath the org directory
      -
    • org/Foo.java
    • -
    • org/foo/bar.jsp
    • -
    org/**/Dummy.javamatches all Dummy.java files underneath the org directory
      -
    • org/Dummy.java
    • -
    • org/foo/Dummy.java
    • -
    • org/foo/bar/Dummy.java
    • -
    org/**/*.javamatches all .java files underneath the org directory
      -
    • org/Foo.java
    • -
    • org/foo/Bar.java
    • -
    • org/foo/bar/Baz.java
    • -
    -

    -
    -
    -
    -- 2.39.5