From: Julien HENRY Date: Mon, 13 Apr 2015 09:59:54 +0000 (+0200) Subject: Restore old behavior for InputFile::lines() -> returns 1 for empty files X-Git-Tag: 5.2-RC1~2303 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1434abc6dcf716a06267a109908c7dc920fad9c8;p=sonarqube.git Restore old behavior for InputFile::lines() -> returns 1 for empty files --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java b/sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java index 978dbdb9643..53950bec479 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/SourceDataFactory.java @@ -31,13 +31,12 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.utils.KeyValueFormat; import org.sonar.batch.duplication.DuplicationCache; -import org.sonar.batch.protocol.output.BatchReport; +import org.sonar.batch.protocol.output.*; import org.sonar.batch.protocol.output.BatchReport.Range; import org.sonar.batch.protocol.output.BatchReport.Scm; import org.sonar.batch.protocol.output.BatchReport.Scm.Changeset; import org.sonar.batch.protocol.output.BatchReport.Symbols; import org.sonar.batch.protocol.output.BatchReport.SyntaxHighlighting; -import org.sonar.batch.protocol.output.BatchReportReader; import org.sonar.batch.report.BatchReportUtils; import org.sonar.batch.report.ReportPublisher; import org.sonar.batch.scan.measure.MeasureCache; @@ -73,7 +72,9 @@ public class SourceDataFactory implements BatchComponent { public byte[] consolidateData(DefaultInputFile inputFile) throws IOException { FileSourceDb.Data.Builder dataBuilder = createForSource(inputFile); - applyLineMeasures(inputFile, dataBuilder); + if (!inputFile.isEmpty()) { + applyLineMeasures(inputFile, dataBuilder); + } applyScm(inputFile, dataBuilder); applyDuplications(inputFile.key(), dataBuilder); applyHighlighting(inputFile, dataBuilder); diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java index a55562c88f2..d1defb7b7ca 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/SourcePersister.java @@ -19,15 +19,14 @@ */ package org.sonar.batch.index; -import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.batch.fs.internal.FileMetadata.LineHashConsumer; - import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.FileMetadata; +import org.sonar.api.batch.fs.internal.FileMetadata.LineHashConsumer; import org.sonar.api.utils.System2; import org.sonar.batch.ProjectTree; import org.sonar.batch.scan.filesystem.InputPathCache; @@ -126,9 +125,6 @@ public class SourcePersister implements ScanPersister { @CheckForNull private String lineHashesAsMd5Hex(DefaultInputFile f) { - if (f.lines() == 0) { - return null; - } // A md5 string is 32 char long + '\n' = 33 final StringBuilder result = new StringBuilder(f.lines() * (32 + 1)); diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java index 644cf8bf724..e116bb80565 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java @@ -47,12 +47,12 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private final IssueExclusionsLoader issueExclusionsLoader; private final IssuesReports issuesReport; private final LocalIssueTracking localIssueTracking; - private final ReportPublisher publishReportJob; + private final ReportPublisher reportPublisher; public DatabaseLessPhaseExecutor(Phases phases, InitializersExecutor initializersExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext, DefaultIndex index, EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, - IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking, ReportPublisher publishReportJob) { + IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking, ReportPublisher reportPublisher) { this.phases = phases; this.initializersExecutor = initializersExecutor; this.sensorsExecutor = sensorsExecutor; @@ -66,7 +66,7 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { this.profileVerifier = profileVerifier; this.issueExclusionsLoader = issueExclusionsLoader; this.localIssueTracking = localIssueTracking; - this.publishReportJob = publishReportJob; + this.reportPublisher = reportPublisher; } /** @@ -106,7 +106,7 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private void publishReportJob() { String stepName = "Publish report"; eventBus.fireEvent(new BatchStepEvent(stepName, true)); - this.publishReportJob.execute(); + this.reportPublisher.execute(); eventBus.fireEvent(new BatchStepEvent(stepName, false)); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java index 657a58083f2..7d01ad44a3c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java @@ -49,7 +49,7 @@ public final class DatabaseModePhaseExecutor implements PhaseExecutor { private final PostJobsExecutor postJobsExecutor; private final InitializersExecutor initializersExecutor; private final SensorsExecutor sensorsExecutor; - private final ReportPublisher publishReportJob; + private final ReportPublisher reportPublisher; private final SensorContext sensorContext; private final DefaultIndex index; private final ProjectInitializer pi; @@ -66,7 +66,7 @@ public final class DatabaseModePhaseExecutor implements PhaseExecutor { public DatabaseModePhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext, DefaultIndex index, - EventBus eventBus, ReportPublisher publishReportJob, ProjectInitializer pi, + EventBus eventBus, ReportPublisher reportPublisher, ProjectInitializer pi, ScanPersister[] persisters, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, DefaultAnalysisMode analysisMode, DatabaseSession session, ResourcePersister resourcePersister) { this.phases = phases; @@ -77,7 +77,7 @@ public final class DatabaseModePhaseExecutor implements PhaseExecutor { this.sensorContext = sensorContext; this.index = index; this.eventBus = eventBus; - this.publishReportJob = publishReportJob; + this.reportPublisher = reportPublisher; this.pi = pi; this.persisters = persisters; this.fsLogger = fsLogger; @@ -168,7 +168,7 @@ public final class DatabaseModePhaseExecutor implements PhaseExecutor { private void publishReportJob() { String stepName = "Publish report"; eventBus.fireEvent(new BatchStepEvent(stepName, true)); - this.publishReportJob.execute(); + this.reportPublisher.execute(); eventBus.fireEvent(new BatchStepEvent(stepName, false)); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java index 941f7d42f61..51365f6d5c6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java @@ -106,7 +106,7 @@ public final class ScmSensor implements Sensor { } private void addIfNotEmpty(List filesToBlame, InputFile f) { - if (f.lines() > 0) { + if (!f.isEmpty()) { filesToBlame.add(f); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java index 62ea53ce6ae..ac5d983c1e9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/EmptyFileTest.java @@ -84,7 +84,7 @@ public class EmptyFileTest { .property("sonar.xoo.internalKey", "my/internal/key") .start(); - assertThat(result.issues()).hasSize(10); + assertThat(result.issues()).hasSize(11); } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java index 4e0af79ccc7..d98180bf417 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java @@ -105,11 +105,17 @@ public interface InputFile extends InputPath { Status status(); /** - * Number of physical lines. This method supports all end-of-line characters. Returns - * zero if the file is empty. + * Number of physical lines. This method supports all end-of-line characters. Formula is (number of line break + 1). Returns + * 1 if the file is empty.
Returns 2 for foo\nbar. Returns 3 for foo\nbar\n. */ int lines(); + /** + * Check if the file content is empty (ignore potential BOM). + * @since 5.2 + */ + boolean isEmpty(); + /** * Return a {@link TextPointer} in the given file. * @param line Line of the pointer. Start at 1. diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java index 4f89a1c0dd3..5190bb1a0f1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java @@ -104,6 +104,11 @@ public class DefaultInputFile implements InputFile { return lines; } + @Override + public boolean isEmpty() { + return lastValidOffset == 0; + } + /** * Component key. */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java index cb5ea5660af..fa894077be4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java @@ -66,7 +66,7 @@ public class FileMetadata implements BatchComponent { } private static class LineCounter extends CharHandler { - private int lines = 0; + private int lines = 1; private int nonBlankLines = 0; private boolean blankLine = true; boolean alreadyLoggedInvalidCharacter = false; @@ -80,9 +80,6 @@ public class FileMetadata implements BatchComponent { @Override protected void handleAll(char c) { - if (this.lines == 0) { - this.lines = 1; - } if (!alreadyLoggedInvalidCharacter && c == '\ufffd') { LOG.warn("Invalid character encountered in file {} at line {} for encoding {}. Please fix file content or configure the encoding to be used using property '{}'.", file, lines, encoding, CoreProperties.ENCODING_PROPERTY); @@ -156,19 +153,12 @@ public class FileMetadata implements BatchComponent { private final MessageDigest lineMd5Digest = DigestUtils.getMd5Digest(); private final StringBuilder sb = new StringBuilder(); private final LineHashConsumer consumer; - private int line = 0; + private int line = 1; public LineHashComputer(LineHashConsumer consumer) { this.consumer = consumer; } - @Override - protected void handleAll(char c) { - if (this.line == 0) { - this.line = 1; - } - } - @Override protected void handleIgnoreEoL(char c) { if (!Character.isWhitespace(c)) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java index 9e06a3e9e5c..e26451cf82d 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/FileMetadataTest.java @@ -56,7 +56,7 @@ public class FileMetadataTest { FileUtils.touch(tempFile); FileMetadata.Metadata metadata = new FileMetadata().readMetadata(tempFile, Charsets.UTF_8); - assertThat(metadata.lines).isEqualTo(0); + assertThat(metadata.lines).isEqualTo(1); assertThat(metadata.nonBlankLines).isEqualTo(0); assertThat(metadata.hash).isNotEmpty(); assertThat(metadata.originalLineOffsets).containsOnly(0); @@ -219,6 +219,8 @@ public class FileMetadataTest { case 3: assertThat(Hex.encodeHexString(hash)).isEqualTo(md5Hex("baz")); break; + default: + fail("Invalid line"); } } }); @@ -236,7 +238,13 @@ public class FileMetadataTest { @Override public void consume(int lineIdx, @Nullable byte[] hash) { - fail("File is empty and should not report any line hash"); + switch (lineIdx) { + case 1: + assertThat(hash).isNull(); + break; + default: + fail("Invalid line"); + } } }); }