kotlin-format 0.0.0-stage → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs ADDED
@@ -0,0 +1,738 @@
1
+ #!/usr/bin/env node
2
+ import { exists, loadConfig, projectRoot, resolveOptions, validateConfig } from "./config.mjs";
3
+ import { glob, lstat, readFile, readdir, writeFile } from "node:fs/promises";
4
+ import { extname, join, relative, resolve, sep } from "node:path";
5
+ import { parseArgs } from "node:util";
6
+ // \0rolldown/runtime.js
7
+ var __create = Object.create;
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __getProtoOf = Object.getPrototypeOf;
12
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
13
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
16
+ key = keys[i];
17
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
25
+ value: mod,
26
+ enumerable: true
27
+ }) : target, mod));
28
+ // js/cli.ts
29
+ var import_ignore = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
30
+ function makeArray(subject) {
31
+ return Array.isArray(subject) ? subject : [subject];
32
+ }
33
+ const UNDEFINED = void 0;
34
+ const EMPTY = "";
35
+ const SPACE = " ";
36
+ const ESCAPE = "\\";
37
+ const REGEX_LITERAL_SPECIAL = /[.*+?()[\]{}^$|\\/]/;
38
+ const BOM = "";
39
+ const REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
40
+ const REGEX_ANCHORED_GLOBSTAR = /^\/\*{2,}$/;
41
+ const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
42
+ const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
43
+ const REGEX_SPLITALL_CRLF = /\r?\n/g;
44
+ const DOUBLE_SLASH = "//";
45
+ const SLASH_CODE = 47;
46
+ const DOT_CODE = 46;
47
+ const SLASH = "/";
48
+ let TMP_KEY_IGNORE = "node-ignore";
49
+ /* istanbul ignore else */
50
+ if (typeof Symbol !== "undefined") TMP_KEY_IGNORE = Symbol.for("node-ignore");
51
+ const KEY_IGNORE = TMP_KEY_IGNORE;
52
+ const define = (object, key, value) => {
53
+ Object.defineProperty(object, key, { value });
54
+ return value;
55
+ };
56
+ const RETURN_FALSE = () => false;
57
+ const POSIX_CLASSES = {
58
+ alnum: "0-9A-Za-z",
59
+ alpha: "A-Za-z",
60
+ blank: " \\t",
61
+ cntrl: "\\x00-\\x1f\\x7f",
62
+ digit: "0-9",
63
+ graph: "!-.0-~",
64
+ lower: "a-z",
65
+ print: " -.0-~",
66
+ punct: "!-.:-@\\[-`{-~",
67
+ space: " \\t\\n\\r",
68
+ upper: "A-Z",
69
+ xdigit: "0-9A-Fa-f"
70
+ };
71
+ const CLASS_MEMBERS_TO_ESCAPE = "\\]^-[";
72
+ const escapeMember = (char) => CLASS_MEMBERS_TO_ESCAPE.indexOf(char) < 0 ? char : ESCAPE + char;
73
+ const NON_SLASH = "(?!\\/)";
74
+ const classSource = (negated, body) => {
75
+ if (negated) return `[^\\/${body}]`;
76
+ const source = `[${body}]`;
77
+ return new RegExp(source).test("/") ? NON_SLASH + source : source;
78
+ };
79
+ const scanBracket = (pattern, start) => {
80
+ const { length } = pattern;
81
+ let index = start + 1;
82
+ let negated = EMPTY;
83
+ const lead = pattern[index];
84
+ if (lead === "!" || lead === "^") {
85
+ negated = "^";
86
+ index++;
87
+ }
88
+ let body = EMPTY;
89
+ let prev = EMPTY;
90
+ for (;;) {
91
+ const char = pattern[index];
92
+ if (char === UNDEFINED) return null;
93
+ if (char === ESCAPE) {
94
+ const escaped = pattern[index + 1];
95
+ if (escaped === UNDEFINED) return null;
96
+ body += escapeMember(escaped);
97
+ prev = escaped;
98
+ index++;
99
+ } else if (char === "-" && prev && index + 1 < length && pattern[index + 1] !== "]") {
100
+ index++;
101
+ let to = pattern[index];
102
+ if (to === ESCAPE) to = pattern[index += 1];
103
+ if (prev <= to) body += `-${escapeMember(to)}`;
104
+ prev = EMPTY;
105
+ } else if (char === "[" && pattern[index + 1] === ":") {
106
+ const nameStart = index + 2;
107
+ let end = nameStart;
108
+ while (end < length && pattern[end] !== "]") end++;
109
+ if (end === length) return null;
110
+ if (end > nameStart && pattern[end - 1] === ":") {
111
+ const name = pattern.slice(nameStart, end - 1);
112
+ if (!Object.prototype.hasOwnProperty.call(POSIX_CLASSES, name)) return null;
113
+ body += POSIX_CLASSES[name];
114
+ prev = EMPTY;
115
+ index = end;
116
+ } else {
117
+ body += escapeMember("[");
118
+ prev = "[";
119
+ index = nameStart - 2;
120
+ }
121
+ } else {
122
+ body += escapeMember(char);
123
+ prev = char;
124
+ }
125
+ index++;
126
+ if (pattern[index] === "]") return {
127
+ end: index,
128
+ source: classSource(negated, body)
129
+ };
130
+ }
131
+ };
132
+ const NEVER_MATCH = "[]";
133
+ const PLACEHOLDER = "\0";
134
+ const REGEX_RESTORE_PLACEHOLDER = new RegExp(`${PLACEHOLDER}(\\d+)${PLACEHOLDER}`, "g");
135
+ const TRAILING_WILDCARD = "";
136
+ const TRAILING_DOUBLESTAR = "";
137
+ const isReserved = (char) => char === PLACEHOLDER || char === TRAILING_WILDCARD || char === TRAILING_DOUBLESTAR;
138
+ const extractBrackets = (pattern) => {
139
+ const sources = [];
140
+ const hold = (source) => `${PLACEHOLDER}${sources.push(source) - 1}${PLACEHOLDER}`;
141
+ const { length } = pattern;
142
+ let out = EMPTY;
143
+ let index = 0;
144
+ while (index < length) {
145
+ const char = pattern[index];
146
+ if (char === ESCAPE) {
147
+ const escaped = pattern[index + 1];
148
+ if (escaped === UNDEFINED || escaped === SLASH && index + 2 === length) out += hold(NEVER_MATCH);
149
+ else if (escaped === "*" || escaped === "[" || escaped === SPACE) out += pattern.slice(index, index + 2);
150
+ else out += hold(REGEX_LITERAL_SPECIAL.test(escaped) ? ESCAPE + escaped : isReserved(escaped) ? `[${escaped}]` : escaped);
151
+ index += 2;
152
+ } else if (isReserved(char)) {
153
+ out += hold(`[${char}]`);
154
+ index++;
155
+ } else if (char === "[") {
156
+ const scanned = scanBracket(pattern, index);
157
+ if (scanned === null) {
158
+ out += hold(NEVER_MATCH);
159
+ index = length;
160
+ } else {
161
+ out += hold(scanned.source);
162
+ index = scanned.end + 1;
163
+ }
164
+ } else {
165
+ out += char;
166
+ index++;
167
+ }
168
+ }
169
+ return {
170
+ source: out,
171
+ sources
172
+ };
173
+ };
174
+ const DIRECT = null;
175
+ const REGEX_INNER_SLASH = /\/(?!$)/;
176
+ const REPLACERS = [
177
+ [
178
+ /(\\+)( ?)/g,
179
+ (_, run, space) => space ? run.slice(0, run.length - run.length % 2) + SPACE : run,
180
+ "\\ "
181
+ ],
182
+ [
183
+ /(^|\/)\*{3,}(?=\/|$)/g,
184
+ (_, start) => `${start}**`,
185
+ "*"
186
+ ],
187
+ [/[\\$.|*+(){^]/g, (match) => `\\${match}`],
188
+ [
189
+ /(?!\\)\?/g,
190
+ () => "[^/]",
191
+ "?"
192
+ ],
193
+ [
194
+ /^\//,
195
+ () => "^",
196
+ SLASH
197
+ ],
198
+ [
199
+ /\//g,
200
+ () => "\\/",
201
+ SLASH
202
+ ],
203
+ [
204
+ /^\^*(?:\\\*\\\*\\\/)+/,
205
+ () => "^(?:.*\\/)?",
206
+ "*"
207
+ ],
208
+ [DIRECT, (source, pattern) => {
209
+ if (!source || source[0] === "^") return source;
210
+ return (!REGEX_INNER_SLASH.test(pattern) ? "(?:^|\\/)" : "^") + source;
211
+ }],
212
+ [
213
+ /\\\/\\\*\\\*(?=\\\/|$)/g,
214
+ (_, index, str) => index + 6 < str.length ? str.slice(index + 6) === "\\/" ? "(?:\\/[^\\/]+)+" : "(?:\\/[^\\/]+)*" : `\\/${TRAILING_DOUBLESTAR}`,
215
+ "*"
216
+ ],
217
+ [
218
+ /(^|[^\\]+)(\\\*)+(?=.+)/g,
219
+ (_, p1, p2) => {
220
+ return p1 + p2.replace(/\\\*/g, "[^\\/]*");
221
+ },
222
+ "*"
223
+ ],
224
+ [
225
+ /(^|[^\\])((?:\\\\)*)\\\*$/,
226
+ (match, p1, p2) => p2 === EMPTY ? p1 + TRAILING_WILDCARD : match,
227
+ "*"
228
+ ],
229
+ [
230
+ /\\\\\\(?=[$.|*+(){^])/g,
231
+ () => ESCAPE,
232
+ "\\\\"
233
+ ],
234
+ [
235
+ /\\\\/g,
236
+ () => ESCAPE,
237
+ "\\\\"
238
+ ],
239
+ [
240
+ /\\\[([^\]/]*?)($|\])/g,
241
+ (match, range, close) => `\\[${range}${close}`,
242
+ "["
243
+ ],
244
+ [DIRECT, (source) => {
245
+ const last = source[source.length - 1];
246
+ if (!last || last === TRAILING_WILDCARD || last === TRAILING_DOUBLESTAR) return source;
247
+ return last === SLASH ? `${source}$` : `${source}(?=$|\\/$)`;
248
+ }]
249
+ ];
250
+ const REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\/)?\uE000$/;
251
+ const MODE_IGNORE = "regex";
252
+ const MODE_CHECK_IGNORE = "checkRegex";
253
+ const replaceTrailingWildcard = (_, p1) => {
254
+ return `${p1 ? `${p1}[^/]+` : "[^/]*"}(?=$|\\/$)`;
255
+ };
256
+ const REGEX_REPLACE_TRAILING_DOUBLESTAR = /\uE001$/;
257
+ const replaceTrailingDoublestar = () => ".+(?=$|\\/$)";
258
+ const WILDCARD = "[^\\/]*";
259
+ const separatorAfter = (run, at) => {
260
+ let separator = EMPTY;
261
+ for (let index = at + 1; index < run.length && !run[index].wildcard; index++) separator += run[index].single;
262
+ return separator;
263
+ };
264
+ const pinWildcards = (source) => {
265
+ if (source.indexOf(WILDCARD) < 0) return source;
266
+ const tokens = [];
267
+ const { length } = source;
268
+ let index = 0;
269
+ while (index < length) {
270
+ const char = source[index];
271
+ if (source.startsWith(WILDCARD, index)) {
272
+ tokens.push({ wildcard: true });
273
+ index += 6;
274
+ } else if (char === "[") {
275
+ let end = index + 1;
276
+ if (source[end] === "^") end++;
277
+ if (source[end] === "]") end++;
278
+ while (end < length && source[end] !== "]") end += source[end] === ESCAPE ? 2 : 1;
279
+ end++;
280
+ tokens.push({ single: source.slice(index, end) });
281
+ index = end;
282
+ } else if (char === ESCAPE) {
283
+ tokens.push({ single: source.slice(index, index + 2) });
284
+ index += 2;
285
+ } else if (char === "(") {
286
+ let depth = 0;
287
+ let end = index;
288
+ do {
289
+ if (source[end] === ESCAPE) end++;
290
+ else if (source[end] === "(") depth++;
291
+ else if (source[end] === ")") depth--;
292
+ end++;
293
+ } while (end < length && depth > 0);
294
+ if ("*+?".indexOf(source[end]) >= 0) end++;
295
+ tokens.push({ boundary: source.slice(index, end) });
296
+ index = end;
297
+ } else if (char === "^" || char === "$") {
298
+ tokens.push({ boundary: char });
299
+ index++;
300
+ } else {
301
+ tokens.push({ single: char });
302
+ index++;
303
+ }
304
+ }
305
+ let out = EMPTY;
306
+ let run = [];
307
+ const flush = () => {
308
+ let lastWildcard;
309
+ run.forEach((token, at) => {
310
+ if (token.wildcard) lastWildcard = at;
311
+ });
312
+ run.forEach((token, at) => {
313
+ if (!token.wildcard) {
314
+ out += token.single;
315
+ return;
316
+ }
317
+ out += at === lastWildcard ? WILDCARD : `(?:(?!${separatorAfter(run, at)})[^\\/])*`;
318
+ });
319
+ run = [];
320
+ };
321
+ tokens.forEach((token) => {
322
+ if (token.boundary === void 0) {
323
+ run.push(token);
324
+ return;
325
+ }
326
+ flush();
327
+ out += token.boundary;
328
+ });
329
+ flush();
330
+ return out;
331
+ };
332
+ const makeRegexPrefix = (pattern) => {
333
+ if (REGEX_ANCHORED_GLOBSTAR.test(pattern)) pattern = "**";
334
+ const { source, sources } = extractBrackets(pattern);
335
+ const replaced = REPLACERS.reduce((prev, [matcher, replacer, required]) => {
336
+ if (matcher === DIRECT) return replacer(prev, pattern);
337
+ if (required !== UNDEFINED && prev.indexOf(required) < 0) return prev;
338
+ return matcher.test(prev) ? prev.replace(matcher, replacer.bind(pattern)) : prev;
339
+ }, source);
340
+ return sources.length ? replaced.replace(REGEX_RESTORE_PLACEHOLDER, (match, index) => sources[index]) : replaced;
341
+ };
342
+ const checkSourceOf = (body, prefix) => {
343
+ if (body[body.length - 1] === SLASH) prefix = makeRegexPrefix(body.slice(0, -1));
344
+ const head = prefix.slice(0, -1);
345
+ const last = prefix[prefix.length - 1];
346
+ return last === TRAILING_WILDCARD ? `${head}$` : last === TRAILING_DOUBLESTAR ? `${head}.*$` : NEVER_MATCH;
347
+ };
348
+ const matchesBasename = (body) => {
349
+ const index = body.indexOf(SLASH);
350
+ return index < 0 || index === body.length - 1;
351
+ };
352
+ const basenameOf = (path) => {
353
+ const end = path.length - 1;
354
+ const index = path.lastIndexOf(SLASH, path[end] === SLASH ? end - 1 : end);
355
+ return index < 0 ? path : path.slice(index + 1);
356
+ };
357
+ const parentOf = (path) => {
358
+ if (path.charCodeAt(0) === SLASH_CODE || path.indexOf(DOUBLE_SLASH) >= 0) {
359
+ const slices = path.split(SLASH).filter(Boolean);
360
+ slices.pop();
361
+ return slices.length ? slices.join(SLASH) + SLASH : EMPTY;
362
+ }
363
+ const end = path.length - 1;
364
+ const cut = path.lastIndexOf(SLASH, path.charCodeAt(end) === SLASH_CODE ? end - 1 : end);
365
+ return cut < 0 ? EMPTY : path.slice(0, cut + 1);
366
+ };
367
+ const isString = (subject) => typeof subject === "string";
368
+ const checkPattern = (pattern) => pattern && isString(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern);
369
+ const splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
370
+ var IgnoreRule = class {
371
+ constructor(pattern, mark, body, ignoreCase, negative, prefix) {
372
+ this.pattern = pattern;
373
+ this.mark = mark;
374
+ this.negative = negative;
375
+ define(this, "body", body);
376
+ define(this, "ignoreCase", ignoreCase);
377
+ define(this, "regexPrefix", prefix);
378
+ }
379
+ get _basenameOnly() {
380
+ return define(this, "_basenameOnly", matchesBasename(this.body));
381
+ }
382
+ get regex() {
383
+ const key = "_regex";
384
+ if (this[key]) return this[key];
385
+ return this._make(MODE_IGNORE, key);
386
+ }
387
+ get checkRegex() {
388
+ const key = "_checkRegex";
389
+ if (this[key]) return this[key];
390
+ return this._make(MODE_CHECK_IGNORE, key);
391
+ }
392
+ _make(mode, key) {
393
+ const str = pinWildcards(mode === MODE_IGNORE ? this.regexPrefix.replace(REGEX_REPLACE_TRAILING_WILDCARD, replaceTrailingWildcard).replace(REGEX_REPLACE_TRAILING_DOUBLESTAR, replaceTrailingDoublestar) : checkSourceOf(this.body, this.regexPrefix));
394
+ const regex = this.ignoreCase ? new RegExp(str, "i") : new RegExp(str);
395
+ return define(this, key, regex);
396
+ }
397
+ };
398
+ const isLineEnd = (char) => char === "\r" || char === "\n";
399
+ const trimEnd = (body) => {
400
+ let end = body.length;
401
+ while (end && isLineEnd(body[end - 1])) end--;
402
+ const lineEnd = end;
403
+ while (end && body[end - 1] === SPACE) end--;
404
+ if (end === lineEnd) return body.slice(0, end);
405
+ let backslashes = 0;
406
+ while (backslashes < end && body[end - backslashes - 1] === ESCAPE) backslashes++;
407
+ return backslashes % 2 ? body.slice(0, end - 1) + SPACE : body.slice(0, end);
408
+ };
409
+ const createRule = ({ pattern, mark }, ignoreCase) => {
410
+ let body = pattern[0] === BOM ? pattern.slice(1) : pattern;
411
+ if (body[0] === "#") return;
412
+ let negative = false;
413
+ if (body[0] === "!") {
414
+ negative = true;
415
+ body = body.slice(1);
416
+ }
417
+ const last = body[body.length - 1];
418
+ if (last === SPACE || last === "\r" || last === "\n") body = trimEnd(body);
419
+ if (!body) return;
420
+ body = body.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, "!").replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, "#");
421
+ const regexPrefix = makeRegexPrefix(body);
422
+ return new IgnoreRule(pattern, mark, body, ignoreCase, negative, regexPrefix);
423
+ };
424
+ var RuleManager = class {
425
+ constructor(ignoreCase) {
426
+ this._ignoreCase = ignoreCase;
427
+ this._rules = [];
428
+ this._basenameCount = 0;
429
+ }
430
+ _add(pattern) {
431
+ if (pattern && pattern[KEY_IGNORE]) {
432
+ this._rules = this._rules.concat(pattern._rules._rules);
433
+ this._basenameCount += pattern._rules._basenameCount;
434
+ this._added = true;
435
+ return;
436
+ }
437
+ if (isString(pattern)) pattern = { pattern };
438
+ const rule = checkPattern(pattern.pattern) && createRule(pattern, this._ignoreCase);
439
+ if (rule) {
440
+ this._added = true;
441
+ this._rules.push(rule);
442
+ if (matchesBasename(rule.body)) this._basenameCount++;
443
+ }
444
+ }
445
+ add(pattern) {
446
+ this._added = false;
447
+ makeArray(isString(pattern) ? splitPattern(pattern) : pattern).forEach(this._add, this);
448
+ if (this._added) this._literalRules = UNDEFINED;
449
+ return this._added;
450
+ }
451
+ testLiteral(path) {
452
+ const rules = this._literalRules || (this._literalRules = this._rules.filter(({ body }) => body[body.length - (body[body.length - 1] === SLASH ? 2 : 1)] === "*"));
453
+ let ignored = false;
454
+ let unignored = false;
455
+ let matchedRule;
456
+ for (let index = rules.length - 1; index >= 0; index--) {
457
+ const rule = rules[index];
458
+ if (rule.checkRegex.test(path)) {
459
+ ignored = !rule.negative;
460
+ unignored = rule.negative;
461
+ matchedRule = rule.negative ? UNDEFINED : rule;
462
+ break;
463
+ }
464
+ }
465
+ const ret = {
466
+ ignored,
467
+ unignored
468
+ };
469
+ if (matchedRule) ret.rule = matchedRule;
470
+ return ret;
471
+ }
472
+ test(path, mode) {
473
+ const rules = this._rules;
474
+ const { length } = rules;
475
+ const shortcut = this._basenameCount * 2 >= length;
476
+ const basename = shortcut ? basenameOf(path) : path;
477
+ for (let index = length - 1; index >= 0; index--) {
478
+ const rule = rules[index];
479
+ if (rule[mode].test(shortcut && rule._basenameOnly ? basename : path)) {
480
+ const { negative } = rule;
481
+ const ret = {
482
+ ignored: !negative,
483
+ unignored: negative
484
+ };
485
+ if (!negative) ret.rule = rule;
486
+ return ret;
487
+ }
488
+ }
489
+ return {
490
+ ignored: false,
491
+ unignored: false
492
+ };
493
+ }
494
+ };
495
+ const throwError = (message, Ctor) => {
496
+ throw new Ctor(message);
497
+ };
498
+ const checkPath = (path, originalPath, doThrow) => {
499
+ if (!isString(path)) return doThrow(`path must be a string, but got \`${originalPath}\``, TypeError);
500
+ if (!path) return doThrow(`path must not be empty`, TypeError);
501
+ if (checkPath.isNotRelative(path)) return doThrow(`path should be a \`path.relative()\`d string, but got "${originalPath}"`, RangeError);
502
+ return true;
503
+ };
504
+ const isNotRelative = (path) => {
505
+ const first = path.charCodeAt(0);
506
+ if (first === SLASH_CODE) return true;
507
+ if (first !== DOT_CODE) return false;
508
+ if (path.length === 1) return true;
509
+ const second = path.charCodeAt(1);
510
+ if (second === SLASH_CODE) return true;
511
+ if (second !== DOT_CODE) return false;
512
+ return path.length === 2 || path.charCodeAt(2) === SLASH_CODE;
513
+ };
514
+ checkPath.isNotRelative = isNotRelative;
515
+ /* istanbul ignore next */
516
+ checkPath.convert = (p) => p;
517
+ var Ignore = class {
518
+ constructor({ ignorecase = true, ignoreCase = ignorecase, allowRelativePaths = false } = {}) {
519
+ define(this, KEY_IGNORE, true);
520
+ this._rules = new RuleManager(ignoreCase);
521
+ this._strictPathCheck = !allowRelativePaths;
522
+ this._initCache();
523
+ }
524
+ _initCache() {
525
+ this._ignoreCache = Object.create(null);
526
+ this._testCache = Object.create(null);
527
+ }
528
+ add(pattern) {
529
+ if (this._rules.add(pattern)) this._initCache();
530
+ return this;
531
+ }
532
+ addPattern(pattern) {
533
+ return this.add(pattern);
534
+ }
535
+ _test(originalPath, cache) {
536
+ const path = originalPath && checkPath.convert(originalPath);
537
+ checkPath(path, originalPath, this._strictPathCheck ? throwError : RETURN_FALSE);
538
+ return this._t(path, cache);
539
+ }
540
+ checkIgnore(path) {
541
+ if (path.charCodeAt(path.length - 1) !== SLASH_CODE) return this.test(path);
542
+ const dir = this._t(path, this._testCache);
543
+ if (dir.ignored) return dir;
544
+ const literal = this._rules.testLiteral(path);
545
+ return literal.ignored || literal.unignored ? literal : dir;
546
+ }
547
+ _t(path, cache) {
548
+ if (path in cache) return cache[path];
549
+ const parentPath = parentOf(path);
550
+ const parent = parentPath ? this._t(parentPath, cache) : UNDEFINED;
551
+ return cache[path] = parent && parent.ignored ? parent : this._rules.test(path, MODE_IGNORE);
552
+ }
553
+ ignores(path) {
554
+ return this._test(path, this._ignoreCache).ignored;
555
+ }
556
+ createFilter() {
557
+ return (path) => !this.ignores(path);
558
+ }
559
+ filter(paths) {
560
+ return makeArray(paths).filter(this.createFilter());
561
+ }
562
+ test(path) {
563
+ return this._test(path, this._testCache);
564
+ }
565
+ };
566
+ const factory = (options) => new Ignore(options);
567
+ const isPathValid = (path) => checkPath(path && checkPath.convert(path), path, RETURN_FALSE);
568
+ /* istanbul ignore next */
569
+ const setupWindows = () => {
570
+ const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
571
+ checkPath.convert = makePosix;
572
+ const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
573
+ checkPath.isNotRelative = (path) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path);
574
+ };
575
+ /* istanbul ignore next */
576
+ if (typeof process !== "undefined" && process.platform === "win32") setupWindows();
577
+ module.exports = factory;
578
+ factory.default = factory;
579
+ module.exports.isPathValid = isPathValid;
580
+ define(module.exports, Symbol.for("setupWindows"), setupWindows);
581
+ })))(), 1);
582
+ const help = `Usage: kotlin-format [files/directories/globs...] [options]
583
+
584
+ --write Format files in place
585
+ --check Report files that need formatting (exit 1)
586
+ --stdin-filepath <file.kt> Format stdin; use this path for config and .kts
587
+ --config <path> Use an explicit JSON/JS/MJS/TS config
588
+ --style <KOTLINLANG|GOOGLE|META>
589
+ --max-width <1..999>
590
+ --remove-unused-imports / --no-remove-unused-imports
591
+ --preserve-lambda-breaks / --no-preserve-lambda-breaks
592
+ --help, -h Show help
593
+ --version, -v Show version
594
+
595
+ Without --write/--check, a single file (or stdin) is formatted to stdout.
596
+ With --write/--check and no paths, scan the current directory.
597
+ Directories scan .kt/.kts files and respect .gitignore; symlinks are skipped.
598
+ Exit codes: 0 success, 1 formatting required, 2 invalid input/config or failure.
599
+ `;
600
+ async function main() {
601
+ const { values, positionals } = parseArgs({
602
+ allowPositionals: true,
603
+ allowNegative: true,
604
+ options: {
605
+ write: { type: "boolean" },
606
+ check: { type: "boolean" },
607
+ "stdin-filepath": { type: "string" },
608
+ config: { type: "string" },
609
+ style: { type: "string" },
610
+ "max-width": { type: "string" },
611
+ "remove-unused-imports": { type: "boolean" },
612
+ "preserve-lambda-breaks": { type: "boolean" },
613
+ help: {
614
+ type: "boolean",
615
+ short: "h"
616
+ },
617
+ version: {
618
+ type: "boolean",
619
+ short: "v"
620
+ }
621
+ }
622
+ });
623
+ if (values.help) {
624
+ process.stdout.write(help);
625
+ return;
626
+ }
627
+ if (values.version) {
628
+ const pkg = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
629
+ process.stdout.write(`${pkg.version}\n`);
630
+ return;
631
+ }
632
+ if (values.write && values.check) throw new Error("--write and --check cannot be combined");
633
+ const overrides = {};
634
+ for (const [flag, key] of [
635
+ ["style", "style"],
636
+ ["max-width", "maxWidth"],
637
+ ["remove-unused-imports", "removeUnusedImports"],
638
+ ["preserve-lambda-breaks", "preserveLambdaBreaks"]
639
+ ]) if (values[flag] !== void 0) overrides[key] = flag === "max-width" ? Number(values[flag]) : values[flag];
640
+ const cliConfig = validateConfig(overrides, "arguments");
641
+ const stdin = values["stdin-filepath"] !== void 0 || positionals.includes("-") || !positionals.length && !values.write && !values.check;
642
+ if (stdin && (positionals.some((p) => p !== "-") || positionals.length > 1 || values.write)) throw new Error("stdin cannot be combined with file paths or --write");
643
+ if (stdin && process.stdin.isTTY) throw new Error("Provide a file path or pipe source to stdin");
644
+ const { formatWithOptions } = await import("./kotlin-format.mjs");
645
+ async function format(source, file) {
646
+ const config = {
647
+ ...await loadConfig(file, { configPath: values.config }),
648
+ ...cliConfig
649
+ };
650
+ const o = resolveOptions(config);
651
+ return formatWithOptions(source, o.maxWidth, o.blockIndent, o.continuationIndent, o.trailingCommas, o.removeUnusedImports, o.preserveLambdaBreaks, file.endsWith(".kts"));
652
+ }
653
+ if (stdin) {
654
+ const file = resolve(values["stdin-filepath"] ?? "stdin.kt");
655
+ const chunks = [];
656
+ for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
657
+ const source = Buffer.concat(chunks).toString("utf8");
658
+ const result = await format(source, file);
659
+ if (values.check) {
660
+ if (source !== result) {
661
+ process.stdout.write(`${file}\n`);
662
+ process.exitCode = 1;
663
+ }
664
+ } else process.stdout.write(result);
665
+ return;
666
+ }
667
+ const files = /* @__PURE__ */ new Set();
668
+ const ignoreCache = /* @__PURE__ */ new Map();
669
+ async function ignored(path, directory) {
670
+ const root = await projectRoot(path);
671
+ const parts = relative(root, path).split(sep);
672
+ let current = root;
673
+ const inherited = [];
674
+ for (let i = 0; i < parts.length; i++) {
675
+ if ([".git", "node_modules"].includes(parts[i])) return true;
676
+ let rules = ignoreCache.get(current);
677
+ if (!rules) {
678
+ rules = (0, import_ignore.default)();
679
+ const config = join(current, ".gitignore");
680
+ if (await exists(config)) rules.add(await readFile(config, "utf8"));
681
+ ignoreCache.set(current, rules);
682
+ }
683
+ inherited.push({
684
+ base: current,
685
+ rules
686
+ });
687
+ current = join(current, parts[i]);
688
+ let excluded = false;
689
+ for (const entry of inherited) {
690
+ const result = entry.rules.test(relative(entry.base, current).split(sep).join("/") + (i < parts.length - 1 || directory ? "/" : ""));
691
+ if (result.ignored) excluded = true;
692
+ else if (result.unignored) excluded = false;
693
+ }
694
+ if (excluded) return true;
695
+ }
696
+ return false;
697
+ }
698
+ async function visit(path) {
699
+ const info = await lstat(path);
700
+ if (info.isSymbolicLink() || await ignored(path, info.isDirectory())) return;
701
+ if (info.isDirectory()) for (const name of (await readdir(path)).sort()) await visit(join(path, name));
702
+ else if (info.isFile() && [".kt", ".kts"].includes(extname(path))) files.add(path);
703
+ }
704
+ for (const input of positionals.length ? positionals : ["."]) if (await exists(resolve(input))) await visit(resolve(input));
705
+ else {
706
+ let matched = false;
707
+ for await (const path of glob(input)) {
708
+ matched = true;
709
+ await visit(resolve(path));
710
+ }
711
+ if (!matched) throw new Error(`No files match: ${input}`);
712
+ }
713
+ if (!files.size) throw new Error("No Kotlin files found");
714
+ if (!values.write && !values.check && files.size !== 1) throw new Error("Use --write or --check for multiple files");
715
+ for (const file of [...files].sort()) try {
716
+ const source = await readFile(file, "utf8");
717
+ const result = await format(source, file);
718
+ if (values.write) {
719
+ if (source !== result) {
720
+ await writeFile(file, result);
721
+ process.stdout.write(`${file}\n`);
722
+ }
723
+ } else if (values.check) {
724
+ if (source !== result) {
725
+ process.stdout.write(`${file}\n`);
726
+ process.exitCode ||= 1;
727
+ }
728
+ } else process.stdout.write(result);
729
+ } catch (error) {
730
+ process.stderr.write(`${file}: ${error instanceof Error ? error.message : String(error)}\n`);
731
+ process.exitCode = 2;
732
+ }
733
+ }
734
+ main().catch((error) => {
735
+ process.stderr.write(`kotlin-format: ${error instanceof Error ? error.message : String(error)}\n`);
736
+ process.exitCode = 2;
737
+ });
738
+ export {};