changelog-guru
Version:
Git changelog generator
90 lines (89 loc) • 4.41 kB
JavaScript
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Linter_config, _Linter_length;
import { once } from 'events';
import fs from 'fs';
import path from 'path';
import readline from 'readline';
import TaskTree from 'tasktree-cli';
import { splitHeadline } from '../utils/commit.js';
import { findSame, unify } from '../utils/text.js';
const SUBJECT_MAX_LENGTH = 10;
const GIT_PARAMETERS = ['HUSKY_GIT_PARAMS', 'GIT_PARAMS'];
const GIT_MESSAGES_PATHS = ['.git/COMMIT_EDITMSG', '.git/MERGE_MSG', '.git/SQUASH_MSG'];
export class Linter {
constructor(config, length = 100) {
_Linter_config.set(this, void 0);
_Linter_length.set(this, void 0);
__classPrivateFieldSet(this, _Linter_config, config, "f");
__classPrivateFieldSet(this, _Linter_length, length, "f");
}
async lint(text) {
const task = TaskTree.add('Lint commit message:');
await __classPrivateFieldGet(this, _Linter_config, "f").init();
const parameter = GIT_PARAMETERS.find(n => [text, `%${n}%`, `$${n}`].includes(n));
const message = [];
let filePath;
if (!text)
task.error('Empty commit message');
if (parameter && parameter in process.env)
filePath = process.env[parameter];
if (GIT_MESSAGES_PATHS.includes(text))
filePath = path.resolve(process.cwd(), text);
if (filePath) {
if (!fs.existsSync(filePath))
task.fail(`${filePath} not found`);
const rl = readline.createInterface({ input: fs.createReadStream(filePath), crlfDelay: Infinity });
rl.on('line', line => line.trim()[0] !== '#' && message.push(line));
await once(rl, 'close');
}
else {
message.push(...text.split('\n'));
}
this.lintMessage(task, message);
if (task.haveErrors) {
task.fail('Incorrect commit message:');
}
else {
task.complete('Commit message is correct', true);
}
}
lintMessage(task, message) {
const [headline, ...body] = message;
if (headline) {
const [type, scope, subject] = splitHeadline(headline);
const types = __classPrivateFieldGet(this, _Linter_config, "f").types.map(([name]) => name);
if (headline.length > __classPrivateFieldGet(this, _Linter_length, "f")) {
task.error(`Headline has a length of ${headline.length}. Maximum allowed is {bold ${__classPrivateFieldGet(this, _Linter_length, "f")}}`);
}
if (!type || !findSame(type, types))
task.error('Unknown commit type!');
if (type !== unify(type))
task.error('Type is not in lowercase');
if (type) {
if (!subject)
task.error('Subject is empty');
if (subject && subject.length <= SUBJECT_MAX_LENGTH)
task.error('Subject is not informative');
}
__classPrivateFieldGet(this, _Linter_config, "f").rules.forEach(rule => {
if (rule.lint) {
rule.lint({ task, headline, body, type, scope, subject });
}
});
}
else {
task.error('Headline is empty');
}
}
}
_Linter_config = new WeakMap(), _Linter_length = new WeakMap();