Skip to content

Instantly share code, notes, and snippets.

@gpeal
Created January 17, 2021 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gpeal/5012fa1b5721ca07c6286a430be31e28 to your computer and use it in GitHub Desktop.
Save gpeal/5012fa1b5721ca07c6286a430be31e28 to your computer and use it in GitHub Desktop.
Tonal Dangerbot
import { fail, warn } from "danger";
const fs = require("fs");
const xml2js = require("xml2js");
const detektReportFile = fs.readFileSync(
"../build/reports/detekt/detekt-checkstyle.xml"
);
const parser = new xml2js.Parser({ async: false, attrkey: "attrs" });
parser.parseString(detektReportFile, (err, report) => {
if (err != null) {
fail(`Failed to parse detekt report ${err}`);
return;
}
for (const fileResult of report.checkstyle.file) {
const fullFileName = fileResult.attrs.name;
const fileName = fullFileName.substring(fullFileName.indexOf("Android"));
for (const error of fileResult.error.map((e) => e.attrs)) {
warn(error.message, fileName, error.line);
}
}
});
import { fail, warn } from "danger";
const childProcess = require("child_process");
const fs = require("fs");
const xml2js = require("xml2js");
const findFiles = (wholename) => {
return childProcess
.execSync(`find .. -wholename "${wholename}"`)
.toString()
.split("\n")
.filter((l) => l.length > 0);
};
const parser = new xml2js.Parser({ async: false, attrkey: "attrs" });
for (fileName of findFiles("../app/build/reports/lint-results-*.xml")) {
const reportXml = fs.readFileSync(fileName).toString();
parser.parseString(reportXml, (err, report) => {
if (err != null) {
fail(`Failed to parse lint report ${err}`);
return;
}
const issues = report.issues.issue.filter(
(i) => i.attrs.severity === "Error"
);
for (const issue of issues) {
const fileName = issue.location[0].attrs.file;
const relativeFileName = fileName.substring(fileName.indexOf("Android"));
const lineNumber = issue.location[0].attrs.line;
const message = issue.attrs.message;
warn(message, relativeFileName, lineNumber);
}
});
}
{
"name": "danger-tonal",
"scripts": {
"danger": "danger",
"danger-detekt": "danger ci --dangerfile detekt.dangerfile.js --id detekt --no-publish-check",
"danger-unit-test": "danger ci --dangerfile unit-test.dangerfile.js --id unit-test --no-publish-check",
"danger-lint": "danger ci --dangerfile lint.dangerfile.js --id lint --no-publish-check",
},
"dependencies": {
"danger": "^10.4.1",
"xml2js": "^0.4.23"
},
"devDependencies": {
"prettier": "2.1.2",
"@types/node": "^14.11.2",
"@types/xml2js": "^0.4.5"
}
}
# GitHub Actions Workflow
name: PR checks
on:
pull_request:
push:
branches:
- main
jobs:
detekt:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup Java JDK
uses: actions/setup-java@v1.4.3
with:
java-version: 1.8
- name: Run detekt
run: cd Android && ./detekt
- name: NPM Install
if: ${{ failure() }}
working-directory: Android/danger
run: npm install
- name: Danger
if: ${{ failure() }}
working-directory: Android/danger
env:
GITHUB_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
run: npm run danger-detekt
import { fail, warn } from "danger";
const childProcess = require("child_process");
const fs = require("fs");
const xml2js = require("xml2js");
const parser = new xml2js.Parser({ async: false, attrkey: "attrs" });
const findFiles = (wholename) => {
return childProcess
.execSync(`find .. -wholename "${wholename}"`)
.toString()
.split("\n")
.filter((l) => l.length > 0);
};
const analyzeReport = (fileName) => {
const reportXml = fs.readFileSync(fileName).toString();
parser.parseString(reportXml, (err, report) => {
if (err != null) {
console.error("Failed to parse report", err);
fail(`Failed to parse test report.`);
return;
}
const testCases = report.testsuite.testcase;
for (const testCase of testCases) {
if (testCase.failure != null) {
const fullyQualifiedClassName = testCase.attrs.classname;
const package = fullyQualifiedClassName.split(".");
const className = package.pop();
const testFiles = findFiles(
"../*/src/test/java/" + package.join("/") + "/" + className + ".*"
);
if (testFiles.length == 0) {
fail(
`Unable to find test file for ${fullyQualifiedClassName} ${package} ${className}.`
);
return;
}
const testFile = testFiles[0];
const testFileContents = fs
.readFileSync(testFile)
.toString()
.split("\n");
const lineNumber = testFileContents.findIndex(
(l) => l.indexOf(testCase.attrs.name) !== -1
);
const msg =
`**${fullyQualifiedClassName}#${testCase.attrs.name}**\n` +
testCase.failure[0]["_"].split("\n").slice(0, 10).join("\n");
warn(msg, testFile.replace("..", "Android"), lineNumber);
}
}
});
};
const testReports = findFiles("../*/build/test-results/*/TEST-*.xml").forEach(
analyzeReport
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment