Search in sources :

Example 11 with BlameLine

use of org.sonar.api.batch.scm.BlameLine in project sonarqube by SonarSource.

the class XooBlameCommandTest method testBlame.

@Test
public void testBlame() throws IOException {
    File source = new File(baseDir, "src/foo.xoo");
    FileUtils.write(source, "sample content");
    File scm = new File(baseDir, "src/foo.xoo.scm");
    FileUtils.write(scm, "123,julien,2014-12-12\n234,julien,2014-12-24");
    DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage(Xoo.KEY).setModuleBaseDir(baseDir.toPath()).build();
    fs.add(inputFile);
    BlameOutput result = mock(BlameOutput.class);
    when(input.filesToBlame()).thenReturn(Arrays.asList(inputFile));
    new XooBlameCommand().blame(input, result);
    verify(result).blameResult(inputFile, Arrays.asList(new BlameLine().revision("123").author("julien").date(DateUtils.parseDate("2014-12-12")), new BlameLine().revision("234").author("julien").date(DateUtils.parseDate("2014-12-24"))));
}
Also used : TestInputFileBuilder(org.sonar.api.batch.fs.internal.TestInputFileBuilder) BlameLine(org.sonar.api.batch.scm.BlameLine) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) BlameOutput(org.sonar.api.batch.scm.BlameCommand.BlameOutput) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) File(java.io.File) Test(org.junit.Test)

Example 12 with BlameLine

use of org.sonar.api.batch.scm.BlameLine in project sonarqube by SonarSource.

the class SvnBlameCommand method blame.

@VisibleForTesting
void blame(SVNClientManager clientManager, InputFile inputFile, BlameOutput output) {
    String filename = inputFile.relativePath();
    LOG.debug("Process file {}", filename);
    AnnotationHandler handler = new AnnotationHandler();
    try {
        if (!checkStatus(clientManager, inputFile)) {
            return;
        }
        SVNLogClient logClient = clientManager.getLogClient();
        logClient.setDiffOptions(new SVNDiffOptions(true, true, true));
        logClient.doAnnotate(inputFile.file(), SVNRevision.UNDEFINED, SVNRevision.create(1), SVNRevision.BASE, true, true, handler, null);
    } catch (SVNAuthenticationException e) {
        if (configuration.isEmpty()) {
            LOG.warn("Authentication to SVN server is required but no authentication data was passed to the scanner");
        }
        throw new IllegalStateException("Authentication error when executing blame for file " + filename, e);
    } catch (SVNException e) {
        throw new IllegalStateException("Error when executing blame for file " + filename, e);
    }
    List<BlameLine> lines = handler.getLines();
    if (lines.size() == inputFile.lines() - 1) {
        // SONARPLUGINS-3097 SVN do not report blame on last empty line
        lines.add(lines.get(lines.size() - 1));
    }
    output.blameResult(inputFile, lines);
}
Also used : BlameLine(org.sonar.api.batch.scm.BlameLine) SVNAuthenticationException(org.tmatesoft.svn.core.SVNAuthenticationException) SVNDiffOptions(org.tmatesoft.svn.core.wc.SVNDiffOptions) SVNException(org.tmatesoft.svn.core.SVNException) SVNLogClient(org.tmatesoft.svn.core.wc.SVNLogClient) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 13 with BlameLine

use of org.sonar.api.batch.scm.BlameLine in project sonarqube by SonarSource.

the class JGitBlameCommand method blame.

private void blame(BlameOutput output, Git git, File gitBaseDir, InputFile inputFile) {
    String filename = pathResolver.relativePath(gitBaseDir, inputFile.file());
    LOG.debug("Blame file {}", filename);
    BlameResult blameResult;
    try {
        blameResult = git.blame().setTextComparator(RawTextComparator.WS_IGNORE_ALL).setFilePath(filename).call();
    } catch (Exception e) {
        throw new IllegalStateException("Unable to blame file " + inputFile.relativePath(), e);
    }
    List<BlameLine> lines = new ArrayList<>();
    if (blameResult == null) {
        LOG.debug("Unable to blame file {}. It is probably a symlink.", inputFile.relativePath());
        return;
    }
    for (int i = 0; i < blameResult.getResultContents().size(); i++) {
        if (blameResult.getSourceAuthor(i) == null || blameResult.getSourceCommit(i) == null) {
            LOG.debug("Unable to blame file {}. No blame info at line {}. Is file committed? [Author: {} Source commit: {}]", inputFile.relativePath(), i + 1, blameResult.getSourceAuthor(i), blameResult.getSourceCommit(i));
            return;
        }
        lines.add(new BlameLine().date(blameResult.getSourceCommitter(i).getWhen()).revision(blameResult.getSourceCommit(i).getName()).author(blameResult.getSourceAuthor(i).getEmailAddress()));
    }
    if (lines.size() == inputFile.lines() - 1) {
        // SONARPLUGINS-3097 Git do not report blame on last empty line
        lines.add(lines.get(lines.size() - 1));
    }
    output.blameResult(inputFile, lines);
}
Also used : BlameLine(org.sonar.api.batch.scm.BlameLine) BlameResult(org.eclipse.jgit.blame.BlameResult) ArrayList(java.util.ArrayList)

