]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9666 Restore support of multi-valued properties containing line breaks
authorJulien HENRY <julien.henry@sonarsource.com>
Thu, 7 Sep 2017 14:29:42 +0000 (16:29 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Fri, 15 Sep 2017 06:51:08 +0000 (08:51 +0200)
sonar-scanner-engine/src/main/java/org/sonar/scanner/config/DefaultConfiguration.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/config/DefaultConfigurationTest.java

index 6433faa01f01404ad6634f0fc1667f3664e2fc2e..3a5e18f2e3fb049506d6d708daeb6c6b4763c3a9 100644 (file)
@@ -24,6 +24,7 @@ import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -116,19 +117,61 @@ public abstract class DefaultConfiguration implements Configuration {
     List<String> result = new ArrayList<>();
     try (CSVParser csvParser = CSVFormat.RFC4180
       .withHeader((String) null)
-      .withIgnoreSurroundingSpaces(true)
+      .withIgnoreEmptyLines()
+      .withIgnoreSurroundingSpaces()
       .parse(new StringReader(value))) {
       List<CSVRecord> records = csvParser.getRecords();
       if (records.isEmpty()) {
         return ArrayUtils.EMPTY_STRING_ARRAY;
       }
-      records.get(0).iterator().forEachRemaining(result::add);
+      processRecords(result, records);
       return result.toArray(new String[result.size()]);
     } catch (IOException e) {
       throw new IllegalStateException("Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'", e);
     }
   }
 
+  /**
+   * In most cases we expect a single record. <br>Having multiple records means the input value was splitted over multiple lines (this is common in Maven).
+   * For example:
+   * <pre>
+   *   &lt;sonar.exclusions&gt;
+   *     src/foo,
+   *     src/bar,
+   *     src/biz
+   *   &lt;sonar.exclusions&gt;
+   * </pre>
+   * In this case records will be merged to form a single list of items. Last item of a record is appended to first item of next record.
+   * <p>
+   * This is a very curious case, but we try to preserve line break in the middle of an item:
+   * <pre>
+   *   &lt;sonar.exclusions&gt;
+   *     a
+   *     b,
+   *     c
+   *   &lt;sonar.exclusions&gt;
+   * </pre>
+   * will produce ['a\nb', 'c']
+   */
+  private static void processRecords(List<String> result, List<CSVRecord> records) {
+    for (CSVRecord csvRecord : records) {
+      Iterator<String> it = csvRecord.iterator();
+      if (!result.isEmpty()) {
+        String next = it.next();
+        if (!next.isEmpty()) {
+          int lastItemIdx = result.size() - 1;
+          String previous = result.get(lastItemIdx);
+          if (previous.isEmpty()) {
+            result.set(lastItemIdx, next);
+          } else {
+            result.set(lastItemIdx, previous + "\n" + next);
+          }
+        }
+      }
+      it.forEachRemaining(result::add);
+    }
+  }
+
   private Optional<String> getInternal(String key) {
     if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) {
       throw MessageException.of("Access to the secured property '" + key
index adf55780f1d31000a792ff6088ecea0de5f433cd..f21b30a8ea5207760ade2c17c9b59e21117d48d9 100644 (file)
@@ -114,6 +114,12 @@ public class DefaultConfigurationTest {
     assertThat(getStringArray("a , b")).containsExactly("a", "b");
     assertThat(getStringArray("\"a \",\" b\"")).containsExactly("a ", " b");
     assertThat(getStringArray("\"a,b\",c")).containsExactly("a,b", "c");
+    assertThat(getStringArray("\"a\nb\",c")).containsExactly("a\nb", "c");
+    assertThat(getStringArray("\"a\",\n  b\n")).containsExactly("a", "b");
+    assertThat(getStringArray("a\n,b\n")).containsExactly("a", "b");
+    assertThat(getStringArray("a\n,,b\n")).containsExactly("a", "", "b");
+    assertThat(getStringArray("a,\n\nb,c")).containsExactly("a", "b", "c");
+    assertThat(getStringArray("a,b\n\nc,d")).containsExactly("a", "b\nc", "d");
     try {
       getStringArray("\"a ,b");
       fail("Expected exception");