1 | "use strict";
|
2 | var __asyncValues = (this && this.__asyncValues) || function (o) {
|
3 | if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
4 | var m = o[Symbol.asyncIterator], i;
|
5 | return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
6 | function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
7 | function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
8 | };
|
9 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
10 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
11 | };
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | const execa_1 = __importDefault(require("execa"));
|
14 | const load_1 = __importDefault(require("@commitlint/load"));
|
15 | const lint_1 = __importDefault(require("@commitlint/lint"));
|
16 | const read_1 = __importDefault(require("@commitlint/read"));
|
17 | const lodash_isfunction_1 = __importDefault(require("lodash.isfunction"));
|
18 | const resolve_from_1 = __importDefault(require("resolve-from"));
|
19 | const resolve_global_1 = __importDefault(require("resolve-global"));
|
20 | const yargs_1 = __importDefault(require("yargs"));
|
21 | const util_1 = __importDefault(require("util"));
|
22 | const cli_error_1 = require("./cli-error");
|
23 | const pkg = require('../package');
|
24 | const gitDefaultCommentChar = '#';
|
25 | const cli = yargs_1.default
|
26 | .options({
|
27 | color: {
|
28 | alias: 'c',
|
29 | default: true,
|
30 | description: 'toggle colored output',
|
31 | type: 'boolean',
|
32 | },
|
33 | config: {
|
34 | alias: 'g',
|
35 | description: 'path to the config file',
|
36 | type: 'string',
|
37 | },
|
38 | 'print-config': {
|
39 | type: 'boolean',
|
40 | default: false,
|
41 | description: 'print resolved config',
|
42 | },
|
43 | cwd: {
|
44 | alias: 'd',
|
45 | default: process.cwd(),
|
46 | defaultDescription: '(Working Directory)',
|
47 | description: 'directory to execute in',
|
48 | type: 'string',
|
49 | },
|
50 | edit: {
|
51 | alias: 'e',
|
52 | description: 'read last commit message from the specified file or fallbacks to ./.git/COMMIT_EDITMSG',
|
53 | type: 'string',
|
54 | },
|
55 | env: {
|
56 | alias: 'E',
|
57 | description: 'check message in the file at path given by environment variable value',
|
58 | type: 'string',
|
59 | },
|
60 | extends: {
|
61 | alias: 'x',
|
62 | description: 'array of shareable configurations to extend',
|
63 | type: 'array',
|
64 | },
|
65 | 'help-url': {
|
66 | alias: 'H',
|
67 | type: 'string',
|
68 | description: 'help url in error message',
|
69 | },
|
70 | from: {
|
71 | alias: 'f',
|
72 | description: 'lower end of the commit range to lint; applies if edit=false',
|
73 | type: 'string',
|
74 | },
|
75 | 'git-log-args': {
|
76 | description: "addditional git log arguments as space separated string, example '--first-parent --cherry-pick'",
|
77 | type: 'string',
|
78 | },
|
79 | format: {
|
80 | alias: 'o',
|
81 | description: 'output format of the results',
|
82 | type: 'string',
|
83 | },
|
84 | 'parser-preset': {
|
85 | alias: 'p',
|
86 | description: 'configuration preset to use for conventional-commits-parser',
|
87 | type: 'string',
|
88 | },
|
89 | quiet: {
|
90 | alias: 'q',
|
91 | default: false,
|
92 | description: 'toggle console output',
|
93 | type: 'boolean',
|
94 | },
|
95 | to: {
|
96 | alias: 't',
|
97 | description: 'upper end of the commit range to lint; applies if edit=false',
|
98 | type: 'string',
|
99 | },
|
100 | verbose: {
|
101 | alias: 'V',
|
102 | type: 'boolean',
|
103 | description: 'enable verbose output for reports without problems',
|
104 | },
|
105 | strict: {
|
106 | alias: 's',
|
107 | type: 'boolean',
|
108 | description: 'enable strict mode; result code 2 for warnings, 3 for errors',
|
109 | },
|
110 | })
|
111 | .version('version', 'display version information', `${pkg.name}@${pkg.version}`)
|
112 | .alias('v', 'version')
|
113 | .help('help')
|
114 | .alias('h', 'help')
|
115 | .usage(`${pkg.name}@${pkg.version} - ${pkg.description}\n`)
|
116 | .usage(`[input] reads from stdin if --edit, --env, --from and --to are omitted`)
|
117 | .strict();
|
118 | main(cli.argv).catch((err) => {
|
119 | setTimeout(() => {
|
120 | if (err.type === pkg.name) {
|
121 | process.exit(err.error_code);
|
122 | }
|
123 | throw err;
|
124 | }, 0);
|
125 | });
|
126 | async function stdin() {
|
127 | var _a, e_1, _b, _c;
|
128 | let result = '';
|
129 | if (process.stdin.isTTY) {
|
130 | return result;
|
131 | }
|
132 | process.stdin.setEncoding('utf8');
|
133 | try {
|
134 | for (var _d = true, _e = __asyncValues(process.stdin), _f; _f = await _e.next(), _a = _f.done, !_a;) {
|
135 | _c = _f.value;
|
136 | _d = false;
|
137 | try {
|
138 | const chunk = _c;
|
139 | result += chunk;
|
140 | }
|
141 | finally {
|
142 | _d = true;
|
143 | }
|
144 | }
|
145 | }
|
146 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
147 | finally {
|
148 | try {
|
149 | if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
|
150 | }
|
151 | finally { if (e_1) throw e_1.error; }
|
152 | }
|
153 | return result;
|
154 | }
|
155 | async function resolveArgs(args) {
|
156 | return typeof args.then === 'function' ? await args : args;
|
157 | }
|
158 | async function main(args) {
|
159 | var _a;
|
160 | const options = await resolveArgs(args);
|
161 | if (typeof options.edit === 'undefined') {
|
162 | options.edit = false;
|
163 | }
|
164 | const raw = options._;
|
165 | const flags = normalizeFlags(options);
|
166 | if (flags['print-config']) {
|
167 | const loaded = await (0, load_1.default)(getSeed(flags), {
|
168 | cwd: flags.cwd,
|
169 | file: flags.config,
|
170 | });
|
171 | console.log(util_1.default.inspect(loaded, false, null, options.color));
|
172 | return;
|
173 | }
|
174 | const fromStdin = checkFromStdin(raw, flags);
|
175 | const input = await (fromStdin
|
176 | ? stdin()
|
177 | : (0, read_1.default)({
|
178 | to: flags.to,
|
179 | from: flags.from,
|
180 | edit: flags.edit,
|
181 | cwd: flags.cwd,
|
182 | gitLogArgs: flags['git-log-args'],
|
183 | }));
|
184 | const messages = (Array.isArray(input) ? input : [input])
|
185 | .filter((message) => typeof message === 'string')
|
186 | .filter((message) => message.trim() !== '')
|
187 | .filter(Boolean);
|
188 | if (messages.length === 0 && !checkFromRepository(flags)) {
|
189 | const err = new cli_error_1.CliError('[input] is required: supply via stdin, or --env or --edit or --from and --to', pkg.name);
|
190 | yargs_1.default.showHelp('log');
|
191 | console.log(err.message);
|
192 | throw err;
|
193 | }
|
194 | const loaded = await (0, load_1.default)(getSeed(flags), {
|
195 | cwd: flags.cwd,
|
196 | file: flags.config,
|
197 | });
|
198 | const parserOpts = selectParserOpts(loaded.parserPreset);
|
199 | const opts = {
|
200 | parserOpts: {},
|
201 | plugins: {},
|
202 | ignores: [],
|
203 | defaultIgnores: true,
|
204 | };
|
205 | if (parserOpts) {
|
206 | opts.parserOpts = parserOpts;
|
207 | }
|
208 | if (loaded.plugins) {
|
209 | opts.plugins = loaded.plugins;
|
210 | }
|
211 | if (loaded.ignores) {
|
212 | opts.ignores = loaded.ignores;
|
213 | }
|
214 | if (loaded.defaultIgnores === false) {
|
215 | opts.defaultIgnores = false;
|
216 | }
|
217 | const format = loadFormatter(loaded, flags);
|
218 |
|
219 |
|
220 | if (flags.edit) {
|
221 | try {
|
222 | const { stdout } = await (0, execa_1.default)('git', ['config', 'core.commentChar']);
|
223 | opts.parserOpts.commentChar = stdout.trim() || gitDefaultCommentChar;
|
224 | }
|
225 | catch (e) {
|
226 | const execaError = e;
|
227 |
|
228 |
|
229 | if (!execaError.failed || execaError.exitCode !== 1) {
|
230 | console.warn('Could not determine core.commentChar git configuration', e);
|
231 | }
|
232 | opts.parserOpts.commentChar = gitDefaultCommentChar;
|
233 | }
|
234 | }
|
235 | const results = await Promise.all(messages.map((message) => (0, lint_1.default)(message, loaded.rules, opts)));
|
236 | if (Object.keys(loaded.rules).length === 0) {
|
237 | let input = '';
|
238 | if (results.length !== 0) {
|
239 | input = results[0].input;
|
240 | }
|
241 | results.splice(0, results.length, {
|
242 | valid: false,
|
243 | errors: [
|
244 | {
|
245 | level: 2,
|
246 | valid: false,
|
247 | name: 'empty-rules',
|
248 | message: [
|
249 | 'Please add rules to your `commitlint.config.js`',
|
250 | ' - Getting started guide: https://commitlint.js.org/#/?id=getting-started',
|
251 | ' - Example config: https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/config-conventional/index.js',
|
252 | ].join('\n'),
|
253 | },
|
254 | ],
|
255 | warnings: [],
|
256 | input,
|
257 | });
|
258 | }
|
259 | const report = results.reduce((info, result) => {
|
260 | info.valid = result.valid ? info.valid : false;
|
261 | info.errorCount += result.errors.length;
|
262 | info.warningCount += result.warnings.length;
|
263 | info.results.push(result);
|
264 | return info;
|
265 | }, {
|
266 | valid: true,
|
267 | errorCount: 0,
|
268 | warningCount: 0,
|
269 | results: [],
|
270 | });
|
271 | const helpUrl = ((_a = flags['help-url']) === null || _a === void 0 ? void 0 : _a.trim()) || loaded.helpUrl;
|
272 | const output = format(report, {
|
273 | color: flags.color,
|
274 | verbose: flags.verbose,
|
275 | helpUrl,
|
276 | });
|
277 | if (!flags.quiet && output !== '') {
|
278 | console.log(output);
|
279 | }
|
280 | if (flags.strict) {
|
281 | if (report.errorCount > 0) {
|
282 | throw new cli_error_1.CliError(output, pkg.name, 3);
|
283 | }
|
284 | if (report.warningCount > 0) {
|
285 | throw new cli_error_1.CliError(output, pkg.name, 2);
|
286 | }
|
287 | }
|
288 | if (!report.valid) {
|
289 | throw new cli_error_1.CliError(output, pkg.name);
|
290 | }
|
291 | }
|
292 | function checkFromStdin(input, flags) {
|
293 | return input.length === 0 && !checkFromRepository(flags);
|
294 | }
|
295 | function checkFromRepository(flags) {
|
296 | return checkFromHistory(flags) || checkFromEdit(flags);
|
297 | }
|
298 | function checkFromEdit(flags) {
|
299 | return Boolean(flags.edit) || Boolean(flags.env);
|
300 | }
|
301 | function checkFromHistory(flags) {
|
302 | return typeof flags.from === 'string' || typeof flags.to === 'string';
|
303 | }
|
304 | function normalizeFlags(flags) {
|
305 | const edit = getEditValue(flags);
|
306 | return Object.assign(Object.assign({}, flags), { edit });
|
307 | }
|
308 | function getEditValue(flags) {
|
309 | if (flags.env) {
|
310 | if (!(flags.env in process.env)) {
|
311 | throw new Error(`Received '${flags.env}' as value for -E | --env, but environment variable '${flags.env}' is not available globally`);
|
312 | }
|
313 | return process.env[flags.env];
|
314 | }
|
315 | const { edit } = flags;
|
316 |
|
317 |
|
318 | if (edit === '') {
|
319 | return true;
|
320 | }
|
321 | if (typeof edit === 'boolean') {
|
322 | return edit;
|
323 | }
|
324 |
|
325 |
|
326 |
|
327 |
|
328 |
|
329 | const isGitParams = edit === '$GIT_PARAMS' || edit === '%GIT_PARAMS%';
|
330 | const isHuskyParams = edit === '$HUSKY_GIT_PARAMS' || edit === '%HUSKY_GIT_PARAMS%';
|
331 | if (isGitParams || isHuskyParams) {
|
332 | console.warn(`Using environment variable syntax (${edit}) in -e |\
|
333 | --edit is deprecated. Use '{-E|--env} HUSKY_GIT_PARAMS instead'`);
|
334 | if (isGitParams && 'GIT_PARAMS' in process.env) {
|
335 | return process.env.GIT_PARAMS;
|
336 | }
|
337 | if ('HUSKY_GIT_PARAMS' in process.env) {
|
338 | return process.env.HUSKY_GIT_PARAMS;
|
339 | }
|
340 | throw new Error(`Received ${edit} as value for -e | --edit, but GIT_PARAMS or HUSKY_GIT_PARAMS are not available globally.`);
|
341 | }
|
342 | return edit;
|
343 | }
|
344 | function getSeed(flags) {
|
345 | const n = (flags.extends || []).filter((i) => typeof i === 'string');
|
346 | return n.length > 0
|
347 | ? { extends: n, parserPreset: flags['parser-preset'] }
|
348 | : { parserPreset: flags['parser-preset'] };
|
349 | }
|
350 | function selectParserOpts(parserPreset) {
|
351 | if (typeof parserPreset !== 'object') {
|
352 | return undefined;
|
353 | }
|
354 | if (typeof parserPreset.parserOpts !== 'object') {
|
355 | return undefined;
|
356 | }
|
357 | return parserPreset.parserOpts;
|
358 | }
|
359 | function loadFormatter(config, flags) {
|
360 | const moduleName = flags.format || config.formatter || '@commitlint/format';
|
361 | const modulePath = resolve_from_1.default.silent(__dirname, moduleName) ||
|
362 | resolve_from_1.default.silent(flags.cwd, moduleName) ||
|
363 | resolve_global_1.default.silent(moduleName);
|
364 | if (modulePath) {
|
365 | const moduleInstance = require(modulePath);
|
366 | if ((0, lodash_isfunction_1.default)(moduleInstance.default)) {
|
367 | return moduleInstance.default;
|
368 | }
|
369 | return moduleInstance;
|
370 | }
|
371 | throw new Error(`Using format ${moduleName}, but cannot find the module.`);
|
372 | }
|
373 |
|
374 | process.on('unhandledRejection', (reason, promise) => {
|
375 | console.log('Unhandled Rejection at: Promise ', promise, ' reason: ', reason);
|
376 | throw reason;
|
377 | });
|
378 |
|
\ | No newline at end of file |