Example 14 with BlameLine

use of org.sonar.api.batch.scm.BlameLine in project sonarqube by SonarSource.

the class DefaultBlameOutput method blameResult.

@Override
public synchronized void blameResult(InputFile file, List<BlameLine> lines) {
    checkNotNull(file);
    checkNotNull(lines);
    checkArgument(allFilesToBlame.contains(file), "It was not expected to blame file %s", file);
    if (lines.size() != file.lines()) {
        LOG.debug("Ignoring blame result since provider returned {} blame lines but file {} has {} lines", lines.size(), file, file.lines());
        return;
    }
    Builder scmBuilder = ScannerReport.Changesets.newBuilder();
    DefaultInputFile inputFile = (DefaultInputFile) file;
    scmBuilder.setComponentRef(inputFile.scannerId());
    Map<String, Integer> changesetsIdByRevision = new HashMap<>();
    int lineId = 1;
    for (BlameLine line : lines) {
        validateLine(line, lineId, file);
        Integer changesetId = changesetsIdByRevision.get(line.revision());
        if (changesetId == null) {
            addChangeset(scmBuilder, line);
            changesetId = scmBuilder.getChangesetCount() - 1;
            changesetsIdByRevision.put(line.revision(), changesetId);
        }
        scmBuilder.addChangesetIndexByLine(changesetId);
        lineId++;
    }
    writer.writeComponentChangesets(scmBuilder.build());
    allFilesToBlame.remove(file);
    count++;
    progressReport.message(count + "/" + total + " " + pluralize(count) + " have been analyzed");
}
Also used : BlameLine(org.sonar.api.batch.scm.BlameLine) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) HashMap(java.util.HashMap) Builder(org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder)

Example 15 with BlameLine

use of org.sonar.api.batch.scm.BlameLine in project sonarqube by SonarSource.

the class SvnBlameCommandTest method testParsingOfOutput.

