From 84f912b7f839b23c92c3b06d267230a5f3ef9e58 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 14:49:31 -0400 Subject: [PATCH 01/11] chore: add standard as a dep --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 03a275a..58d63b6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Validate the commit message for a particular commit in node core", "main": "index.js", "scripts": { - "pretest": "lintit && check-pkg", + "pretest": "standard && check-pkg", "test": "tap -j4 --cov test/**/*.js test/*.js", "posttest": "tap --coverage-report=text-summary", "test-ci": "npm run test -- --coverage-report=lcov" @@ -17,7 +17,7 @@ }, "devDependencies": { "check-pkg": "^2.1.1", - "lintit": "^7.2.1", + "standard": "^14.3.4", "tap": "^14.10.2" }, "files": [ From 6d3a6bced90c93b05558fe3ff1da0bf129cbb5c5 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 14:50:54 -0400 Subject: [PATCH 02/11] test: first run of standard --fix --- lib/format-pretty.js | 8 +- lib/format-tap.js | 52 ++++----- lib/index.js | 17 ++- lib/rule.js | 10 +- lib/rules/fixes-url.js | 90 +++++++-------- lib/rules/line-after-title.js | 36 +++--- lib/rules/line-length.js | 56 +++++---- lib/rules/metadata-end.js | 36 +++--- lib/rules/pr-url.js | 64 +++++------ lib/rules/reviewers.js | 44 ++++---- lib/rules/subsystem.js | 200 ++++++++++++++++----------------- lib/rules/title-format.js | 68 +++++------ lib/rules/title-length.js | 64 +++++------ lib/tap.js | 30 ++--- lib/utils.js | 14 +-- test/cli-test.js | 16 +-- test/rule-test.js | 2 +- test/rules/fixes-url.js | 66 +++++------ test/rules/line-after-title.js | 42 +++---- test/rules/line-length.js | 56 ++++----- test/rules/pr-url.js | 53 +++++---- test/rules/reviewers.js | 36 +++--- test/rules/subsystem.js | 64 +++++------ test/rules/title-format.js | 76 ++++++------- test/utils-test.js | 32 +++--- test/validator.js | 8 +- 26 files changed, 618 insertions(+), 622 deletions(-) diff --git a/lib/format-pretty.js b/lib/format-pretty.js index 72b18e5..2d1dc35 100644 --- a/lib/format-pretty.js +++ b/lib/format-pretty.js @@ -5,7 +5,7 @@ const utils = require('./utils') const MAX_LINE_COL_LEN = 6 -module.exports = function formatPretty(context, msgs, validator, opts) { +module.exports = function formatPretty (context, msgs, validator, opts) { opts = Object.assign({ detailed: false }, opts) @@ -57,7 +57,7 @@ module.exports = function formatPretty(context, msgs, validator, opts) { } } -function formatLength(msg, opts) { +function formatLength (msg, opts) { const out = formatMessage(msg) const str = msg.string const l = str.length @@ -68,7 +68,7 @@ function formatLength(msg, opts) { ${diff}` } -function formatMessage(msg) { +function formatMessage (msg) { const l = msg.line || 0 const col = msg.column || 0 const pad = utils.rightPad(`${l}:${col}`, MAX_LINE_COL_LEN) @@ -83,6 +83,6 @@ function formatMessage(msg) { return ` ${icon} ${line} ${utils.rightPad(m, 40)} ${id}` } -function formatId(id) { +function formatId (id) { return chalk.red(id) } diff --git a/lib/format-tap.js b/lib/format-tap.js index f6ab300..e1fc783 100644 --- a/lib/format-tap.js +++ b/lib/format-tap.js @@ -1,6 +1,6 @@ 'use strict' -module.exports = function formatTap(t, context, msgs, validator) { +module.exports = function formatTap (t, context, msgs, validator) { for (const m of msgs) { switch (m.level) { case 'pass': @@ -19,7 +19,7 @@ module.exports = function formatTap(t, context, msgs, validator) { } } -function onFail(context, m, validator, t) { +function onFail (context, m, validator, t) { switch (m.id) { case 'line-length': case 'title-length': @@ -34,44 +34,44 @@ function onFail(context, m, validator, t) { } } -function lengthFail(context, m, validator, t) { +function lengthFail (context, m, validator, t) { const body = m.id === 'title-length' ? context.title : context.body t.fail(`${m.id}: ${m.message}`, { - found: m.string.length - , compare: '<=' - , wanted: m.maxLength - , at: { - line: m.line || 0 - , column: m.column || 0 - , body: body + found: m.string.length, + compare: '<=', + wanted: m.maxLength, + at: { + line: m.line || 0, + column: m.column || 0, + body: body } }) } -function subsystemFail(context, m, validator, t) { +function subsystemFail (context, m, validator, t) { t.fail(`${m.id}: ${m.message} (${m.string})`, { - found: m.string - , compare: 'indexOf() !== -1' - , wanted: m.wanted || '' - , at: { - line: m.line || 0 - , column: m.column || 0 - , body: m.title + found: m.string, + compare: 'indexOf() !== -1', + wanted: m.wanted || '', + at: { + line: m.line || 0, + column: m.column || 0, + body: m.title } }) } -function defaultFail(context, m, validator, t) { +function defaultFail (context, m, validator, t) { t.fail(`${m.id}: ${m.message} (${m.string})`, { - found: m.string - , compare: Array.isArray(m.wanted) ? 'indexOf() !== -1' : '===' - , wanted: m.wanted || '' - , at: { - line: m.line || 0 - , column: m.column || 0 - , body: context.body + found: m.string, + compare: Array.isArray(m.wanted) ? 'indexOf() !== -1' : '===', + wanted: m.wanted || '', + at: { + line: m.line || 0, + column: m.column || 0, + body: context.body } }) } diff --git a/lib/index.js b/lib/index.js index c9327f2..1ce0b03 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,7 +6,7 @@ const BaseRule = require('./rule') const RULES = require('./rules') module.exports = class ValidateCommit extends EE { - constructor(options) { + constructor (options) { super() this.opts = Object.assign({ @@ -20,7 +20,7 @@ module.exports = class ValidateCommit extends EE { this.loadBaseRules() } - loadBaseRules() { + loadBaseRules () { const keys = Object.keys(RULES) for (const key of keys) { this.rules.set(key, new BaseRule(RULES[key])) @@ -32,7 +32,7 @@ module.exports = class ValidateCommit extends EE { } } - disableRule(id) { + disableRule (id) { if (!this.rules.has(id)) { throw new TypeError(`Invalid rule: "${id}"`) } @@ -40,7 +40,7 @@ module.exports = class ValidateCommit extends EE { this.rules.get(id).disabled = true } - lint(str) { + lint (str) { if (Array.isArray(str)) { for (const item of str) { this.lint(item) @@ -54,22 +54,21 @@ module.exports = class ValidateCommit extends EE { setImmediate(() => { this.emit('commit', { - commit: commit - , messages: this.messages.get(commit.sha) || [] + commit: commit, + messages: this.messages.get(commit.sha) || [] }) }) } } - report(opts) { + report (opts) { const commit = opts.commit const sha = commit.sha if (!sha) { throw new Error('Invalid report. Missing commit sha') } - if (opts.data.level === 'fail') - this.errors++ + if (opts.data.level === 'fail') { this.errors++ } const ar = this.messages.get(sha) || [] ar.push(opts.data) this.messages.set(sha, ar) diff --git a/lib/rule.js b/lib/rule.js index aece7ed..f6e2d95 100644 --- a/lib/rule.js +++ b/lib/rule.js @@ -1,11 +1,11 @@ 'use strict' module.exports = class Rule { - constructor(opts) { + constructor (opts) { opts = Object.assign({ - options: {} - , defaults: {} - , meta: {} + options: {}, + defaults: {}, + meta: {} }, opts) if (!opts.id) { @@ -24,7 +24,7 @@ module.exports = class Rule { this._validate = opts.validate } - validate(commit) { + validate (commit) { this._validate(commit, this) } } diff --git a/lib/rules/fixes-url.js b/lib/rules/fixes-url.js index 3b32ea7..fa8b42f 100644 --- a/lib/rules/fixes-url.js +++ b/lib/rules/fixes-url.js @@ -6,21 +6,21 @@ const github = new RegExp('^https://github\.com/[\\w-]+\/[\\w-]+/' + ) module.exports = { - id: id -, meta: { - description: 'enforce format of Fixes URLs' - , recommended: true - } -, defaults: {} -, options: {} -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce format of Fixes URLs', + recommended: true + }, + defaults: {}, + options: {}, + validate: (context, rule) => { const parsed = context.toJSON() if (!Array.isArray(parsed.fixes) || !parsed.fixes.length) { context.report({ - id: id - , message: 'skipping fixes-url' - , string: '' - , level: 'skip' + id: id, + message: 'skipping fixes-url', + string: '', + level: 'skip' }) return } @@ -31,68 +31,68 @@ module.exports = { if (url[0] === '#') { // See nodejs/node#2aa376914b621018c5784104b82c13e78ee51307 // for an example - const {line, column} = findLineAndColumn(context.body, url) + const { line, column } = findLineAndColumn(context.body, url) context.report({ - id: id - , message: 'Fixes must be a URL, not an issue number.' - , string: url - , line: line - , column: column - , level: 'fail' + id: id, + message: 'Fixes must be a URL, not an issue number.', + string: url, + line: line, + column: column, + level: 'fail' }) } else if (match) { if (match[1] === 'pull' && match[2] === undefined) { - const {line, column} = findLineAndColumn(context.body, url) + const { line, column } = findLineAndColumn(context.body, url) context.report({ - id: id - , message: 'Pull request URL must reference a comment or discussion.' - , string: url - , line: line - , column: column - , level: 'fail' + id: id, + message: 'Pull request URL must reference a comment or discussion.', + string: url, + line: line, + column: column, + level: 'fail' }) } else { - const {line, column} = findLineAndColumn(context.body, url) + const { line, column } = findLineAndColumn(context.body, url) context.report({ - id: id - , message: 'Valid fixes URL.' - , string: url - , line: line - , column: column - , level: 'pass' + id: id, + message: 'Valid fixes URL.', + string: url, + line: line, + column: column, + level: 'pass' }) } } else { - const {line, column} = findLineAndColumn(context.body, url) + const { line, column } = findLineAndColumn(context.body, url) context.report({ - id: id - , message: 'Fixes must be a GitHub URL.' - , string: url - , line: line - , column: column - , level: 'fail' + id: id, + message: 'Fixes must be a GitHub URL.', + string: url, + line: line, + column: column, + level: 'fail' }) } } } } -function findLineAndColumn(body, str) { +function findLineAndColumn (body, str) { for (let i = 0; i < body.length; i++) { const l = body[i] if (~l.indexOf('Fixes')) { const idx = l.indexOf(str) if (idx !== -1) { return { - line: i - , column: idx + line: i, + column: idx } } } } return { - line: -1 - , column: -1 + line: -1, + column: -1 } } diff --git a/lib/rules/line-after-title.js b/lib/rules/line-after-title.js index d976479..9c64f02 100644 --- a/lib/rules/line-after-title.js +++ b/lib/rules/line-after-title.js @@ -3,32 +3,32 @@ const id = 'line-after-title' module.exports = { - id: id -, meta: { - description: 'enforce a blank newline after the commit title' - , recommended: true - } -, defaults: {} -, options: {} -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce a blank newline after the commit title', + recommended: true + }, + defaults: {}, + options: {}, + validate: (context, rule) => { // all commits should have a body and a blank line after the title if (context.body[0]) { context.report({ - id: id - , message: 'blank line expected after title' - , string: context.body.length ? context.body[0] : '' - , line: 1 - , column: 0 - , level: 'fail' + id: id, + message: 'blank line expected after title', + string: context.body.length ? context.body[0] : '', + line: 1, + column: 0, + level: 'fail' }) return } context.report({ - id: id - , message: 'blank line after title' - , string: '' - , level: 'pass' + id: id, + message: 'blank line after title', + string: '', + level: 'pass' }) } } diff --git a/lib/rules/line-length.js b/lib/rules/line-length.js index a59ea2a..b335d72 100644 --- a/lib/rules/line-length.js +++ b/lib/rules/line-length.js @@ -3,28 +3,28 @@ const id = 'line-length' module.exports = { - id: id -, meta: { - description: 'enforce max length of lines in commit body' - , recommended: true - } -, defaults: { + id: id, + meta: { + description: 'enforce max length of lines in commit body', + recommended: true + }, + defaults: { length: 72 - } -, options: { + }, + options: { length: 72 - } -, validate: (context, rule) => { + }, + validate: (context, rule) => { const len = rule.options.length const parsed = context.toJSON() // release commits include the notable changes from the changelog // in the commit message if (parsed.release) { context.report({ - id: id - , message: 'skipping line-length for release commit' - , string: '' - , level: 'skip' + id: id, + message: 'skipping line-length for release commit', + string: '', + level: 'skip' }) return } @@ -32,31 +32,29 @@ module.exports = { for (let i = 0; i < parsed.body.length; i++) { const line = parsed.body[i] // Skip quoted lines, e.g. for original commit messages of V8 backports. - if (line.startsWith(' ')) - continue + if (line.startsWith(' ')) { continue } // Skip lines with URLs. - if (/https?:\/\//.test(line)) - continue + if (/https?:\/\//.test(line)) { continue } if (line.length > len) { failed = true context.report({ - id: id - , message: `Line should be <= ${len} columns.` - , string: line - , maxLength: len - , line: i - , column: len - , level: 'fail' + id: id, + message: `Line should be <= ${len} columns.`, + string: line, + maxLength: len, + line: i, + column: len, + level: 'fail' }) } } if (!failed) { context.report({ - id: id - , message: 'line-lengths are valid' - , string: '' - , level: 'pass' + id: id, + message: 'line-lengths are valid', + string: '', + level: 'pass' }) } } diff --git a/lib/rules/metadata-end.js b/lib/rules/metadata-end.js index bfe3a1a..f4c9bb3 100644 --- a/lib/rules/metadata-end.js +++ b/lib/rules/metadata-end.js @@ -3,14 +3,14 @@ const id = 'metadata-end' module.exports = { - id: id -, meta: { - description: 'enforce that metadata is at the end of commit messages' - , recommended: true - } -, defaults: {} -, options: {} -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce that metadata is at the end of commit messages', + recommended: true + }, + defaults: {}, + options: {}, + validate: (context, rule) => { const parsed = context.toJSON() const body = parsed.body const end = parsed.metadata.end @@ -26,22 +26,22 @@ module.exports = { if (lineNum !== end + 1) { context.report({ - id: id - , message: 'commit metadata at end of message' - , string: body[lineNum] - , line: lineNum - , column: 0 - , level: 'fail' + id: id, + message: 'commit metadata at end of message', + string: body[lineNum], + line: lineNum, + column: 0, + level: 'fail' }) return } } context.report({ - id: id - , message: 'metadata is at end of message' - , string: '' - , level: 'pass' + id: id, + message: 'metadata is at end of message', + string: '', + level: 'pass' }) } } diff --git a/lib/rules/pr-url.js b/lib/rules/pr-url.js index b42607f..75d2cc3 100644 --- a/lib/rules/pr-url.js +++ b/lib/rules/pr-url.js @@ -4,22 +4,22 @@ const id = 'pr-url' const prUrl = /^https:\/\/github\.com\/[\w-]+\/[\w-]+\/pull\/\d+$/ module.exports = { - id: id -, meta: { - description: 'enforce PR-URL' - , recommended: true - } -, defaults: {} -, options: {} -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce PR-URL', + recommended: true + }, + defaults: {}, + options: {}, + validate: (context, rule) => { if (!context.prUrl) { context.report({ - id: id - , message: 'Commit must have a PR-URL.' - , string: context.prUrl - , line: 0 - , column: 0 - , level: 'fail' + id: id, + message: 'Commit must have a PR-URL.', + string: context.prUrl, + line: 0, + column: 0, + level: 'fail' }) return } @@ -36,30 +36,30 @@ module.exports = { // see nodejs/node#7d3a7ea0d7df9b6f11df723dec370f49f4f87e99 // for an example context.report({ - id: id - , message: 'PR-URL must be a URL, not a pull request number.' - , string: context.prUrl - , line: line - , column: column - , level: 'fail' + id: id, + message: 'PR-URL must be a URL, not a pull request number.', + string: context.prUrl, + line: line, + column: column, + level: 'fail' }) } else if (!prUrl.test(context.prUrl)) { context.report({ - id: id - , message: 'PR-URL must be a GitHub pull request URL.' - , string: context.prUrl - , line: line - , column: column - , level: 'fail' + id: id, + message: 'PR-URL must be a GitHub pull request URL.', + string: context.prUrl, + line: line, + column: column, + level: 'fail' }) } else { context.report({ - id: id - , message: 'PR-URL is valid.' - , string: context.prUrl - , line: line - , column: column - , level: 'pass' + id: id, + message: 'PR-URL is valid.', + string: context.prUrl, + line: line, + column: column, + level: 'pass' }) } } diff --git a/lib/rules/reviewers.js b/lib/rules/reviewers.js index 7450210..e00cf9d 100644 --- a/lib/rules/reviewers.js +++ b/lib/rules/reviewers.js @@ -3,22 +3,22 @@ const id = 'reviewers' module.exports = { - id: id -, meta: { - description: 'enforce having reviewers' - , recommended: true - } -, defaults: {} -, options: {} -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce having reviewers', + recommended: true + }, + defaults: {}, + options: {}, + validate: (context, rule) => { const parsed = context.toJSON() // release commits generally won't have any reviewers if (parsed.release) { context.report({ - id: id - , message: 'skipping reviewers for release commit' - , string: '' - , level: 'skip' + id: id, + message: 'skipping reviewers for release commit', + string: '', + level: 'skip' }) return } @@ -27,12 +27,12 @@ module.exports = { // See nodejs/node#5aac4c42da104c30d8f701f1042d61c2f06b7e6c // for an example return context.report({ - id: id - , message: 'Commit must have at least 1 reviewer.' - , string: null - , line: 0 - , column: 0 - , level: 'fail' + id: id, + message: 'Commit must have at least 1 reviewer.', + string: null, + line: 0, + column: 0, + level: 'fail' }) } @@ -42,10 +42,10 @@ module.exports = { // of strings context.report({ - id: id - , message: 'reviewers are valid' - , string: '' - , level: 'pass' + id: id, + message: 'reviewers are valid', + string: '', + level: 'pass' }) } } diff --git a/lib/rules/subsystem.js b/lib/rules/subsystem.js index 4b6264c..2ac53aa 100644 --- a/lib/rules/subsystem.js +++ b/lib/rules/subsystem.js @@ -3,111 +3,111 @@ const id = 'subsystem' const validSubsystems = [ - 'benchmark' -, 'build' -, 'bootstrap' -, 'cli' -, 'deps' -, 'doc' -, 'errors' -, 'etw' -, 'esm' -, 'gyp' -, 'inspector' -, 'lib' -, 'loader' -, 'meta' -, 'msi' -, 'node' -, 'n-api' -, 'perfctr' -, 'policy' -, 'src' -, 'test' -, 'tools' -, 'wasm' -, 'win' + 'benchmark', + 'build', + 'bootstrap', + 'cli', + 'deps', + 'doc', + 'errors', + 'etw', + 'esm', + 'gyp', + 'inspector', + 'lib', + 'loader', + 'meta', + 'msi', + 'node', + 'n-api', + 'perfctr', + 'policy', + 'src', + 'test', + 'tools', + 'wasm', + 'win', // core libs -, 'assert' -, 'async_hooks' -, 'buffer' -, 'child_process' -, 'cluster' -, 'console' -, 'constants' -, 'crypto' -, 'debugger' -, 'dgram' -, 'dns' -, 'domain' -, 'events' -, 'fs' -, 'http' -, 'http2' -, 'https' -, 'inspector' -, 'module' -, 'net' -, 'os' -, 'path' -, 'perf_hooks' -, 'process' -, 'punycode' -, 'querystring' -, 'quic' -, 'readline' -, 'repl' -, 'report' -, 'stream' -, 'string_decoder' -, 'sys' -, 'timers' -, 'tls' -, 'trace_events' -, 'tty' -, 'url' -, 'util' -, 'v8' -, 'vm' -, 'wasi' -, 'worker' -, 'zlib' + 'assert', + 'async_hooks', + 'buffer', + 'child_process', + 'cluster', + 'console', + 'constants', + 'crypto', + 'debugger', + 'dgram', + 'dns', + 'domain', + 'events', + 'fs', + 'http', + 'http2', + 'https', + 'inspector', + 'module', + 'net', + 'os', + 'path', + 'perf_hooks', + 'process', + 'punycode', + 'querystring', + 'quic', + 'readline', + 'repl', + 'report', + 'stream', + 'string_decoder', + 'sys', + 'timers', + 'tls', + 'trace_events', + 'tty', + 'url', + 'util', + 'v8', + 'vm', + 'wasi', + 'worker', + 'zlib' ] module.exports = { - id: id -, meta: { - description: 'enforce subsystem validity' - , recommended: true - } -, defaults: { + id: id, + meta: { + description: 'enforce subsystem validity', + recommended: true + }, + defaults: { subsystems: validSubsystems - } -, options: { + }, + options: { subsystems: validSubsystems - } -, validate: (context, rule) => { + }, + validate: (context, rule) => { const subs = rule.options.subsystems const parsed = context.toJSON() if (!parsed.subsystems.length) { if (!parsed.release && !parsed.working) { // Missing subsystem context.report({ - id: id - , message: 'Missing subsystem.' - , string: parsed.title - , line: 0 - , column: 0 - , level: 'fail' - , wanted: subs + id: id, + message: 'Missing subsystem.', + string: parsed.title, + line: 0, + column: 0, + level: 'fail', + wanted: subs }) } else { context.report({ - id: id - , message: 'Release commits do not have subsystems' - , string: '' - , level: 'skip' + id: id, + message: 'Release commits do not have subsystems', + string: '', + level: 'skip' }) } } else { @@ -118,23 +118,23 @@ module.exports = { // invalid subsystem const column = parsed.title.indexOf(sub) context.report({ - id: id - , message: `Invalid subsystem: "${sub}"` - , string: parsed.title - , line: 0 - , column: column - , level: 'fail' - , wanted: subs + id: id, + message: `Invalid subsystem: "${sub}"`, + string: parsed.title, + line: 0, + column: column, + level: 'fail', + wanted: subs }) } } if (!failed) { context.report({ - id: id - , message: 'valid subsystems' - , string: parsed.subsystems.join(',') - , level: 'pass' + id: id, + message: 'valid subsystems', + string: parsed.subsystems.join(','), + level: 'pass' }) } } diff --git a/lib/rules/title-format.js b/lib/rules/title-format.js index c070311..12cc2a1 100644 --- a/lib/rules/title-format.js +++ b/lib/rules/title-format.js @@ -3,21 +3,21 @@ const id = 'title-format' module.exports = { - id: id -, meta: { - description: 'enforce commit title format' - , recommended: true - } -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce commit title format', + recommended: true + }, + validate: (context, rule) => { let pass = true if (/[\.\?\!]$/.test(context.title)) { context.report({ - id: id - , message: 'Do not use punctuation at end of title.' - , string: context.title - , line: 0 - , column: context.title.length - , level: 'fail' + id: id, + message: 'Do not use punctuation at end of title.', + string: context.title, + line: 0, + column: context.title.length, + level: 'fail' }) pass = false } @@ -26,12 +26,12 @@ module.exports = { const result = /^([^:]+:)[^ ]/.exec(context.title) if (result) { context.report({ - id: id - , message: 'Add a space after subsystem(s).' - , string: context.title - , line: 0 - , column: result[1].length - , level: 'fail' + id: id, + message: 'Add a space after subsystem(s).', + string: context.title, + line: 0, + column: result[1].length, + level: 'fail' }) pass = false } @@ -41,12 +41,12 @@ module.exports = { const result = /\s\s/.exec(context.title) if (result) { context.report({ - id: id - , message: 'Do not use consecutive spaces in title.' - , string: context.title - , line: 0 - , column: result.index + 1 - , level: 'fail' + id: id, + message: 'Do not use consecutive spaces in title.', + string: context.title, + line: 0, + column: result.index + 1, + level: 'fail' }) pass = false } @@ -57,12 +57,12 @@ module.exports = { const result = /^([^:]+?): [A-Z]/.exec(context.title) if (result) { context.report({ - id: id - , message: 'First word after subsystem(s) in title should be lowercase.' - , string: context.title - , line: 0 - , column: result[1].length + 3 - , level: 'fail' + id: id, + message: 'First word after subsystem(s) in title should be lowercase.', + string: context.title, + line: 0, + column: result[1].length + 3, + level: 'fail' }) pass = false } @@ -70,10 +70,10 @@ module.exports = { if (pass) { context.report({ - id: id - , message: 'Title is formatted correctly.' - , string: '' - , level: 'pass' + id: id, + message: 'Title is formatted correctly.', + string: '', + level: 'pass' }) } } diff --git a/lib/rules/title-length.js b/lib/rules/title-length.js index 330105e..8b8229e 100644 --- a/lib/rules/title-length.js +++ b/lib/rules/title-length.js @@ -3,30 +3,30 @@ const id = 'title-length' module.exports = { - id: id -, meta: { - description: 'enforce max length of commit title' - , recommended: true - } -, defaults: { - length: 50 - , max_length: 72 - } -, options: { - length: 50 - , max_length: 72 - } -, validate: (context, rule) => { + id: id, + meta: { + description: 'enforce max length of commit title', + recommended: true + }, + defaults: { + length: 50, + max_length: 72 + }, + options: { + length: 50, + max_length: 72 + }, + validate: (context, rule) => { const max = rule.options.max_length if (context.title.length > max) { context.report({ - id: id - , message: `Title must be <= ${max} columns.` - , string: context.title - , maxLength: max - , line: 0 - , column: max - , level: 'fail' + id: id, + message: `Title must be <= ${max} columns.`, + string: context.title, + maxLength: max, + line: 0, + column: max, + level: 'fail' }) return } @@ -34,22 +34,22 @@ module.exports = { const len = rule.options.length if (context.title.length > len) { context.report({ - id: id - , message: `Title should be <= ${len} columns.` - , string: context.title - , maxLength: len - , line: 0 - , column: len - , level: 'warn' + id: id, + message: `Title should be <= ${len} columns.`, + string: context.title, + maxLength: len, + line: 0, + column: len, + level: 'warn' }) return } context.report({ - id: id - , message: `Title is <= ${len} columns.` - , string: '' - , level: 'pass' + id: id, + message: `Title is <= ${len} columns.`, + string: '', + level: 'pass' }) } } diff --git a/lib/tap.js b/lib/tap.js index bdfc200..aec27d5 100644 --- a/lib/tap.js +++ b/lib/tap.js @@ -3,7 +3,7 @@ const util = require('util') class Test { - constructor(tap, name) { + constructor (tap, name) { this.tap = tap this.name = name this._count = 0 @@ -13,13 +13,13 @@ class Test { this.begin() } - pass(msg) { + pass (msg) { this.tap.write(`ok ${++this._count} ${msg}`) this._passes++ this.tap.pass() } - fail(msg, extra) { + fail (msg, extra) { this.tap.write(`not ok ${++this._count} ${msg}`) if (extra) { this.tap.write(' ---') @@ -38,13 +38,13 @@ class Test { this.tap.fail() } - skip(msg) { + skip (msg) { this.tap.write(`ok ${++this._count} ${msg} # SKIP`) this._skips++ this.tap.skip() } - begin() { + begin () { this.tap.write(`# ${this.name}`) } } @@ -52,7 +52,7 @@ class Test { const Readable = require('stream').Readable module.exports = class Tap extends Readable { - constructor() { + constructor () { super() this._wroteVersion = false this._count = 0 @@ -61,7 +61,7 @@ module.exports = class Tap extends Readable { this._skips = 0 } - get status() { + get status () { if (this._failures) { return 'fail' } @@ -69,40 +69,40 @@ module.exports = class Tap extends Readable { return 'pass' } - writeVersion() { + writeVersion () { if (!this._wroteVersion) { this.write('TAP version 13') this._wroteVersion = true } } - pass() { + pass () { this._passes++ this._count++ } - fail() { + fail () { this._failures++ this._count++ } - skip() { + skip () { this._skips++ this._count++ } - write(str = '') { + write (str = '') { this.push(`${str}\n`) } - test(name) { + test (name) { const t = new Test(this, name) return t } - _read() {} + _read () {} - end() { + end () { this.write() this.write(`0..${this._count}`) this.write(`# tests ${this._count}`) diff --git a/lib/utils.js b/lib/utils.js index 49dd75d..54e3b64 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -9,7 +9,7 @@ exports.CHECK = CHECK exports.X = X exports.WARN = WARN -exports.rightPad = function rightPad(str, max) { +exports.rightPad = function rightPad (str, max) { const diff = max - str.length + 1 if (diff > 0) { return `${str}${' '.repeat(diff)}` @@ -17,7 +17,7 @@ exports.rightPad = function rightPad(str, max) { return str } -exports.leftPad = function leftPad(str, max) { +exports.leftPad = function leftPad (str, max) { const diff = max - str.length + 1 if (diff > 0) { return `${' '.repeat(diff)}${str}` @@ -38,7 +38,7 @@ exports.header = (sha, status) => { } } -exports.describeRule = function describeRule(rule, max = 20) { +exports.describeRule = function describeRule (rule, max = 20) { if (rule.meta && rule.meta.description) { const desc = rule.meta.description const title = exports.leftPad(rule.id, max) @@ -46,13 +46,13 @@ exports.describeRule = function describeRule(rule, max = 20) { } } -exports.describeSubsystem = function describeSubsystem(subsystems, max = 20) { +exports.describeSubsystem = function describeSubsystem (subsystems, max = 20) { if (subsystems) { for (let sub = 0; sub < subsystems.length; sub = sub + 3) { console.log('%s %s %s', - chalk.green(exports.leftPad(subsystems[sub] || '', max)), - chalk.green(exports.leftPad(subsystems[sub + 1] || '', max)), - chalk.green(exports.leftPad(subsystems[sub + 2] || '', max)) + chalk.green(exports.leftPad(subsystems[sub] || '', max)), + chalk.green(exports.leftPad(subsystems[sub + 1] || '', max)), + chalk.green(exports.leftPad(subsystems[sub + 2] || '', max)) ) } } diff --git a/test/cli-test.js b/test/cli-test.js index e1ba08e..04fc0bf 100644 --- a/test/cli-test.js +++ b/test/cli-test.js @@ -1,13 +1,13 @@ 'use strict' -const {test} = require('tap') -const {spawn} = require('child_process') +const { test } = require('tap') +const { spawn } = require('child_process') const subsystems = require('../lib/rules/subsystem') test('Test cli flags', (t) => { t.test('test list-subsystems', (tt) => { const ls = spawn('./bin/cmd.js', ['--list-subsystems'], { - env: {FORCE_COLOR: 0} + env: { FORCE_COLOR: 0 } }) let compiledData = '' ls.stdout.on('data', (data) => { @@ -25,14 +25,14 @@ test('Test cli flags', (t) => { const defaultSubsystems = subsystems.defaults.subsystems tt.equal(subsystemsFromOutput.length, - defaultSubsystems.length, - 'Should have the same length') + defaultSubsystems.length, + 'Should have the same length') // Loop through the output list and compare with the real list // to make sure they are all there const missing = [] subsystemsFromOutput.forEach((sub) => { - if (!defaultSubsystems.find((x) => {return x === sub})) { + if (!defaultSubsystems.find((x) => { return x === sub })) { missing.push(sub) } }) @@ -55,8 +55,8 @@ test('Test cli flags', (t) => { ls.on('close', (code) => { tt.equal(compiledData.trim(), - `core-validate-commit v${require('../package.json').version}`, - 'output is equal') + `core-validate-commit v${require('../package.json').version}`, + 'output is equal') tt.end() }) }) diff --git a/test/rule-test.js b/test/rule-test.js index f6da50e..fbc675a 100644 --- a/test/rule-test.js +++ b/test/rule-test.js @@ -14,7 +14,7 @@ test('Base Rule Test', (t) => { t.test('No validate function', (tt) => { tt.throws(() => { - new BaseRule({id: 'test-rule'}) + new BaseRule({ id: 'test-rule' }) }, 'Rule must have validate function') tt.end() diff --git a/test/rules/fixes-url.js b/test/rules/fixes-url.js index f3bcbba..2b016e0 100644 --- a/test/rules/fixes-url.js +++ b/test/rules/fixes-url.js @@ -12,34 +12,34 @@ const VALID_FIXES_URL = 'Valid fixes URL.' const makeCommit = (msg) => { return new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: msg + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: msg }, new Validator()) } test('rule: fixes-url', (t) => { const valid = [ - [ 'GitHub issue URL' - , 'https://github.com/nodejs/node/issues/1234' ] - , [ 'GitHub issue URL containing hyphen' - , 'https://github.com/nodejs/node-report/issues/1234' ] - , [ 'GitHub issue URL containing hyphen with comment' - , 'https://github.com/nodejs/node-report/issues/1234#issuecomment-1234' ] - , [ 'GitHub issue URL with comment' - , 'https://github.com/nodejs/node/issues/1234#issuecomment-1234' ] - , [ 'GitHub PR URL containing hyphen with comment' - , 'https://github.com/nodejs/node-report/pull/1234#issuecomment-1234' ] - , [ 'GitHub PR URL containing hyphen with discussion comment' - , 'https://github.com/nodejs/node-report/pull/1234#discussion_r1234' ] - , [ 'GitHub PR URL with comment' - , 'https://github.com/nodejs/node/pull/1234#issuecomment-1234' ] - , [ 'GitHub PR URL with discussion comment' - , 'https://github.com/nodejs/node/pull/1234#discussion_r1234' ] + [ 'GitHub issue URL', + 'https://github.com/nodejs/node/issues/1234' ], + [ 'GitHub issue URL containing hyphen', + 'https://github.com/nodejs/node-report/issues/1234' ], + [ 'GitHub issue URL containing hyphen with comment', + 'https://github.com/nodejs/node-report/issues/1234#issuecomment-1234' ], + [ 'GitHub issue URL with comment', + 'https://github.com/nodejs/node/issues/1234#issuecomment-1234' ], + [ 'GitHub PR URL containing hyphen with comment', + 'https://github.com/nodejs/node-report/pull/1234#issuecomment-1234' ], + [ 'GitHub PR URL containing hyphen with discussion comment', + 'https://github.com/nodejs/node-report/pull/1234#discussion_r1234' ], + [ 'GitHub PR URL with comment', + 'https://github.com/nodejs/node/pull/1234#issuecomment-1234' ], + [ 'GitHub PR URL with discussion comment', + 'https://github.com/nodejs/node/pull/1234#discussion_r1234' ] ] for (const [name, url] of valid) { @@ -65,16 +65,16 @@ Fixes: ${url}` } const invalid = [ - [ 'issue number', NOT_AN_ISSUE_NUMBER - , '#1234' ] - , [ 'GitHub PR URL', INVALID_PRURL - , 'https://github.com/nodejs/node/pull/1234' ] - , [ 'GitHub PR URL containing hyphen', INVALID_PRURL - , 'https://github.com/nodejs/node-report/pull/1234' ] - , [ 'non-GitHub URL', NOT_A_GITHUB_URL - , 'https://nodejs.org' ] - , [ 'not a URL or issue number', NOT_A_GITHUB_URL - , 'fhqwhgads' ] + [ 'issue number', NOT_AN_ISSUE_NUMBER, + '#1234' ], + [ 'GitHub PR URL', INVALID_PRURL, + 'https://github.com/nodejs/node/pull/1234' ], + [ 'GitHub PR URL containing hyphen', INVALID_PRURL, + 'https://github.com/nodejs/node-report/pull/1234' ], + [ 'non-GitHub URL', NOT_A_GITHUB_URL, + 'https://nodejs.org' ], + [ 'not a URL or issue number', NOT_A_GITHUB_URL, + 'fhqwhgads' ] ] for (const [name, expected, url] of invalid) { t.test(name, (tt) => { diff --git a/test/rules/line-after-title.js b/test/rules/line-after-title.js index 4b99afd..acc8008 100644 --- a/test/rules/line-after-title.js +++ b/test/rules/line-after-title.js @@ -10,13 +10,13 @@ test('rule: line-after-title', (t) => { tt.plan(7) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: 'test: fix something\nfhqwhgads' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: 'test: fix something\nfhqwhgads' }, v) context.report = (opts) => { @@ -36,13 +36,13 @@ test('rule: line-after-title', (t) => { tt.plan(4) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: 'test: fix something\n\nfhqwhgads' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: 'test: fix something\n\nfhqwhgads' }, v) context.report = (opts) => { @@ -59,13 +59,13 @@ test('rule: line-after-title', (t) => { tt.plan(4) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: 'test: fix something' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: 'test: fix something' }, v) context.report = (opts) => { diff --git a/test/rules/line-length.js b/test/rules/line-length.js index 9c5fac0..50e65cb 100644 --- a/test/rules/line-length.js +++ b/test/rules/line-length.js @@ -10,13 +10,13 @@ test('rule: line-length', (t) => { tt.plan(7) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `test: fix something + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `test: fix something ${'aaa'.repeat(30)}` }, v) @@ -41,13 +41,13 @@ ${'aaa'.repeat(30)}` t.test('release commit', (tt) => { const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `2016-01-01, Version 1.0.0 + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `2016-01-01, Version 1.0.0 ${'aaa'.repeat(30)}` }, v) @@ -70,13 +70,13 @@ ${'aaa'.repeat(30)}` t.test('quoted lines', (tt) => { const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `src: make foo mor foo-ey + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `src: make foo mor foo-ey Here’s the original code: @@ -104,13 +104,13 @@ That was the original code. t.test('URLs', (tt) => { const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `src: make foo mor foo-ey + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `src: make foo mor foo-ey https://${'very-'.repeat(80)}-long-url.org/ ` diff --git a/test/rules/pr-url.js b/test/rules/pr-url.js index 8893649..3c34770 100644 --- a/test/rules/pr-url.js +++ b/test/rules/pr-url.js @@ -11,8 +11,8 @@ test('rule: pr-url', (t) => { t.test('missing', (tt) => { tt.plan(7) const context = { - prUrl: null - , report: (opts) => { + prUrl: null, + report: (opts) => { tt.pass('called report') tt.equal(opts.id, 'pr-url', 'id') tt.equal(opts.message, MISSING_PR_URL, 'message') @@ -26,16 +26,15 @@ test('rule: pr-url', (t) => { Rule.validate(context) }) - t.test('invalid numeric', (tt) => { tt.plan(7) const context = { - prUrl: '#1234' - , body: [ - '' - , 'PR-URL: #1234' - ] - , report: (opts) => { + prUrl: '#1234', + body: [ + '', + 'PR-URL: #1234' + ], + report: (opts) => { tt.pass('called report') tt.equal(opts.id, 'pr-url', 'id') tt.equal(opts.message, NUMERIC_PR_URL, 'message') @@ -53,12 +52,12 @@ test('rule: pr-url', (t) => { tt.plan(7) const url = 'https://github.com/nodejs/node/issues/1234' const context = { - prUrl: url - , body: [ - '' - , `PR-URL: ${url}` - ] - , report: (opts) => { + prUrl: url, + body: [ + '', + `PR-URL: ${url}` + ], + report: (opts) => { tt.pass('called report') tt.equal(opts.id, 'pr-url', 'id') tt.equal(opts.message, INVALID_PR_URL, 'message') @@ -76,12 +75,12 @@ test('rule: pr-url', (t) => { tt.plan(7) const url = 'https://github.com/nodejs/node/pull/1234' const context = { - prUrl: url - , body: [ - '' - , `PR-URL: ${url}` - ] - , report: (opts) => { + prUrl: url, + body: [ + '', + `PR-URL: ${url}` + ], + report: (opts) => { tt.pass('called report') tt.equal(opts.id, 'pr-url', 'id') tt.equal(opts.message, VALID_PR_URL, 'message') @@ -99,12 +98,12 @@ test('rule: pr-url', (t) => { tt.plan(7) const url = 'https://github.com/nodejs/node-report/pull/1234' const context = { - prUrl: url - , body: [ - '' - , `PR-URL: ${url}` - ] - , report: (opts) => { + prUrl: url, + body: [ + '', + `PR-URL: ${url}` + ], + report: (opts) => { tt.pass('called report') tt.equal(opts.id, 'pr-url', 'id') tt.equal(opts.message, VALID_PR_URL, 'message') diff --git a/test/rules/reviewers.js b/test/rules/reviewers.js index eed8bfc..3ad7a4c 100644 --- a/test/rules/reviewers.js +++ b/test/rules/reviewers.js @@ -11,13 +11,13 @@ test('rule: reviewers', (t) => { tt.plan(7) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `test: fix something + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `test: fix something This is a test` }, v) @@ -39,13 +39,13 @@ This is a test` tt.plan(2) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: `2016-04-12, Version x.y.z + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: `2016-04-12, Version x.y.z This is a test` }, v) @@ -53,10 +53,10 @@ This is a test` context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'reviewers' - , message: 'skipping reviewers for release commit' - , string: '' - , level: 'skip' + id: 'reviewers', + message: 'skipping reviewers for release commit', + string: '', + level: 'skip' }) } diff --git a/test/rules/subsystem.js b/test/rules/subsystem.js index 4c3d096..9b9bef9 100644 --- a/test/rules/subsystem.js +++ b/test/rules/subsystem.js @@ -10,13 +10,13 @@ test('rule: subsystem', (t) => { tt.plan(7) const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: 'fhqwhgads: come on' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: 'fhqwhgads: come on' }, v) context.report = (opts) => { @@ -30,7 +30,7 @@ test('rule: subsystem', (t) => { tt.end() } - Rule.validate(context, {options: {subsystems: Rule.defaults.subsystems}}) + Rule.validate(context, { options: { subsystems: Rule.defaults.subsystems } }) }) t.test('skip for release commit', (tt) => { @@ -38,27 +38,27 @@ test('rule: subsystem', (t) => { const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: '2016-04-12, Version x.y.z' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: '2016-04-12, Version x.y.z' }, v) context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'subsystem' - , message: 'Release commits do not have subsystems' - , string: '' - , level: 'skip' + id: 'subsystem', + message: 'Release commits do not have subsystems', + string: '', + level: 'skip' }) tt.end() } - Rule.validate(context, {options: {subsystems: Rule.defaults.subsystems}}) + Rule.validate(context, { options: { subsystems: Rule.defaults.subsystems } }) }) t.test('valid', (tt) => { @@ -66,27 +66,27 @@ test('rule: subsystem', (t) => { const v = new Validator() const context = new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: 'quic: come on, fhqwhgads' + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: 'quic: come on, fhqwhgads' }, v) context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'subsystem' - , message: 'valid subsystems' - , string: 'quic' - , level: 'pass' + id: 'subsystem', + message: 'valid subsystems', + string: 'quic', + level: 'pass' }) tt.end() } - Rule.validate(context, {options: {subsystems: Rule.defaults.subsystems}}) + Rule.validate(context, { options: { subsystems: Rule.defaults.subsystems } }) }) t.end() }) diff --git a/test/rules/title-format.js b/test/rules/title-format.js index cc745cf..ab12101 100644 --- a/test/rules/title-format.js +++ b/test/rules/title-format.js @@ -5,16 +5,16 @@ const Rule = require('../../lib/rules/title-format') const Commit = require('gitlint-parser-node') const Validator = require('../../') -function makeCommit(title) { +function makeCommit (title) { const v = new Validator() return new Commit({ - sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea' - , author: { - name: 'Evan Lucas' - , email: 'evanlucas@me.com' - , date: '2016-04-12T19:42:23Z' - } - , message: title + sha: 'e7c077c610afa371430180fbd447bfef60ebc5ea', + author: { + name: 'Evan Lucas', + email: 'evanlucas@me.com', + date: '2016-04-12T19:42:23Z' + }, + message: title }, v) } @@ -26,12 +26,12 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'Add a space after subsystem(s).' - , string: 'test:missing space' - , line: 0 - , column: 5 - , level: 'fail' + id: 'title-format', + message: 'Add a space after subsystem(s).', + string: 'test:missing space', + line: 0, + column: 5, + level: 'fail' }) } @@ -46,10 +46,10 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'Title is formatted correctly.' - , string: '' - , level: 'pass' + id: 'title-format', + message: 'Title is formatted correctly.', + string: '', + level: 'pass' }) } @@ -64,12 +64,12 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'Do not use consecutive spaces in title.' - , string: 'test: with two spaces' - , line: 0 - , column: 11 - , level: 'fail' + id: 'title-format', + message: 'Do not use consecutive spaces in title.', + string: 'test: with two spaces', + line: 0, + column: 11, + level: 'fail' }) } @@ -84,12 +84,12 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'First word after subsystem(s) in title should be lowercase.' - , string: 'test: Some message' - , line: 0 - , column: 7 - , level: 'fail' + id: 'title-format', + message: 'First word after subsystem(s) in title should be lowercase.', + string: 'test: Some message', + line: 0, + column: 7, + level: 'fail' }) } @@ -104,10 +104,10 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'Title is formatted correctly.' - , string: '' - , level: 'pass' + id: 'title-format', + message: 'Title is formatted correctly.', + string: '', + level: 'pass' }) } @@ -122,10 +122,10 @@ test('rule: title-format', (t) => { context.report = (opts) => { tt.pass('called report') tt.strictSame(opts, { - id: 'title-format' - , message: 'Title is formatted correctly.' - , string: '' - , level: 'pass' + id: 'title-format', + message: 'Title is formatted correctly.', + string: '', + level: 'pass' }) } diff --git a/test/utils-test.js b/test/utils-test.js index 6caf50f..4de8824 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -1,6 +1,6 @@ 'use strict' -const {test} = require('tap') +const { test } = require('tap') const utils = require('../lib/utils') // We aren't testing the chalk library, so strip off the colors/styles it adds @@ -45,60 +45,60 @@ test('test utility functions', (t) => { t.test('test headers function - skip', (tt) => { const header = utils.header('abc123', 'skip') tt.equal(header.replace(stripAnsiRegex, ''), - '✔ abc123 # SKIPPED', - 'should be equal') + '✔ abc123 # SKIPPED', + 'should be equal') tt.end() }) t.test('test headers function - pass', (tt) => { const header = utils.header('abc123', 'pass') tt.equal(header.replace(stripAnsiRegex, ''), - '✔ abc123', - 'should be equal') + '✔ abc123', + 'should be equal') tt.end() }) t.test('test headers function - pass', (tt) => { const header = utils.header('abc123', 'pass') tt.equal(header.replace(stripAnsiRegex, ''), - '✔ abc123', - 'should be equal') + '✔ abc123', + 'should be equal') tt.end() }) t.test('test headers function - fail', (tt) => { const header = utils.header('abc123', 'fail') tt.equal(header.replace(stripAnsiRegex, ''), - '✖ abc123', - 'should be equal') + '✖ abc123', + 'should be equal') tt.end() }) t.test('test describeRule function', (tt) => { - function logger() { + function logger () { const args = [...arguments] tt.equal(args[1].replace(stripAnsiRegex, ''), - ' rule-id', 'has a title with padding') + ' rule-id', 'has a title with padding') tt.equal(args[2].replace(stripAnsiRegex, ''), - 'a description', 'has a description') + 'a description', 'has a description') } // overrite the console.log console.log = logger - utils.describeRule({id: 'rule-id', meta: {description: 'a description'}}) + utils.describeRule({ id: 'rule-id', meta: { description: 'a description' } }) // put it back console.log = originalConsoleLog tt.end() }) t.test('test describeRule function - no meta data description', (tt) => { - function logger() { + function logger () { tt.fails('should not reach here') } // overrite the console.log console.log = logger - utils.describeRule({id: 'rule-id', meta: {}}) + utils.describeRule({ id: 'rule-id', meta: {} }) tt.pass('no return value') // put it back @@ -107,7 +107,7 @@ test('test utility functions', (t) => { }) t.test('test describeSubsystem function - no subsystems', (tt) => { - function logger() { + function logger () { tt.fails('should not reach here') } diff --git a/test/validator.js b/test/validator.js index b126bd9..fdf9b10 100644 --- a/test/validator.js +++ b/test/validator.js @@ -304,8 +304,8 @@ test('Validator - real commits', (t) => { }) tt.equal(filtered.length, 1, 'messages.length') tt.equal(filtered[0].message, - 'Do not use punctuation at end of title.', - 'message') + 'Do not use punctuation at end of title.', + 'message') tt.end() }) }) @@ -322,8 +322,8 @@ test('Validator - real commits', (t) => { }) tt.equal(filtered.length, 1, 'messages.length') tt.equal(filtered[0].message, - 'First word after subsystem(s) in title should be lowercase.', - 'message') + 'First word after subsystem(s) in title should be lowercase.', + 'message') tt.equal(filtered[0].column, 7, 'column') tt.end() }) From 7847fe1a570929a650ab9dc79326eae678e40c93 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 14:57:51 -0400 Subject: [PATCH 03/11] chore: fix returns outside of functions and move functions to highest scope --- bin/cmd.js | 57 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/bin/cmd.js b/bin/cmd.js index fc20481..5a0a111 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -38,12 +38,13 @@ const parsed = nopt(knownOpts, shortHand) const usage = require('help')() if (parsed.help) { - return usage() + usage() + process.exit(0) } if (parsed.version) { console.log('core-validate-commit', 'v' + require('../package').version) - return + process.exit(0) } const args = parsed.argv.remain @@ -91,7 +92,7 @@ const v = new Validator(parsed) if (parsed['list-subsystems']) { utils.describeSubsystem(subsystem.defaults.subsystems.sort()) - return + process.exit(0) } if (parsed.list) { @@ -104,7 +105,7 @@ if (parsed.list) { for (const rule of v.rules.values()) { utils.describeRule(rule, max) } - return + process.exit(0) } if (parsed.tap) { @@ -127,35 +128,35 @@ if (parsed.tap) { } }) - function run() { - if (!args.length) return - const sha = args.shift() - load(sha, (err, data) => { - if (err) throw err - v.lint(data) - run() - }) - } - - run() + tapRun() } else { v.on('commit', (c) => { pretty(c.commit, c.messages, v) - run() + commitRun() }) - function run() { - if (!args.length) { - process.exitCode = v.errors - return - } - const sha = args.shift() - load(sha, (err, data) => { - if (err) throw err - v.lint(data) - }) - } + commitRun() +} + +function tapRun () { + if (!args.length) return + const sha = args.shift() + load(sha, (err, data) => { + if (err) throw err + v.lint(data) + tapRun() + }) +} - run() +function commitRun () { + if (!args.length) { + process.exitCode = v.errors + return + } + const sha = args.shift() + load(sha, (err, data) => { + if (err) throw err + v.lint(data) + }) } From 795e96b2d67bd2f87a55aae5a80c3723c449d3ba Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 14:58:11 -0400 Subject: [PATCH 04/11] test: run standard --fix again --- bin/cmd.js | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/bin/cmd.js b/bin/cmd.js index 5a0a111..c98a792 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -16,22 +16,22 @@ const Tap = require('../lib/tap') const utils = require('../lib/utils') const subsystem = require('../lib/rules/subsystem') const knownOpts = { - help: Boolean -, version: Boolean -, 'validate-metadata': Boolean -, tap: Boolean -, out: path -, list: Boolean -, 'list-subsystems': Boolean + help: Boolean, + version: Boolean, + 'validate-metadata': Boolean, + tap: Boolean, + out: path, + list: Boolean, + 'list-subsystems': Boolean } const shortHand = { - h: ['--help'] -, v: ['--version'] -, V: ['--validate-metadata'] -, t: ['--tap'] -, o: ['--out'] -, l: ['--list'] -, ls: ['--list-subsystems'] + h: ['--help'], + v: ['--version'], + V: ['--validate-metadata'], + t: ['--tap'], + o: ['--out'], + l: ['--list'], + ls: ['--list-subsystems'] } const parsed = nopt(knownOpts, shortHand) @@ -48,10 +48,9 @@ if (parsed.version) { } const args = parsed.argv.remain -if (!args.length) - args.push('HEAD') +if (!args.length) { args.push('HEAD') } -function load(sha, cb) { +function load (sha, cb) { const parsed = url.parse(sha) if (parsed.protocol) { return loadPatch(parsed, cb) @@ -63,7 +62,7 @@ function load(sha, cb) { }) } -function loadPatch(uri, cb) { +function loadPatch (uri, cb) { let h = http if (~uri.protocol.indexOf('https')) { h = https @@ -122,14 +121,12 @@ if (parsed.tap) { if (count === total) { setImmediate(() => { tap.end() - if (tap.status === 'fail') - process.exitCode = 1 + if (tap.status === 'fail') { process.exitCode = 1 } }) } }) tapRun() - } else { v.on('commit', (c) => { pretty(c.commit, c.messages, v) From 3b4baa93f7f2971219bda23bfe7612406da757e6 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:01:06 -0400 Subject: [PATCH 05/11] test: fix 'no-new' errors --- test/rule-test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/rule-test.js b/test/rule-test.js index fbc675a..c721676 100644 --- a/test/rule-test.js +++ b/test/rule-test.js @@ -6,7 +6,8 @@ const BaseRule = require('../lib/rule') test('Base Rule Test', (t) => { t.test('No id param', (tt) => { tt.throws(() => { - new BaseRule() + const Rule = new BaseRule() + Rule() }, 'Rule must have an id') tt.end() @@ -14,7 +15,8 @@ test('Base Rule Test', (t) => { t.test('No validate function', (tt) => { tt.throws(() => { - new BaseRule({ id: 'test-rule' }) + const Rule = new BaseRule({ id: 'test-rule' }) + Rule() }, 'Rule must have validate function') tt.end() From e1b76e2296aaea2fe539444ebd8e31057f9388c5 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:03:17 -0400 Subject: [PATCH 06/11] test: fix no-useless-escape errors --- lib/rules/fixes-url.js | 2 +- lib/rules/title-format.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rules/fixes-url.js b/lib/rules/fixes-url.js index fa8b42f..55db4f8 100644 --- a/lib/rules/fixes-url.js +++ b/lib/rules/fixes-url.js @@ -1,7 +1,7 @@ 'use strict' const id = 'fixes-url' -const github = new RegExp('^https://github\.com/[\\w-]+\/[\\w-]+/' + +const github = new RegExp('^https://github.com/[\\w-]+/[\\w-]+/' + '(issues|pull)/\\d+(#issuecomment-\\d+|#discussion_r\\d+)?$' ) diff --git a/lib/rules/title-format.js b/lib/rules/title-format.js index 12cc2a1..da4518e 100644 --- a/lib/rules/title-format.js +++ b/lib/rules/title-format.js @@ -10,7 +10,7 @@ module.exports = { }, validate: (context, rule) => { let pass = true - if (/[\.\?\!]$/.test(context.title)) { + if (/[.?!]$/.test(context.title)) { context.report({ id: id, message: 'Do not use punctuation at end of title.', From 05460f05b572c2942dd8fd1f9737f7d84fd5c1c8 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:06:22 -0400 Subject: [PATCH 07/11] test: disable no-control-regex on a line where it's (?) needed --- test/utils-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils-test.js b/test/utils-test.js index 4de8824..0f57f98 100644 --- a/test/utils-test.js +++ b/test/utils-test.js @@ -5,7 +5,7 @@ const utils = require('../lib/utils') // We aren't testing the chalk library, so strip off the colors/styles it adds const stripAnsiRegex = -/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g +/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g // eslint-disable-line no-control-regex const originalConsoleLog = console.log From 62dcac136393b433846ee70bdb03c2eb202329fb Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:16:44 -0400 Subject: [PATCH 08/11] test: another standard --fix --- bin/cmd.js | 2 +- test/rules/fixes-url.js | 52 ++++++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/bin/cmd.js b/bin/cmd.js index c98a792..cea68cf 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -112,7 +112,7 @@ if (parsed.tap) { tap.pipe(process.stdout) if (parsed.out) tap.pipe(fs.createWriteStream(parsed.out)) let count = 0 - let total = args.length + const total = args.length v.on('commit', (c) => { count++ diff --git a/test/rules/fixes-url.js b/test/rules/fixes-url.js index 2b016e0..fe15f53 100644 --- a/test/rules/fixes-url.js +++ b/test/rules/fixes-url.js @@ -24,22 +24,22 @@ const makeCommit = (msg) => { test('rule: fixes-url', (t) => { const valid = [ - [ 'GitHub issue URL', - 'https://github.com/nodejs/node/issues/1234' ], - [ 'GitHub issue URL containing hyphen', - 'https://github.com/nodejs/node-report/issues/1234' ], - [ 'GitHub issue URL containing hyphen with comment', - 'https://github.com/nodejs/node-report/issues/1234#issuecomment-1234' ], - [ 'GitHub issue URL with comment', - 'https://github.com/nodejs/node/issues/1234#issuecomment-1234' ], - [ 'GitHub PR URL containing hyphen with comment', - 'https://github.com/nodejs/node-report/pull/1234#issuecomment-1234' ], - [ 'GitHub PR URL containing hyphen with discussion comment', - 'https://github.com/nodejs/node-report/pull/1234#discussion_r1234' ], - [ 'GitHub PR URL with comment', - 'https://github.com/nodejs/node/pull/1234#issuecomment-1234' ], - [ 'GitHub PR URL with discussion comment', - 'https://github.com/nodejs/node/pull/1234#discussion_r1234' ] + ['GitHub issue URL', + 'https://github.com/nodejs/node/issues/1234'], + ['GitHub issue URL containing hyphen', + 'https://github.com/nodejs/node-report/issues/1234'], + ['GitHub issue URL containing hyphen with comment', + 'https://github.com/nodejs/node-report/issues/1234#issuecomment-1234'], + ['GitHub issue URL with comment', + 'https://github.com/nodejs/node/issues/1234#issuecomment-1234'], + ['GitHub PR URL containing hyphen with comment', + 'https://github.com/nodejs/node-report/pull/1234#issuecomment-1234'], + ['GitHub PR URL containing hyphen with discussion comment', + 'https://github.com/nodejs/node-report/pull/1234#discussion_r1234'], + ['GitHub PR URL with comment', + 'https://github.com/nodejs/node/pull/1234#issuecomment-1234'], + ['GitHub PR URL with discussion comment', + 'https://github.com/nodejs/node/pull/1234#discussion_r1234'] ] for (const [name, url] of valid) { @@ -65,16 +65,16 @@ Fixes: ${url}` } const invalid = [ - [ 'issue number', NOT_AN_ISSUE_NUMBER, - '#1234' ], - [ 'GitHub PR URL', INVALID_PRURL, - 'https://github.com/nodejs/node/pull/1234' ], - [ 'GitHub PR URL containing hyphen', INVALID_PRURL, - 'https://github.com/nodejs/node-report/pull/1234' ], - [ 'non-GitHub URL', NOT_A_GITHUB_URL, - 'https://nodejs.org' ], - [ 'not a URL or issue number', NOT_A_GITHUB_URL, - 'fhqwhgads' ] + ['issue number', NOT_AN_ISSUE_NUMBER, + '#1234'], + ['GitHub PR URL', INVALID_PRURL, + 'https://github.com/nodejs/node/pull/1234'], + ['GitHub PR URL containing hyphen', INVALID_PRURL, + 'https://github.com/nodejs/node-report/pull/1234'], + ['non-GitHub URL', NOT_A_GITHUB_URL, + 'https://nodejs.org'], + ['not a URL or issue number', NOT_A_GITHUB_URL, + 'fhqwhgads'] ] for (const [name, expected, url] of invalid) { t.test(name, (tt) => { From d7b03613ec1c8c7e0ac18a364dc525df41b4567f Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:20:48 -0400 Subject: [PATCH 09/11] chore: update usage of URL / url module --- bin/cmd.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/cmd.js b/bin/cmd.js index cea68cf..81eccd3 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -6,7 +6,6 @@ const exec = require('child_process').exec const fs = require('fs') const http = require('http') const https = require('https') -const url = require('url') const nopt = require('nopt') const path = require('path') const pretty = require('../lib/format-pretty') @@ -51,7 +50,7 @@ const args = parsed.argv.remain if (!args.length) { args.push('HEAD') } function load (sha, cb) { - const parsed = url.parse(sha) + const parsed = new URL(sha) if (parsed.protocol) { return loadPatch(parsed, cb) } From ac789d8db873dedc9705e4d7f6dc6614edbf6aa3 Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Tue, 14 Jul 2020 15:21:21 -0400 Subject: [PATCH 10/11] test: fix instances of no-case-declarations --- lib/format-tap.js | 7 +++---- lib/utils.js | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/format-tap.js b/lib/format-tap.js index e1fc783..1a6ba3d 100644 --- a/lib/format-tap.js +++ b/lib/format-tap.js @@ -3,12 +3,11 @@ module.exports = function formatTap (t, context, msgs, validator) { for (const m of msgs) { switch (m.level) { - case 'pass': - const a = m.string - ? ` [${m.string}]` - : '' + case 'pass': { + const a = m.string ? ` [${m.string}]` : '' t.pass(`${m.id}: ${m.message}${a}`) break + } case 'skip': t.skip(`${m.id}: ${m.message}`) break diff --git a/lib/utils.js b/lib/utils.js index 54e3b64..b4ae3d8 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -28,11 +28,10 @@ exports.leftPad = function leftPad (str, max) { exports.header = (sha, status) => { switch (status) { case 'skip': - case 'pass': - const suffix = status === 'skip' - ? ' # SKIPPED' - : '' + case 'pass': { + const suffix = status === 'skip' ? ' # SKIPPED' : '' return `${CHECK} ${chalk.underline(sha)}${suffix}` + } case 'fail': return `${X} ${chalk.underline(sha)}` } From ad3eafd20064dc2c87b3096258fb9aae4c5434bb Mon Sep 17 00:00:00 2001 From: Tierney Cyren Date: Thu, 16 Jul 2020 14:02:28 -0400 Subject: [PATCH 11/11] chore: add `\\` in GitHub RegEx Co-authored-by: Rich Trott --- lib/rules/fixes-url.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/fixes-url.js b/lib/rules/fixes-url.js index 55db4f8..cf9129b 100644 --- a/lib/rules/fixes-url.js +++ b/lib/rules/fixes-url.js @@ -1,7 +1,7 @@ 'use strict' const id = 'fixes-url' -const github = new RegExp('^https://github.com/[\\w-]+/[\\w-]+/' + +const github = new RegExp('^https://github\\.com/[\\w-]+/[\\w-]+/' + '(issues|pull)/\\d+(#issuecomment-\\d+|#discussion_r\\d+)?$' )