diff options
Diffstat (limited to 'sonar-scanner-protocol')
7 files changed, 139 insertions, 3 deletions
diff --git a/sonar-scanner-protocol/pom.xml b/sonar-scanner-protocol/pom.xml index c0421f61d94..30174f66e57 100644 --- a/sonar-scanner-protocol/pom.xml +++ b/sonar-scanner-protocol/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>org.sonarsource.sonarqube</groupId> <artifactId>sonarqube</artifactId> - <version>5.6.2-SNAPSHOT</version> + <version>6.1-SNAPSHOT</version> </parent> <artifactId>sonar-scanner-protocol</artifactId> 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..5d408aef691 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 @@ -75,4 +75,7 @@ public class FileStructure { return new File(dir, domain.filePrefix + componentRef + domain.fileSuffix); } + public File contextProperties() { + return new File(dir, "context-props.pb"); + } } diff --git a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportReader.java b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportReader.java index 5cb0d7b8bf2..932373bb3e9 100644 --- a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportReader.java +++ b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportReader.java @@ -162,6 +162,14 @@ public class ScannerReportReader { return null; } + public CloseableIterator<ScannerReport.ContextProperty> readContextProperties() { + File file = fileStructure.contextProperties(); + if (!fileExists(file)) { + return emptyCloseableIterator(); + } + return Protobuf.readStream(file, ScannerReport.ContextProperty.parser()); + } + private static boolean fileExists(File file) { return file.exists() && file.isFile(); } diff --git a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportWriter.java b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportWriter.java index b2da5ba4b56..f85f82495e5 100644 --- a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportWriter.java +++ b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/output/ScannerReportWriter.java @@ -134,6 +134,12 @@ public class ScannerReportWriter { return file; } + public File writeContextProperties(Iterable<ScannerReport.ContextProperty> properties) { + File file = fileStructure.contextProperties(); + Protobuf.writeStream(properties, file, false); + return file; + } + public File getSourceFile(int componentRef) { return fileStructure.fileFor(FileStructure.Domain.SOURCE, componentRef); } diff --git a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/viewer/ScannerReportViewerApp.java b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/viewer/ScannerReportViewerApp.java index 70ea5f477c9..1c8e0d77769 100644 --- a/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/viewer/ScannerReportViewerApp.java +++ b/sonar-scanner-protocol/src/main/java/org/sonar/scanner/protocol/viewer/ScannerReportViewerApp.java @@ -25,12 +25,15 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.sql.Date; import java.text.SimpleDateFormat; import java.util.Scanner; + +import javax.annotation.CheckForNull; import javax.swing.JEditorPane; import javax.swing.JFileChooser; import javax.swing.JFrame; @@ -47,11 +50,14 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeSelectionModel; + +import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.sonar.core.util.CloseableIterator; import org.sonar.scanner.protocol.output.FileStructure.Domain; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component; +import org.sonar.scanner.protocol.output.ScannerReport.Issue; import org.sonar.scanner.protocol.output.ScannerReport.Metadata; import org.sonar.scanner.protocol.output.ScannerReportReader; @@ -75,9 +81,15 @@ public class ScannerReportViewerApp { private JEditorPane sourceEditor; private JScrollPane coverageTab; private JEditorPane coverageEditor; + private JScrollPane testsTab; + private JEditorPane testsEditor; private TextLineNumber textLineNumber; private JScrollPane duplicationTab; private JEditorPane duplicationEditor; + private JScrollPane issuesTab; + private JEditorPane issuesEditor; + private JScrollPane measuresTab; + private JEditorPane measuresEditor; /** * Create the application. @@ -109,6 +121,10 @@ public class ScannerReportViewerApp { private void loadReport() { final JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Choose scanner report directory"); + File lastReport = getLastUsedReport(); + if(lastReport != null) { + fc.setCurrentDirectory(lastReport); + } fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fc.setFileHidingEnabled(false); fc.setApproveButtonText("Open scanner report"); @@ -116,6 +132,7 @@ public class ScannerReportViewerApp { if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); try { + setLastUsedReport(file); loadReport(file); } catch (Exception e) { JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); @@ -126,6 +143,31 @@ public class ScannerReportViewerApp { } } + + @CheckForNull + private File getLastUsedReport() { + File f = new File(System.getProperty("java.io.tmpdir"), ".last_batch_report_dir"); + if(f.exists()) { + String path; + try { + path = FileUtils.readFileToString(f, StandardCharsets.UTF_8); + } catch (IOException e) { + return null; + } + File lastReport = new File(path); + if(lastReport.exists() && lastReport.isDirectory()) { + return lastReport; + } + } + return null; + } + + private void setLastUsedReport(File lastReport) throws IOException { + + File f = new File(System.getProperty("java.io.tmpdir"), ".last_batch_report_dir"); + String fullPath = lastReport.getAbsolutePath(); + FileUtils.write(f, fullPath, StandardCharsets.UTF_8); + } private void exit() { frame.setVisible(false); @@ -190,7 +232,10 @@ public class ScannerReportViewerApp { updateSymbols(component); updateSource(component); updateCoverage(component); + updateTests(component); updateDuplications(component); + updateIssues(component); + updateMeasures(component); } private void updateDuplications(Component component) { @@ -207,6 +252,19 @@ public class ScannerReportViewerApp { } } + private void updateIssues(Component component) { + issuesEditor.setText(""); + try (CloseableIterator<Issue> it = reader.readComponentIssues(component.getRef())) { + while (it.hasNext()) { + Issue issue = it.next(); + int offset = issuesEditor.getDocument().getEndPosition().getOffset(); + issuesEditor.getDocument().insertString(offset, issue.toString(), null); + } + } catch (Exception e) { + throw new IllegalStateException("Can't read issues for " + getNodeName(component), e); + } + } + private void updateCoverage(Component component) { coverageEditor.setText(""); try (CloseableIterator<ScannerReport.LineCoverage> it = reader.readComponentCoverage(component.getRef())) { @@ -218,6 +276,23 @@ public class ScannerReportViewerApp { throw new IllegalStateException("Can't read code coverage for " + getNodeName(component), e); } } + + private void updateTests(Component component) { + testsEditor.setText(""); + File tests = reader.readTests(component.getRef()); + if(tests == null) { + return; + } + try (InputStream inputStream = FileUtils.openInputStream(tests)) { + ScannerReport.Test test = ScannerReport.Test.parser().parseDelimitedFrom(inputStream); + while (test != null) { + testsEditor.getDocument().insertString(testsEditor.getDocument().getEndPosition().getOffset(), test.toString() + "\n", null); + test = ScannerReport.Test.parser().parseDelimitedFrom(inputStream); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + } private void updateSource(Component component) { File sourceFile = reader.getFileStructure().fileFor(Domain.SOURCE, component.getRef()); @@ -247,6 +322,18 @@ public class ScannerReportViewerApp { throw new IllegalStateException("Can't read syntax highlighting for " + getNodeName(component), e); } } + + private void updateMeasures(Component component) { + measuresEditor.setText(""); + try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(component.getRef())) { + while (it.hasNext()) { + ScannerReport.Measure measure = it.next(); + measuresEditor.getDocument().insertString(measuresEditor.getDocument().getEndPosition().getOffset(), measure.toString() + "\n", null); + } + } catch (Exception e) { + throw new IllegalStateException("Can't read measures for " + getNodeName(component), e); + } + } private void updateSymbols(Component component) { symbolEditor.setText(""); @@ -323,6 +410,24 @@ public class ScannerReportViewerApp { duplicationEditor = new JEditorPane(); duplicationTab.setViewportView(duplicationEditor); + + testsTab = new JScrollPane(); + tabbedPane.addTab("Tests", null, testsTab, null); + + testsEditor = new JEditorPane(); + testsTab.setViewportView(testsEditor); + + issuesTab = new JScrollPane(); + tabbedPane.addTab("Issues", null, issuesTab, null); + + issuesEditor = new JEditorPane(); + issuesTab.setViewportView(issuesEditor); + + measuresTab = new JScrollPane(); + tabbedPane.addTab("Measures", null, measuresTab, null); + + measuresEditor = new JEditorPane(); + measuresTab.setViewportView(measuresEditor); treeScrollPane = new JScrollPane(); treeScrollPane.setPreferredSize(new Dimension(200, 400)); diff --git a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto index 1a6efc592f9..f0ab94c1e2a 100644 --- a/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto +++ b/sonar-scanner-protocol/src/main/protobuf/scanner_report.proto @@ -45,6 +45,11 @@ message Metadata { } } +message ContextProperty { + string key = 1; + string value = 2; +} + message ActiveRule { string rule_repository = 1; string rule_key = 2; 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..84bb9693598 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; @@ -71,4 +70,14 @@ public class FileStructureTest { assertThat(structure.fileFor(FileStructure.Domain.ISSUES, 3)).exists().isFile(); assertThat(structure.fileFor(FileStructure.Domain.ISSUES, 42)).doesNotExist(); } + + @Test + public void contextProperties_file() throws Exception { + File dir = temp.newFolder(); + File file = new File(dir, "context-props.pb"); + FileUtils.write(file, "content"); + + FileStructure structure = new FileStructure(dir); + assertThat(structure.contextProperties()).exists().isFile().isEqualTo(file); + } } |