@Test
public void testParsingOfOutput() throws Exception {
    File repoDir = unzip("repo-svn.zip");
    String scmUrl = "file:///" + unixPath(new File(repoDir, "repo-svn"));
    File baseDir = new File(checkout(scmUrl), "dummy-svn");
    when(fs.baseDir()).thenReturn(baseDir);
    DefaultInputFile inputFile = new TestInputFileBuilder("foo", DUMMY_JAVA).setLines(27).setModuleBaseDir(baseDir.toPath()).build();
    BlameOutput blameResult = mock(BlameOutput.class);
    when(input.filesToBlame()).thenReturn(singletonList(inputFile));
    newSvnBlameCommand().blame(input, blameResult);
    ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
    verify(blameResult).blameResult(eq(inputFile), captor.capture());
    List<BlameLine> result = captor.getValue();
    assertThat(result).hasSize(27);
    Date commitDate = new Date(1342691097393L);
    BlameLine[] expected = IntStream.rangeClosed(1, 27).mapToObj(i -> new BlameLine().date(commitDate).revision("2").author("dgageot")).toArray(BlameLine[]::new);
    assertThat(result).containsExactly(expected);
}
Also used : TestInputFileBuilder(org.sonar.api.batch.fs.internal.TestInputFileBuilder) BlameLine(org.sonar.api.batch.scm.BlameLine) Arrays(java.util.Arrays) Enumeration(java.util.Enumeration) Date(java.util.Date) SVNStatus(org.tmatesoft.svn.core.wc.SVNStatus) URISyntaxException(java.net.URISyntaxException) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) BlameInput(org.sonar.api.batch.scm.BlameCommand.BlameInput) SVNClientManager(org.tmatesoft.svn.core.wc.SVNClientManager) Collections.singletonList(java.util.Collections.singletonList) Mockito.verifyNoInteractions(org.mockito.Mockito.verifyNoInteractions) Mockito.doThrow(org.mockito.Mockito.doThrow) Mockito.anyBoolean(org.mockito.Mockito.anyBoolean) ZipFile(java.util.zip.ZipFile) Path(java.nio.file.Path) ZipEntry(java.util.zip.ZipEntry) Parameterized(org.junit.runners.Parameterized) StandardOpenOption(java.nio.file.StandardOpenOption) FileSystem(org.sonar.api.batch.fs.FileSystem) TestInputFileBuilder(org.sonar.api.batch.fs.internal.TestInputFileBuilder) BlameLine(org.sonar.api.batch.scm.BlameLine) List(java.util.List) SVNStatusClient(org.tmatesoft.svn.core.wc.SVNStatusClient) Mockito.any(org.mockito.Mockito.any) LoggerLevel(org.sonar.api.utils.log.LoggerLevel) Mockito.eq(org.mockito.Mockito.eq) Mockito.mock(org.mockito.Mockito.mock) IntStream(java.util.stream.IntStream) InputFile(org.sonar.api.batch.fs.InputFile) SVNWCUtil(org.tmatesoft.svn.core.wc.SVNWCUtil) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) SVNDepth(org.tmatesoft.svn.core.SVNDepth) Assert.assertThrows(org.junit.Assert.assertThrows) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) SvnCodec(org.tmatesoft.svn.core.internal.wc2.compat.SvnCodec) SVNLogClient(org.tmatesoft.svn.core.wc.SVNLogClient) ArgumentCaptor(org.mockito.ArgumentCaptor) Before(org.junit.Before) ISVNOptions(org.tmatesoft.svn.core.wc.ISVNOptions) Files(java.nio.file.Files) SVNStatusType(org.tmatesoft.svn.core.wc.SVNStatusType) SvnCheckout(org.tmatesoft.svn.core.wc2.SvnCheckout) IOException(java.io.IOException) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) File(java.io.File) SVNAuthenticationException(org.tmatesoft.svn.core.SVNAuthenticationException) Mockito.verify(org.mockito.Mockito.verify) ISVNAuthenticationManager(org.tmatesoft.svn.core.auth.ISVNAuthenticationManager) Rule(org.junit.Rule) LogTester(org.sonar.api.utils.log.LogTester) SVNRevision(org.tmatesoft.svn.core.wc.SVNRevision) Paths(java.nio.file.Paths) SVNURL(org.tmatesoft.svn.core.SVNURL) SVNUpdateClient(org.tmatesoft.svn.core.wc.SVNUpdateClient) BlameOutput(org.sonar.api.batch.scm.BlameCommand.BlameOutput) SvnTarget(org.tmatesoft.svn.core.wc2.SvnTarget) TemporaryFolder(org.junit.rules.TemporaryFolder) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) BlameOutput(org.sonar.api.batch.scm.BlameCommand.BlameOutput) ZipFile(java.util.zip.ZipFile) InputFile(org.sonar.api.batch.fs.InputFile) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) File(java.io.File) Date(java.util.Date) Test(org.junit.Test)

Aggregations

BlameLine (org.sonar.api.batch.scm.BlameLine)17 Test (org.junit.Test)12 TestInputFileBuilder (org.sonar.api.batch.fs.internal.TestInputFileBuilder)12 InputFile (org.sonar.api.batch.fs.InputFile)10 File (java.io.File)9 DefaultInputFile (org.sonar.api.batch.fs.internal.DefaultInputFile)9 Date (java.util.Date)7 BlameOutput (org.sonar.api.batch.scm.BlameCommand.BlameOutput)7 IOException (java.io.IOException)4 DefaultFileSystem (org.sonar.api.batch.fs.internal.DefaultFileSystem)4 Path (java.nio.file.Path)3 Arrays (java.util.Arrays)3 Collections.singletonList (java.util.Collections.singletonList)3 List (java.util.List)3 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)3 Before (org.junit.Before)3 Rule (org.junit.Rule)3 TemporaryFolder (org.junit.rules.TemporaryFolder)3 ArgumentCaptor (org.mockito.ArgumentCaptor)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2