diff --git a/README.md b/README.md index 6f5390e..e9c99e1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -*Note:* There are known issues with the latest version of eslint currently that we are looking into. Older versions should be fine. - ---- - # 🐺 Balto Balto is Smart and Fast: diff --git a/main.js b/main.js index 6f965b6..42423a5 100644 --- a/main.js +++ b/main.js @@ -1,156 +1,151 @@ -const io = require("@actions/io"); -const { easyExec } = require("./utils"); -const { generateChangeRanges } = require("./git_utils"); -const CheckRun = require("./check_run"); +const io = require('@actions/io') +const { easyExec } = require('./utils') +const { generateChangeRanges } = require('./git_utils') +const CheckRun = require('./check_run') const { GITHUB_WORKSPACE, INPUT_EXTENSIONS, - INPUT_CONCLUSIONLEVEL, -} = process.env; + INPUT_CONCLUSIONLEVEL +} = process.env -const event = require(process.env.GITHUB_EVENT_PATH); -const checkName = "eslint"; +const event = require(process.env.GITHUB_EVENT_PATH) +const checkName = 'eslint' -async function withCwd(directory, innerAction) { - const oldCwd = process.cwd(); +let yarnOutput = null - try { - process.chdir(directory); - - return await innerAction(); - } finally { - process.chdir(oldCwd); - } -} +async function getYarn () { + if (yarnOutput) return yarnOutput -let yarnOutput = null; + const { output } = await easyExec('yarn list --depth=0 --json') -async function getYarn() { - if (yarnOutput) return yarnOutput; - - return await withCwd(GITHUB_WORKSPACE, async () => { - const { output } = await easyExec("yarn list --depth=0 --json"); - - yarnOutput = JSON.parse(output); - return yarnOutput; - }); + yarnOutput = JSON.parse(output) + return yarnOutput } -async function getPeerDependencies(error) { +async function getPeerDependencies (error) { const peers = error - .split("\n") + .split('\n') .map(l => l.match(/ requires a peer of (?[^@]+)@/)) .filter(m => m) - .map(m => m.groups.packageName); + .map(m => m.groups.packageName) - const versions = []; + const versions = [] for (var peersIndex = 0; peersIndex < peers.length; peersIndex++) { - const peer = peers[peersIndex]; + const peer = peers[peersIndex] - const yarn = await getYarn(); + const yarn = await getYarn() yarn.data.trees .filter(p => p.name.startsWith(`${peer}@`)) - .forEach(p => versions.push(p.name)); + .forEach(p => versions.push(p.name)) } - return versions; + return versions } -async function installEslintPackagesAsync() { - const yarn = await getYarn(); +async function installEslintPackagesAsync () { + const yarn = await getYarn() const versions = yarn.data.trees .filter(p => p.name.match(/eslint/)) - .map(p => p.name); - - await withCwd(__dirname, async () => { - await io.mv("package.json", "package.json-bak"); - - try { - const { error } = await easyExec( - ["npm i", ...versions, "--no-package-lock"].join(" ") - ); - const peerVersions = await getPeerDependencies(error); - await easyExec(["npm i", ...peerVersions, "--no-package-lock"].join(" ")); - } finally { - await io.mv("package.json-bak", "package.json"); + .map(p => p.name) + + await io.mv('package.json', 'package.json-bak') + + try { + const { error } = await easyExec( + ['npm i', ...versions, '--no-package-lock'].join(' ') + ) + const peerVersions = await getPeerDependencies(error) + if (peerVersions.length > 0) { + await easyExec(['npm i', ...peerVersions, '--no-package-lock'].join(' ')) } - }); + } finally { + await io.mv('package.json-bak', 'package.json') + } } -async function runEslint() { - const compareSha = event.pull_request.base.sha; +async function runEslint () { + const compareSha = event.pull_request.base.sha const { output } = await easyExec( `git diff --name-only --diff-filter AM ${compareSha}` - ); + ) - const eslint = require("eslint"); - const cli = new eslint.CLIEngine(); - const extensions = INPUT_EXTENSIONS.split(","); + const eslint = require(`${GITHUB_WORKSPACE}/node_modules/eslint`) + const cli = new eslint.CLIEngine() + const extensions = INPUT_EXTENSIONS.split(',') const paths = output - .split("\n") - .filter(path => extensions.some(e => path.endsWith(`.${e}`))); - const report = cli.executeOnFiles(paths); + .split('\n') + .filter(path => extensions.some(e => path.endsWith(`.${e}`))) + const report = cli.executeOnFiles(paths) - const { results, errorCount, warningCount } = report; + const { results, errorCount, warningCount } = report - const levels = ["", "warning", "failure"]; + const levels = ['', 'warning', 'failure'] - const annotations = []; + const annotations = [] for (let resultsIndex = 0; resultsIndex < results.length; resultsIndex++) { - const result = results[resultsIndex]; - const { filePath, messages } = result; - const path = filePath.substring(GITHUB_WORKSPACE.length + 1); + const result = results[resultsIndex] + const { filePath, messages } = result + const path = filePath.substring(GITHUB_WORKSPACE.length + 1) - if (cli.isPathIgnored(path)) continue; + if (cli.isPathIgnored(path)) continue - const changeRanges = await generateChangeRanges(path, { compareSha }); + const changeRanges = await generateChangeRanges(path, { compareSha }) for ( let messagesIndex = 0; messagesIndex < messages.length; messagesIndex++ ) { - const msg = messages[messagesIndex]; + const msg = messages[messagesIndex] - const { line, severity, ruleId, message } = msg; + const { line, severity, ruleId, message } = msg - if (!changeRanges.some(r => r.doesInclude(line))) continue; + if (!changeRanges.some(r => r.doesInclude(line))) continue - const annotationLevel = levels[severity]; + const annotationLevel = levels[severity] annotations.push({ path, start_line: line, end_line: line, annotation_level: annotationLevel, - message: `[${ruleId}] ${message}`, - }); + message: `[${ruleId}] ${message}` + }) } } return { - conclusion: errorCount > 0 ? INPUT_CONCLUSIONLEVEL : "success", + conclusion: errorCount > 0 ? INPUT_CONCLUSIONLEVEL : 'success', output: { title: checkName, summary: `${errorCount} error(s), ${warningCount} warning(s) found`, - annotations: annotations.slice(0, 50), // TODO: FR what happens with more than 50? - }, - }; + annotations: annotations.slice(0, 50) // TODO: FR what happens with more than 50? + } + } } -async function run() { - const checkRun = new CheckRun({ name: checkName, event }); - await checkRun.create(); - await installEslintPackagesAsync(); - const eslintReport = await runEslint(); - - await checkRun.update(eslintReport); +async function run () { + const checkRun = new CheckRun({ name: checkName, event }) + await checkRun.create() + let report = {} + try { + process.chdir(GITHUB_WORKSPACE) + await installEslintPackagesAsync() + report = await runEslint() + } catch (e) { + report = { + conclusion: 'failure', + output: { title: checkName, summary: `Balto error: ${e}` } + } + } finally { + await checkRun.update(report) + } } -run(); +run()