Skip to content

Commit

Permalink
[FEATURE] Github error reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
SeeSharpSoft committed Aug 13, 2020
1 parent d41ddb2 commit c3c2a02
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 5 deletions.
9 changes: 5 additions & 4 deletions .travis.yml
Expand Up @@ -3,8 +3,9 @@ jdk:
- openjdk9

env:
- IDEA_VERSION=PC-2019.3.3 GRAMMAR_KIT_VERSION=2019.3
- IDEA_VERSION=IU-LATEST-EAP-SNAPSHOT GRAMMAR_KIT_VERSION=2019.3
- IDEA_VERSION=PC-2019.3.3 GRAMMAR_KIT_VERSION=2019.3 GIT_PLUGIN_VERSION=Git4Idea:193.6494.42 GITHUB_PLUGIN_VERSION=org.jetbrains.plugins.github:193.6494.42
- IDEA_VERSION=CL-2020.1.3 GRAMMAR_KIT_VERSION=2019.3 GIT_PLUGIN_VERSION=Git4Idea:201.6668.74 GITHUB_PLUGIN_VERSION=org.jetbrains.plugins.github:201.6668.74
- IDEA_VERSION=IU-LATEST-EAP-SNAPSHOT GRAMMAR_KIT_VERSION=2019.3 GIT_PLUGIN_VERSION=Git4Idea GITHUB_PLUGIN_VERSION=org.jetbrains.plugins.github

script: xvfb-run gradle check

Expand All @@ -14,9 +15,9 @@ after_success:
jobs:
include:
- if: (branch = master AND type = push) OR (type = pull_request)
env: IDEA_VERSION=IC-193.5233.102 GRAMMAR_KIT_VERSION=2019.3
env: IDEA_VERSION=IC-193.5233.102 GRAMMAR_KIT_VERSION=2019.3 GIT_PLUGIN_VERSION=Git4Idea:193.6494.42 GITHUB_PLUGIN_VERSION=org.jetbrains.plugins.github:193.6494.42
script: xvfb-run gradle check verifyPlugin
- stage: deploy
if: branch IN (Testing, Staging, Stable) AND type = push
env: IDEA_VERSION=IC-193.5233.102 GRAMMAR_KIT_VERSION=2019.3 JI_CHANNELS=$TRAVIS_BRANCH
env: IDEA_VERSION=IC-193.5233.102 GRAMMAR_KIT_VERSION=2019.3 JI_CHANNELS=$TRAVIS_BRANCH GIT_PLUGIN_VERSION=Git4Idea:193.6494.42 GITHUB_PLUGIN_VERSION=org.jetbrains.plugins.github:193.6494.42
script: xvfb-run gradle publishPlugin
7 changes: 6 additions & 1 deletion build.gradle
Expand Up @@ -14,7 +14,7 @@ plugins {
id 'org.jetbrains.intellij' version '0.4.10'
id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.8.2'
id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
id 'com.github.ManifestClasspath' version '0.1.0-RELEASE'
}

