Skip to content

Commit

Permalink
SONAR-5077 Special case of empty files
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed Jan 20, 2015
1 parent 143fa80 commit 9030b56
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 12 deletions.
Expand Up @@ -47,6 +47,7 @@ public void put(Value value, Object object, CoderContext context) {
putUTFOrNull(value, f.hash());
value.put(f.lines());
putUTFOrNull(value, f.encoding());
value.put(f.isEmpty());
value.putLongArray(f.originalLineOffsets());
for (int i = 0; i < f.lines(); i++) {
value.putByteArray(f.lineHashes()[i]);
Expand Down Expand Up @@ -76,6 +77,7 @@ public Object get(Value value, Class clazz, CoderContext context) {
file.setHash(value.getString());
file.setLines(value.getInt());
file.setEncoding(value.getString());
file.setEmpty(value.getBoolean());
file.setOriginalLineOffsets(value.getLongArray());
byte[][] lineHashes = new byte[file.lines()][];
for (int i = 0; i < file.lines(); i++) {
Expand Down
Expand Up @@ -55,8 +55,8 @@ Metadata read(File file, Charset encoding) {
long currentOriginalOffset = 0;
List<Long> originalLineOffsets = new ArrayList<Long>();
List<Object> lineHashes = new ArrayList<Object>();
int lines = 0;
char c = (char) -1;
int lines = 1;
char c = (char) 0;
try (Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding))) {
MessageDigest globalMd5Digest = DigestUtils.getMd5Digest();
MessageDigest lineMd5Digest = DigestUtils.getMd5Digest();
Expand Down Expand Up @@ -102,11 +102,11 @@ Metadata read(File file, Charset encoding) {
}
if (c != (char) -1) {
// Last line
lines++;
lineHashes.add(blankline ? null : lineMd5Digest.digest());
}
String filehash = Hex.encodeHexString(globalMd5Digest.digest());
return new Metadata(lines, filehash, originalLineOffsets, lineHashes.toArray(new byte[0][]));
boolean empty = lines == 1 && blankline;
String filehash = empty ? null : Hex.encodeHexString(globalMd5Digest.digest());
return new Metadata(lines, filehash, originalLineOffsets, lineHashes.toArray(new byte[0][]), empty);

} catch (IOException e) {
throw new IllegalStateException(String.format("Fail to read file '%s' with encoding '%s'", file.getAbsolutePath(), encoding), e);
Expand All @@ -131,10 +131,12 @@ static class Metadata {
final String hash;
final long[] originalLineOffsets;
final byte[][] lineHashes;
final boolean empty;

private Metadata(int lines, String hash, List<Long> originalLineOffsets, byte[][] lineHashes) {
private Metadata(int lines, String hash, List<Long> originalLineOffsets, byte[][] lineHashes, boolean empty) {
this.lines = lines;
this.hash = hash;
this.empty = empty;
this.originalLineOffsets = Longs.toArray(originalLineOffsets);
this.lineHashes = lineHashes;
}
Expand Down
Expand Up @@ -112,6 +112,7 @@ DeprecatedDefaultInputFile complete(DeprecatedDefaultInputFile inputFile, InputF
inputFile.setHash(metadata.hash);
inputFile.setOriginalLineOffsets(metadata.originalLineOffsets);
inputFile.setLineHashes(metadata.lineHashes);
inputFile.setEmpty(metadata.empty);
inputFile.setStatus(statusDetection.status(inputFile.moduleKey(), inputFile.relativePath(), metadata.hash));
if (analysisMode.isIncremental() && inputFile.status() == InputFile.Status.SAME) {
return null;
Expand Down
9 changes: 8 additions & 1 deletion sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java
Expand Up @@ -26,6 +26,7 @@
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
Expand Down Expand Up @@ -92,7 +93,7 @@ private void copyPreviousMeasuresForUnmodifiedFiles(final SensorContext context,

if (f.status() == Status.SAME && fileData != null) {
if (fileData.needBlame()) {
filesToBlame.add(f);
addIfNotEmpty(filesToBlame, f);
} else {
// Copy previous measures
String scmAuthorsByLine = fileData.scmAuthorsByLine();
Expand All @@ -105,6 +106,12 @@ private void copyPreviousMeasuresForUnmodifiedFiles(final SensorContext context,
}
}
} else {
addIfNotEmpty(filesToBlame, f);
}
}

private void addIfNotEmpty(List<InputFile> filesToBlame, InputFile f) {
if (!((DefaultInputFile) f).isEmpty()) {
filesToBlame.add(f);
}
}
Expand Down
Expand Up @@ -94,6 +94,36 @@ public void testScmMeasure() throws IOException {
.withValue("1=;2=julien;3=julien;4=julien;5=simon"));
}

@Test
public void noScmOnEmptyFile() throws IOException {

File baseDir = prepareProject();

// Clear file content
FileUtils.write(new File(baseDir, "src/sample.xoo"), "");

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", "src")
.put("sonar.scm.provider", "xoo")
.build())
.start();

// lines + qprofile
assertThat(result.measures()).hasSize(2);

assertThat(result.measures()).contains(new DefaultMeasure<Integer>()
.forMetric(CoreMetrics.LINES)
.onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo"))
.withValue(1));
}

@Test
public void failIfMissingFile() throws IOException {

Expand Down
Expand Up @@ -46,10 +46,11 @@ public void empty_file() throws Exception {
FileUtils.touch(tempFile);

FileMetadata.Metadata metadata = new FileMetadata().read(tempFile, Charsets.UTF_8);
assertThat(metadata.lines).isEqualTo(0);
assertThat(metadata.hash).isNotEmpty();
assertThat(metadata.lines).isEqualTo(1);
assertThat(metadata.hash).isNull();
assertThat(metadata.originalLineOffsets).containsOnly(0);
assertThat(metadata.lineHashes).isEmpty();
assertThat(metadata.lineHashes[0]).isNull();
assertThat(metadata.empty).isTrue();
}

@Test
Expand All @@ -64,6 +65,7 @@ public void windows_without_latest_eol() throws Exception {
assertThat(metadata.lineHashes[0]).containsOnly(md5("foo"));
assertThat(metadata.lineHashes[1]).containsOnly(md5("bar"));
assertThat(metadata.lineHashes[2]).containsOnly(md5("baz"));
assertThat(metadata.empty).isFalse();
}

@Test
Expand Down
Expand Up @@ -39,8 +39,9 @@ public class DefaultInputFile implements InputFile, Serializable {
private String hash;
private int lines;
private String encoding;
long[] originalLineOffsets;
byte[][] lineHashes;
private long[] originalLineOffsets;
private byte[][] lineHashes;
private boolean empty;

public DefaultInputFile(String moduleKey, String relativePath) {
this.moduleKey = moduleKey;
Expand Down Expand Up @@ -168,6 +169,15 @@ public DefaultInputFile setLineHashes(byte[][] lineHashes) {
return this;
}

public boolean isEmpty() {
return this.empty;
}

public DefaultInputFile setEmpty(boolean empty) {
this.empty = empty;
return this;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down

0 comments on commit 9030b56

Please sign in to comment.