From 0417484bef1e4bfefbe7dc8a7a5c9a1a105697af Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Fri, 18 Mar 2016 17:17:47 +0100 Subject: [PATCH] SONAR-6941 Partition files of scanner report in different folders --- .../protocol/output/FileStructure.java | 28 ++++++++++++++++++- .../protocol/output/FileStructureTest.java | 8 +++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/FileStructure.java b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/FileStructure.java index c4d3197cb43..551ed3ea4dc 100644 --- a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/FileStructure.java +++ b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/FileStructure.java @@ -20,6 +20,10 @@ package org.sonar.scanner.protocol.output; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; /** * Structure of files in the zipped report @@ -71,8 +75,30 @@ public class FileStructure { return new File(dir, "activerules.pb"); } + /** + * Too many files in the same folder is a problem. We need to partition the report + * by putting component specific files in subdirectories. + * The partitionning algorithm is very basic: + * - Breadth-first to not generate deep folder for small projects + * - easy to understand + */ + public static Path getSubDirFor(int componentRef) { + String componentRefAsStr = String.valueOf(componentRef); + Path result = Paths.get(""); + for (char c : componentRefAsStr.toCharArray()) { + result = result.resolve(String.valueOf(c)); + } + return result; + } + public File fileFor(Domain domain, int componentRef) { - return new File(dir, domain.filePrefix + componentRef + domain.fileSuffix); + Path parent = dir.toPath().resolve(getSubDirFor(componentRef)); + try { + Files.createDirectories(parent); + } catch (IOException e) { + throw new IllegalStateException("Unable to create subdirectory for component " + componentRef, e); + } + return parent.resolve(domain.filePrefix + componentRef + domain.fileSuffix).toFile(); } } diff --git a/sonar-scanner-protocol/src/test/java/org/sonar/scanner/protocol/output/FileStructureTest.java b/sonar-scanner-protocol/src/test/java/org/sonar/scanner/protocol/output/FileStructureTest.java index 69d5266cf50..2a0890bace8 100644 --- a/sonar-scanner-protocol/src/test/java/org/sonar/scanner/protocol/output/FileStructureTest.java +++ b/sonar-scanner-protocol/src/test/java/org/sonar/scanner/protocol/output/FileStructureTest.java @@ -19,12 +19,11 @@ */ package org.sonar.scanner.protocol.output; +import java.io.File; import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.scanner.protocol.output.FileStructure; -import java.io.File; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -62,8 +61,8 @@ public class FileStructureTest { public void locate_files() throws Exception { File dir = temp.newFolder(); FileUtils.write(new File(dir, "metadata.pb"), "metadata content"); - FileUtils.write(new File(dir, "issues-3.pb"), "issues of component 3"); - FileUtils.write(new File(dir, "component-42.pb"), "details of component 42"); + FileUtils.write(new File(dir, "3/issues-3.pb"), "issues of component 3"); + FileUtils.write(new File(dir, "4/2/component-42.pb"), "details of component 42"); FileStructure structure = new FileStructure(dir); assertThat(structure.metadataFile()).exists().isFile(); @@ -71,4 +70,5 @@ public class FileStructureTest { assertThat(structure.fileFor(FileStructure.Domain.ISSUES, 3)).exists().isFile(); assertThat(structure.fileFor(FileStructure.Domain.ISSUES, 42)).doesNotExist(); } + } -- 2.39.5