jacocoTestReport {
Expand Down Expand Up @@ -77,6 +77,11 @@ intellij {
instrumentCode = true
updateSinceUntilBuild = false
downloadSources = false

plugins = [
System.getenv().getOrDefault('GIT_PLUGIN_VERSION', 'Git4Idea:201.6668.74'),
System.getenv().getOrDefault('GITHUB_PLUGIN_VERSION', 'org.jetbrains.plugins.github:201.6668.74')
]
}
publishPlugin {
token = System.getenv().getOrDefault('JI_TOKEN', '')
Expand Down
@@ -0,0 +1,193 @@
package net.seesharpsoft.intellij.plugins.csv;

import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.ErrorReportSubmitter;
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
import com.intellij.openapi.diagnostic.SubmittedReportInfo;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.*;
import org.jetbrains.plugins.github.api.data.*;
import org.jetbrains.plugins.github.api.data.request.GithubRequestPagination;
import org.jetbrains.plugins.github.authentication.GithubAuthenticationManager;
import org.jetbrains.plugins.github.authentication.accounts.GithubAccount;

import java.awt.*;
import java.io.IOException;
import java.util.Collections;

public class CsvGithubIssueSubmitter extends ErrorReportSubmitter {
public static final String GIT_USER = "SeeSharpSoft";
public static final String GIT_REPO = "intellij-csv-validator";

public static final GHRepositoryPath GITHUB_FULL_PATH = new GHRepositoryPath(GIT_USER, GIT_REPO);

@NotNull
@Override
public String getReportActionText() {
return "Report to 'CSV Plugin' (Github)";
}

@Override
public boolean submit(@NotNull IdeaLoggingEvent[] events, @Nullable String additionalInfo, @NotNull Component parentComponent, @NotNull Consumer<SubmittedReportInfo> consumer) {
final DataContext dataContext = DataManager.getInstance().getDataContext(parentComponent);
final Project project = CommonDataKeys.PROJECT.getData(dataContext);

for (IdeaLoggingEvent event : events) {
if (!submit(event, additionalInfo, project, consumer)) {
return false;
}
}
return true;
}

protected boolean submit(IdeaLoggingEvent event, String additionalInfo, Project project, Consumer<SubmittedReportInfo> consumer) {
GithubAuthenticationManager githubAuthManager = GithubAuthenticationManager.getInstance();
if (!githubAuthManager.ensureHasAccounts(project)) {
return false;
}
GithubAccount githubAccount = githubAuthManager.getSingleOrDefaultAccount(project);
GithubApiRequestExecutor githubExecutor = GithubApiRequestExecutorManager.getInstance().getExecutor(githubAccount, project);

ApplicationManager.getApplication().executeOnPooledThread(() -> {
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
ProgressManager.getInstance().runProcess(() -> {
submitToGithub(event, additionalInfo, githubExecutor, consumer);
}, progressIndicator);
});

return true;
}

private void submitToGithub(IdeaLoggingEvent event, String additionalInfo, GithubApiRequestExecutor githubExecutor, Consumer<SubmittedReportInfo> consumer) {
SubmittedReportInfo.SubmissionStatus status;

String issueTitle = getIssueTitle(event);
String issueDetails = getIssueDetails(event, additionalInfo);
String foundIssueId = searchExistingIssues(githubExecutor, issueTitle);

if (foundIssueId == null) {
createNewIssue(githubExecutor, issueTitle, issueDetails);
status = SubmittedReportInfo.SubmissionStatus.NEW_ISSUE;
} else {
updateExistingIssue(githubExecutor, foundIssueId, issueDetails);
status = SubmittedReportInfo.SubmissionStatus.DUPLICATE;
}
consumer.consume(new SubmittedReportInfo(status));
}

protected void updateExistingIssue(GithubApiRequestExecutor githubExecutor, String issueId, String content) {
GithubApiRequest.Post createIssueCommentRequest =
GithubApiRequests.Repos.Issues.Comments.create(
GithubServerPath.DEFAULT_SERVER,
GIT_USER,
GIT_REPO,
issueId,
content
);

try {
githubExecutor.execute(createIssueCommentRequest);
} catch (IOException exc) {
throw new RuntimeException(exc);
}
}

protected void createNewIssue(GithubApiRequestExecutor githubExecutor, String title, String content) {
GithubApiRequest.Post<GithubIssue> createIssueRequest =
GithubApiRequests.Repos.Issues.create(
GithubServerPath.DEFAULT_SERVER,
GIT_USER,
GIT_REPO,
title,
content,
null,
Collections.emptyList(),
Collections.emptyList());

try {
githubExecutor.execute(createIssueRequest);
} catch (IOException exc) {
throw new RuntimeException(exc);
}
}

protected String searchExistingIssues(GithubApiRequestExecutor githubExecutor, String needle) {
GithubApiRequest<GithubResponsePage<GithubSearchedIssue>> existingIssueRequest =
GithubApiRequests.Search.Issues.get(
GithubServerPath.DEFAULT_SERVER,
GITHUB_FULL_PATH,
GithubIssueState.open.name(),
null,
needle,
new GithubRequestPagination(1, 1)
);

String issueId = null;
try {
GithubResponsePage<GithubSearchedIssue> foundIssuesPage = githubExecutor.execute(existingIssueRequest);
if (foundIssuesPage != null && !foundIssuesPage.getItems().isEmpty()) {
GithubSearchedIssue foundIssue = foundIssuesPage.getItems().get(0);
if (foundIssue.getTitle().equals(needle)) {
issueId = Long.toString(foundIssue.getNumber());
}
}
} catch (IOException exc) {
throw new RuntimeException(exc);
}

return issueId;
}

protected String getIssueTitle(IdeaLoggingEvent event) {
String throwableText = event.getThrowableText();
int index = Math.min(throwableText.indexOf("\r"), throwableText.indexOf("\n"));
return "[Automated Report] " + event.getThrowableText().substring(0, index);
}

protected String getIssueDetails(IdeaLoggingEvent event, String additionalInfo) {
StringBuilder builder = new StringBuilder()
.append("Message\n---\n")
.append(additionalInfo != null && !additionalInfo.isEmpty() ? additionalInfo : "<no message>")
.append("\n\n")
.append("Stacktrace\n---\n")
.append(event.getThrowableText())
.append("\n\n")
.append("Plugin\n---\n")
.append(getPluginDescriptor().getPluginClassLoader().toString())
.append("\n\n")
.append("IDE\n---\n")
.append(ApplicationInfo.getInstance().getVersionName())
.append(" (")
.append(ApplicationInfo.getInstance().getBuild().toString())
.append(")");

return builder.toString();
}

@Override
public String getPrivacyNoticeText() {
StringBuilder builder = new StringBuilder()
.append("An automated issue report contains the provided message, ")
.append("the stacktrace, ")
.append("the plugin class loader info (")
.append(getPluginDescriptor().getPluginClassLoader().toString())
.append("), the used IDE version name (")
.append(ApplicationInfo.getInstance().getVersionName())
.append(") and build number (")
.append(ApplicationInfo.getInstance().getBuild().toString())
.append("). ")
.append("By sending the report I agree to the information be used for resolving this and further related issues. ")
.append("Github Issue Link: ")
.append(String.format("https://%s/%s/%s/issues", GithubServerPath.DEFAULT_SERVER, GIT_USER, GIT_REPO));
return builder.toString();
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Expand Up @@ -61,6 +61,7 @@ FIX: Performance for indexing large CSV files #239
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
on how to target different products -->
<depends>com.intellij.modules.lang</depends>
<depends optional="true" config-file="withGithub.xml">org.jetbrains.plugins.github</depends>

<extensions defaultExtensionNs="com.intellij">
<!-- version 173.* - 192.* -->
Expand Down

0 comments on commit c3c2a02

Please sign in to comment.