@qodalis/cli-files 2.0.0-beta.16 → 2.0.0-beta.18
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/package.json +2 -2
- package/public-api.d.mts +137 -57
- package/public-api.d.ts +137 -57
- package/public-api.js +1758 -846
- package/public-api.js.map +1 -1
- package/public-api.mjs +1759 -847
- package/public-api.mjs.map +1 -1
- package/umd/index.global.js +1016 -377
package/umd/index.global.js
CHANGED
|
@@ -8,7 +8,11 @@ var files = (() => {
|
|
|
8
8
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
9
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
10
|
var __commonJS = (cb, mod) => function __require() {
|
|
11
|
-
|
|
11
|
+
try {
|
|
12
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw mod = 0, e;
|
|
15
|
+
}
|
|
12
16
|
};
|
|
13
17
|
var __copyProps = (to, from, except, desc) => {
|
|
14
18
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -27,7 +31,7 @@ var files = (() => {
|
|
|
27
31
|
mod
|
|
28
32
|
));
|
|
29
33
|
var require_constants = __commonJS({
|
|
30
|
-
"../../node_modules/.pnpm/semver@7.
|
|
34
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/constants.js"(exports, module2) {
|
|
31
35
|
var SEMVER_SPEC_VERSION = "2.0.0";
|
|
32
36
|
var MAX_LENGTH = 256;
|
|
33
37
|
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || /* istanbul ignore next */
|
|
@@ -56,26 +60,26 @@ var files = (() => {
|
|
|
56
60
|
}
|
|
57
61
|
});
|
|
58
62
|
var require_debug = __commonJS({
|
|
59
|
-
"../../node_modules/.pnpm/semver@7.
|
|
63
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/debug.js"(exports, module2) {
|
|
60
64
|
var debug = typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error("SEMVER", ...args) : () => {
|
|
61
65
|
};
|
|
62
66
|
module2.exports = debug;
|
|
63
67
|
}
|
|
64
68
|
});
|
|
65
69
|
var require_re = __commonJS({
|
|
66
|
-
"../../node_modules/.pnpm/semver@7.
|
|
70
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/re.js"(exports, module2) {
|
|
67
71
|
var {
|
|
68
72
|
MAX_SAFE_COMPONENT_LENGTH,
|
|
69
73
|
MAX_SAFE_BUILD_LENGTH,
|
|
70
74
|
MAX_LENGTH
|
|
71
75
|
} = require_constants();
|
|
72
76
|
var debug = require_debug();
|
|
73
|
-
exports
|
|
74
|
-
var re = exports
|
|
75
|
-
var safeRe = exports
|
|
76
|
-
var src = exports
|
|
77
|
-
var safeSrc = exports
|
|
78
|
-
var t = exports
|
|
77
|
+
exports = module2.exports = {};
|
|
78
|
+
var re = exports.re = [];
|
|
79
|
+
var safeRe = exports.safeRe = [];
|
|
80
|
+
var src = exports.src = [];
|
|
81
|
+
var safeSrc = exports.safeSrc = [];
|
|
82
|
+
var t = exports.t = {};
|
|
79
83
|
var R = 0;
|
|
80
84
|
var LETTERDASHNUMBER = "[a-zA-Z0-9-]";
|
|
81
85
|
var safeRegexReplacements = [
|
|
@@ -128,18 +132,18 @@ var files = (() => {
|
|
|
128
132
|
createToken("COERCERTLFULL", src[t.COERCEFULL], true);
|
|
129
133
|
createToken("LONETILDE", "(?:~>?)");
|
|
130
134
|
createToken("TILDETRIM", `(\\s*)${src[t.LONETILDE]}\\s+`, true);
|
|
131
|
-
exports
|
|
135
|
+
exports.tildeTrimReplace = "$1~";
|
|
132
136
|
createToken("TILDE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
|
|
133
137
|
createToken("TILDELOOSE", `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
|
|
134
138
|
createToken("LONECARET", "(?:\\^)");
|
|
135
139
|
createToken("CARETTRIM", `(\\s*)${src[t.LONECARET]}\\s+`, true);
|
|
136
|
-
exports
|
|
140
|
+
exports.caretTrimReplace = "$1^";
|
|
137
141
|
createToken("CARET", `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
|
|
138
142
|
createToken("CARETLOOSE", `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
|
|
139
143
|
createToken("COMPARATORLOOSE", `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`);
|
|
140
144
|
createToken("COMPARATOR", `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`);
|
|
141
145
|
createToken("COMPARATORTRIM", `(\\s*)${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
|
|
142
|
-
exports
|
|
146
|
+
exports.comparatorTrimReplace = "$1$2$3";
|
|
143
147
|
createToken("HYPHENRANGE", `^\\s*(${src[t.XRANGEPLAIN]})\\s+-\\s+(${src[t.XRANGEPLAIN]})\\s*$`);
|
|
144
148
|
createToken("HYPHENRANGELOOSE", `^\\s*(${src[t.XRANGEPLAINLOOSE]})\\s+-\\s+(${src[t.XRANGEPLAINLOOSE]})\\s*$`);
|
|
145
149
|
createToken("STAR", "(<|>)?=?\\s*\\*");
|
|
@@ -148,7 +152,7 @@ var files = (() => {
|
|
|
148
152
|
}
|
|
149
153
|
});
|
|
150
154
|
var require_parse_options = __commonJS({
|
|
151
|
-
"../../node_modules/.pnpm/semver@7.
|
|
155
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/parse-options.js"(exports, module2) {
|
|
152
156
|
var looseOption = Object.freeze({ loose: true });
|
|
153
157
|
var emptyOpts = Object.freeze({});
|
|
154
158
|
var parseOptions = (options) => {
|
|
@@ -164,7 +168,7 @@ var files = (() => {
|
|
|
164
168
|
}
|
|
165
169
|
});
|
|
166
170
|
var require_identifiers = __commonJS({
|
|
167
|
-
"../../node_modules/.pnpm/semver@7.
|
|
171
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/identifiers.js"(exports, module2) {
|
|
168
172
|
var numeric = /^[0-9]+$/;
|
|
169
173
|
var compareIdentifiers = (a, b) => {
|
|
170
174
|
if (typeof a === "number" && typeof b === "number") {
|
|
@@ -186,12 +190,24 @@ var files = (() => {
|
|
|
186
190
|
}
|
|
187
191
|
});
|
|
188
192
|
var require_semver = __commonJS({
|
|
189
|
-
"../../node_modules/.pnpm/semver@7.
|
|
193
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/semver.js"(exports, module2) {
|
|
190
194
|
var debug = require_debug();
|
|
191
195
|
var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
|
|
192
196
|
var { safeRe: re, t } = require_re();
|
|
193
197
|
var parseOptions = require_parse_options();
|
|
194
198
|
var { compareIdentifiers } = require_identifiers();
|
|
199
|
+
var isPrereleaseIdentifier = (prerelease, identifier) => {
|
|
200
|
+
const identifiers = identifier.split(".");
|
|
201
|
+
if (identifiers.length > prerelease.length) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
for (let i = 0; i < identifiers.length; i++) {
|
|
205
|
+
if (compareIdentifiers(prerelease[i], identifiers[i]) !== 0) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
};
|
|
195
211
|
var SemVer = class _SemVer {
|
|
196
212
|
constructor(version, options) {
|
|
197
213
|
options = parseOptions(options);
|
|
@@ -438,8 +454,9 @@ var files = (() => {
|
|
|
438
454
|
if (identifierBase === false) {
|
|
439
455
|
prerelease = [identifier];
|
|
440
456
|
}
|
|
441
|
-
if (
|
|
442
|
-
|
|
457
|
+
if (isPrereleaseIdentifier(this.prerelease, identifier)) {
|
|
458
|
+
const prereleaseBase = this.prerelease[identifier.split(".").length];
|
|
459
|
+
if (isNaN(prereleaseBase)) {
|
|
443
460
|
this.prerelease = prerelease;
|
|
444
461
|
}
|
|
445
462
|
} else {
|
|
@@ -462,7 +479,7 @@ var files = (() => {
|
|
|
462
479
|
}
|
|
463
480
|
});
|
|
464
481
|
var require_parse = __commonJS({
|
|
465
|
-
"../../node_modules/.pnpm/semver@7.
|
|
482
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js"(exports, module2) {
|
|
466
483
|
var SemVer = require_semver();
|
|
467
484
|
var parse = (version, options, throwErrors = false) => {
|
|
468
485
|
if (version instanceof SemVer) {
|
|
@@ -481,7 +498,7 @@ var files = (() => {
|
|
|
481
498
|
}
|
|
482
499
|
});
|
|
483
500
|
var require_valid = __commonJS({
|
|
484
|
-
"../../node_modules/.pnpm/semver@7.
|
|
501
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js"(exports, module2) {
|
|
485
502
|
var parse = require_parse();
|
|
486
503
|
var valid2 = (version, options) => {
|
|
487
504
|
const v = parse(version, options);
|
|
@@ -491,7 +508,7 @@ var files = (() => {
|
|
|
491
508
|
}
|
|
492
509
|
});
|
|
493
510
|
var require_clean = __commonJS({
|
|
494
|
-
"../../node_modules/.pnpm/semver@7.
|
|
511
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/clean.js"(exports, module2) {
|
|
495
512
|
var parse = require_parse();
|
|
496
513
|
var clean = (version, options) => {
|
|
497
514
|
const s = parse(version.trim().replace(/^[=v]+/, ""), options);
|
|
@@ -501,7 +518,7 @@ var files = (() => {
|
|
|
501
518
|
}
|
|
502
519
|
});
|
|
503
520
|
var require_inc = __commonJS({
|
|
504
|
-
"../../node_modules/.pnpm/semver@7.
|
|
521
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/inc.js"(exports, module2) {
|
|
505
522
|
var SemVer = require_semver();
|
|
506
523
|
var inc = (version, release, options, identifier, identifierBase) => {
|
|
507
524
|
if (typeof options === "string") {
|
|
@@ -522,7 +539,7 @@ var files = (() => {
|
|
|
522
539
|
}
|
|
523
540
|
});
|
|
524
541
|
var require_diff = __commonJS({
|
|
525
|
-
"../../node_modules/.pnpm/semver@7.
|
|
542
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/diff.js"(exports, module2) {
|
|
526
543
|
var parse = require_parse();
|
|
527
544
|
var diff = (version1, version2) => {
|
|
528
545
|
const v1 = parse(version1, null, true);
|
|
@@ -563,28 +580,28 @@ var files = (() => {
|
|
|
563
580
|
}
|
|
564
581
|
});
|
|
565
582
|
var require_major = __commonJS({
|
|
566
|
-
"../../node_modules/.pnpm/semver@7.
|
|
583
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/major.js"(exports, module2) {
|
|
567
584
|
var SemVer = require_semver();
|
|
568
585
|
var major = (a, loose) => new SemVer(a, loose).major;
|
|
569
586
|
module2.exports = major;
|
|
570
587
|
}
|
|
571
588
|
});
|
|
572
589
|
var require_minor = __commonJS({
|
|
573
|
-
"../../node_modules/.pnpm/semver@7.
|
|
590
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/minor.js"(exports, module2) {
|
|
574
591
|
var SemVer = require_semver();
|
|
575
592
|
var minor = (a, loose) => new SemVer(a, loose).minor;
|
|
576
593
|
module2.exports = minor;
|
|
577
594
|
}
|
|
578
595
|
});
|
|
579
596
|
var require_patch = __commonJS({
|
|
580
|
-
"../../node_modules/.pnpm/semver@7.
|
|
597
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/patch.js"(exports, module2) {
|
|
581
598
|
var SemVer = require_semver();
|
|
582
599
|
var patch = (a, loose) => new SemVer(a, loose).patch;
|
|
583
600
|
module2.exports = patch;
|
|
584
601
|
}
|
|
585
602
|
});
|
|
586
603
|
var require_prerelease = __commonJS({
|
|
587
|
-
"../../node_modules/.pnpm/semver@7.
|
|
604
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/prerelease.js"(exports, module2) {
|
|
588
605
|
var parse = require_parse();
|
|
589
606
|
var prerelease = (version, options) => {
|
|
590
607
|
const parsed = parse(version, options);
|
|
@@ -594,28 +611,28 @@ var files = (() => {
|
|
|
594
611
|
}
|
|
595
612
|
});
|
|
596
613
|
var require_compare = __commonJS({
|
|
597
|
-
"../../node_modules/.pnpm/semver@7.
|
|
614
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare.js"(exports, module2) {
|
|
598
615
|
var SemVer = require_semver();
|
|
599
616
|
var compare2 = (a, b, loose) => new SemVer(a, loose).compare(new SemVer(b, loose));
|
|
600
617
|
module2.exports = compare2;
|
|
601
618
|
}
|
|
602
619
|
});
|
|
603
620
|
var require_rcompare = __commonJS({
|
|
604
|
-
"../../node_modules/.pnpm/semver@7.
|
|
621
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rcompare.js"(exports, module2) {
|
|
605
622
|
var compare2 = require_compare();
|
|
606
623
|
var rcompare = (a, b, loose) => compare2(b, a, loose);
|
|
607
624
|
module2.exports = rcompare;
|
|
608
625
|
}
|
|
609
626
|
});
|
|
610
627
|
var require_compare_loose = __commonJS({
|
|
611
|
-
"../../node_modules/.pnpm/semver@7.
|
|
628
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-loose.js"(exports, module2) {
|
|
612
629
|
var compare2 = require_compare();
|
|
613
630
|
var compareLoose = (a, b) => compare2(a, b, true);
|
|
614
631
|
module2.exports = compareLoose;
|
|
615
632
|
}
|
|
616
633
|
});
|
|
617
634
|
var require_compare_build = __commonJS({
|
|
618
|
-
"../../node_modules/.pnpm/semver@7.
|
|
635
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/compare-build.js"(exports, module2) {
|
|
619
636
|
var SemVer = require_semver();
|
|
620
637
|
var compareBuild = (a, b, loose) => {
|
|
621
638
|
const versionA = new SemVer(a, loose);
|
|
@@ -626,63 +643,63 @@ var files = (() => {
|
|
|
626
643
|
}
|
|
627
644
|
});
|
|
628
645
|
var require_sort = __commonJS({
|
|
629
|
-
"../../node_modules/.pnpm/semver@7.
|
|
646
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/sort.js"(exports, module2) {
|
|
630
647
|
var compareBuild = require_compare_build();
|
|
631
648
|
var sort = (list2, loose) => list2.sort((a, b) => compareBuild(a, b, loose));
|
|
632
649
|
module2.exports = sort;
|
|
633
650
|
}
|
|
634
651
|
});
|
|
635
652
|
var require_rsort = __commonJS({
|
|
636
|
-
"../../node_modules/.pnpm/semver@7.
|
|
653
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/rsort.js"(exports, module2) {
|
|
637
654
|
var compareBuild = require_compare_build();
|
|
638
655
|
var rsort = (list2, loose) => list2.sort((a, b) => compareBuild(b, a, loose));
|
|
639
656
|
module2.exports = rsort;
|
|
640
657
|
}
|
|
641
658
|
});
|
|
642
659
|
var require_gt = __commonJS({
|
|
643
|
-
"../../node_modules/.pnpm/semver@7.
|
|
660
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gt.js"(exports, module2) {
|
|
644
661
|
var compare2 = require_compare();
|
|
645
662
|
var gt = (a, b, loose) => compare2(a, b, loose) > 0;
|
|
646
663
|
module2.exports = gt;
|
|
647
664
|
}
|
|
648
665
|
});
|
|
649
666
|
var require_lt = __commonJS({
|
|
650
|
-
"../../node_modules/.pnpm/semver@7.
|
|
667
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lt.js"(exports, module2) {
|
|
651
668
|
var compare2 = require_compare();
|
|
652
669
|
var lt = (a, b, loose) => compare2(a, b, loose) < 0;
|
|
653
670
|
module2.exports = lt;
|
|
654
671
|
}
|
|
655
672
|
});
|
|
656
673
|
var require_eq = __commonJS({
|
|
657
|
-
"../../node_modules/.pnpm/semver@7.
|
|
674
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/eq.js"(exports, module2) {
|
|
658
675
|
var compare2 = require_compare();
|
|
659
676
|
var eq = (a, b, loose) => compare2(a, b, loose) === 0;
|
|
660
677
|
module2.exports = eq;
|
|
661
678
|
}
|
|
662
679
|
});
|
|
663
680
|
var require_neq = __commonJS({
|
|
664
|
-
"../../node_modules/.pnpm/semver@7.
|
|
681
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/neq.js"(exports, module2) {
|
|
665
682
|
var compare2 = require_compare();
|
|
666
683
|
var neq = (a, b, loose) => compare2(a, b, loose) !== 0;
|
|
667
684
|
module2.exports = neq;
|
|
668
685
|
}
|
|
669
686
|
});
|
|
670
687
|
var require_gte = __commonJS({
|
|
671
|
-
"../../node_modules/.pnpm/semver@7.
|
|
688
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/gte.js"(exports, module2) {
|
|
672
689
|
var compare2 = require_compare();
|
|
673
690
|
var gte2 = (a, b, loose) => compare2(a, b, loose) >= 0;
|
|
674
691
|
module2.exports = gte2;
|
|
675
692
|
}
|
|
676
693
|
});
|
|
677
694
|
var require_lte = __commonJS({
|
|
678
|
-
"../../node_modules/.pnpm/semver@7.
|
|
695
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/lte.js"(exports, module2) {
|
|
679
696
|
var compare2 = require_compare();
|
|
680
697
|
var lte = (a, b, loose) => compare2(a, b, loose) <= 0;
|
|
681
698
|
module2.exports = lte;
|
|
682
699
|
}
|
|
683
700
|
});
|
|
684
701
|
var require_cmp = __commonJS({
|
|
685
|
-
"../../node_modules/.pnpm/semver@7.
|
|
702
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/cmp.js"(exports, module2) {
|
|
686
703
|
var eq = require_eq();
|
|
687
704
|
var neq = require_neq();
|
|
688
705
|
var gt = require_gt();
|
|
@@ -729,7 +746,7 @@ var files = (() => {
|
|
|
729
746
|
}
|
|
730
747
|
});
|
|
731
748
|
var require_coerce = __commonJS({
|
|
732
|
-
"../../node_modules/.pnpm/semver@7.
|
|
749
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/coerce.js"(exports, module2) {
|
|
733
750
|
var SemVer = require_semver();
|
|
734
751
|
var parse = require_parse();
|
|
735
752
|
var { safeRe: re, t } = require_re();
|
|
@@ -771,8 +788,46 @@ var files = (() => {
|
|
|
771
788
|
module2.exports = coerce2;
|
|
772
789
|
}
|
|
773
790
|
});
|
|
791
|
+
var require_truncate = __commonJS({
|
|
792
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/truncate.js"(exports, module2) {
|
|
793
|
+
var parse = require_parse();
|
|
794
|
+
var constants2 = require_constants();
|
|
795
|
+
var SemVer = require_semver();
|
|
796
|
+
var truncate = (version, truncation, options) => {
|
|
797
|
+
if (!constants2.RELEASE_TYPES.includes(truncation)) {
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
const clonedVersion = cloneInputVersion(version, options);
|
|
801
|
+
return clonedVersion && doTruncation(clonedVersion, truncation);
|
|
802
|
+
};
|
|
803
|
+
var cloneInputVersion = (version, options) => {
|
|
804
|
+
const versionStringToParse = version instanceof SemVer ? version.version : version;
|
|
805
|
+
return parse(versionStringToParse, options);
|
|
806
|
+
};
|
|
807
|
+
var doTruncation = (version, truncation) => {
|
|
808
|
+
if (isPrerelease(truncation)) {
|
|
809
|
+
return version.version;
|
|
810
|
+
}
|
|
811
|
+
version.prerelease = [];
|
|
812
|
+
switch (truncation) {
|
|
813
|
+
case "major":
|
|
814
|
+
version.minor = 0;
|
|
815
|
+
version.patch = 0;
|
|
816
|
+
break;
|
|
817
|
+
case "minor":
|
|
818
|
+
version.patch = 0;
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
return version.format();
|
|
822
|
+
};
|
|
823
|
+
var isPrerelease = (type) => {
|
|
824
|
+
return type.startsWith("pre");
|
|
825
|
+
};
|
|
826
|
+
module2.exports = truncate;
|
|
827
|
+
}
|
|
828
|
+
});
|
|
774
829
|
var require_lrucache = __commonJS({
|
|
775
|
-
"../../node_modules/.pnpm/semver@7.
|
|
830
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/internal/lrucache.js"(exports, module2) {
|
|
776
831
|
var LRUCache = class {
|
|
777
832
|
constructor() {
|
|
778
833
|
this.max = 1e3;
|
|
@@ -807,7 +862,7 @@ var files = (() => {
|
|
|
807
862
|
}
|
|
808
863
|
});
|
|
809
864
|
var require_range = __commonJS({
|
|
810
|
-
"../../node_modules/.pnpm/semver@7.
|
|
865
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/range.js"(exports, module2) {
|
|
811
866
|
var SPACE_CHARACTERS = /\s+/g;
|
|
812
867
|
var Range = class _Range {
|
|
813
868
|
constructor(range, options) {
|
|
@@ -874,6 +929,7 @@ var files = (() => {
|
|
|
874
929
|
return this.range;
|
|
875
930
|
}
|
|
876
931
|
parseRange(range) {
|
|
932
|
+
range = range.replace(BUILDSTRIPRE, "");
|
|
877
933
|
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
|
|
878
934
|
const memoKey = memoOpts + ":" + range;
|
|
879
935
|
const cached = cache.get(memoKey);
|
|
@@ -956,12 +1012,14 @@ var files = (() => {
|
|
|
956
1012
|
var SemVer = require_semver();
|
|
957
1013
|
var {
|
|
958
1014
|
safeRe: re,
|
|
1015
|
+
src,
|
|
959
1016
|
t,
|
|
960
1017
|
comparatorTrimReplace,
|
|
961
1018
|
tildeTrimReplace,
|
|
962
1019
|
caretTrimReplace
|
|
963
1020
|
} = require_re();
|
|
964
1021
|
var { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require_constants();
|
|
1022
|
+
var BUILDSTRIPRE = new RegExp(src[t.BUILD], "g");
|
|
965
1023
|
var isNullSet = (c) => c.value === "<0.0.0-0";
|
|
966
1024
|
var isAny = (c) => c.value === "";
|
|
967
1025
|
var isSatisfiable = (comparators, options) => {
|
|
@@ -990,20 +1048,22 @@ var files = (() => {
|
|
|
990
1048
|
return comp;
|
|
991
1049
|
};
|
|
992
1050
|
var isX = (id) => !id || id.toLowerCase() === "x" || id === "*";
|
|
1051
|
+
var invalidXRangeOrder = (M, m, p) => isX(M) && !isX(m) || isX(m) && p && !isX(p);
|
|
993
1052
|
var replaceTildes = (comp, options) => {
|
|
994
1053
|
return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" ");
|
|
995
1054
|
};
|
|
996
1055
|
var replaceTilde = (comp, options) => {
|
|
997
1056
|
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE];
|
|
1057
|
+
const z = options.includePrerelease ? "-0" : "";
|
|
998
1058
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
999
1059
|
debug("tilde", comp, _, M, m, p, pr);
|
|
1000
1060
|
let ret;
|
|
1001
1061
|
if (isX(M)) {
|
|
1002
1062
|
ret = "";
|
|
1003
1063
|
} else if (isX(m)) {
|
|
1004
|
-
ret = `>=${M}.0.0 <${+M + 1}.0.0-0`;
|
|
1064
|
+
ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`;
|
|
1005
1065
|
} else if (isX(p)) {
|
|
1006
|
-
ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`;
|
|
1066
|
+
ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`;
|
|
1007
1067
|
} else if (pr) {
|
|
1008
1068
|
debug("replaceTilde pr", pr);
|
|
1009
1069
|
ret = `>=${M}.${m}.${p}-${pr} <${M}.${+m + 1}.0-0`;
|
|
@@ -1049,9 +1109,9 @@ var files = (() => {
|
|
|
1049
1109
|
debug("no pr");
|
|
1050
1110
|
if (M === "0") {
|
|
1051
1111
|
if (m === "0") {
|
|
1052
|
-
ret = `>=${M}.${m}.${p}
|
|
1112
|
+
ret = `>=${M}.${m}.${p} <${M}.${m}.${+p + 1}-0`;
|
|
1053
1113
|
} else {
|
|
1054
|
-
ret = `>=${M}.${m}.${p}
|
|
1114
|
+
ret = `>=${M}.${m}.${p} <${M}.${+m + 1}.0-0`;
|
|
1055
1115
|
}
|
|
1056
1116
|
} else {
|
|
1057
1117
|
ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`;
|
|
@@ -1070,6 +1130,9 @@ var files = (() => {
|
|
|
1070
1130
|
const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE];
|
|
1071
1131
|
return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
|
|
1072
1132
|
debug("xRange", comp, ret, gtlt, M, m, p, pr);
|
|
1133
|
+
if (invalidXRangeOrder(M, m, p)) {
|
|
1134
|
+
return comp;
|
|
1135
|
+
}
|
|
1073
1136
|
const xM = isX(M);
|
|
1074
1137
|
const xm = xM || isX(m);
|
|
1075
1138
|
const xp = xm || isX(p);
|
|
@@ -1181,7 +1244,7 @@ var files = (() => {
|
|
|
1181
1244
|
}
|
|
1182
1245
|
});
|
|
1183
1246
|
var require_comparator = __commonJS({
|
|
1184
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1247
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/classes/comparator.js"(exports, module2) {
|
|
1185
1248
|
var ANY = /* @__PURE__ */ Symbol("SemVer ANY");
|
|
1186
1249
|
var Comparator = class _Comparator {
|
|
1187
1250
|
static get ANY() {
|
|
@@ -1291,7 +1354,7 @@ var files = (() => {
|
|
|
1291
1354
|
}
|
|
1292
1355
|
});
|
|
1293
1356
|
var require_satisfies = __commonJS({
|
|
1294
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1357
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js"(exports, module2) {
|
|
1295
1358
|
var Range = require_range();
|
|
1296
1359
|
var satisfies2 = (version, range, options) => {
|
|
1297
1360
|
try {
|
|
@@ -1305,14 +1368,14 @@ var files = (() => {
|
|
|
1305
1368
|
}
|
|
1306
1369
|
});
|
|
1307
1370
|
var require_to_comparators = __commonJS({
|
|
1308
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1371
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/to-comparators.js"(exports, module2) {
|
|
1309
1372
|
var Range = require_range();
|
|
1310
1373
|
var toComparators = (range, options) => new Range(range, options).set.map((comp) => comp.map((c) => c.value).join(" ").trim().split(" "));
|
|
1311
1374
|
module2.exports = toComparators;
|
|
1312
1375
|
}
|
|
1313
1376
|
});
|
|
1314
1377
|
var require_max_satisfying = __commonJS({
|
|
1315
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1378
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/max-satisfying.js"(exports, module2) {
|
|
1316
1379
|
var SemVer = require_semver();
|
|
1317
1380
|
var Range = require_range();
|
|
1318
1381
|
var maxSatisfying = (versions, range, options) => {
|
|
@@ -1338,7 +1401,7 @@ var files = (() => {
|
|
|
1338
1401
|
}
|
|
1339
1402
|
});
|
|
1340
1403
|
var require_min_satisfying = __commonJS({
|
|
1341
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1404
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-satisfying.js"(exports, module2) {
|
|
1342
1405
|
var SemVer = require_semver();
|
|
1343
1406
|
var Range = require_range();
|
|
1344
1407
|
var minSatisfying = (versions, range, options) => {
|
|
@@ -1364,7 +1427,7 @@ var files = (() => {
|
|
|
1364
1427
|
}
|
|
1365
1428
|
});
|
|
1366
1429
|
var require_min_version = __commonJS({
|
|
1367
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1430
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/min-version.js"(exports, module2) {
|
|
1368
1431
|
var SemVer = require_semver();
|
|
1369
1432
|
var Range = require_range();
|
|
1370
1433
|
var gt = require_gt();
|
|
@@ -1420,7 +1483,7 @@ var files = (() => {
|
|
|
1420
1483
|
}
|
|
1421
1484
|
});
|
|
1422
1485
|
var require_valid2 = __commonJS({
|
|
1423
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1486
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/valid.js"(exports, module2) {
|
|
1424
1487
|
var Range = require_range();
|
|
1425
1488
|
var validRange = (range, options) => {
|
|
1426
1489
|
try {
|
|
@@ -1433,7 +1496,7 @@ var files = (() => {
|
|
|
1433
1496
|
}
|
|
1434
1497
|
});
|
|
1435
1498
|
var require_outside = __commonJS({
|
|
1436
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1499
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/outside.js"(exports, module2) {
|
|
1437
1500
|
var SemVer = require_semver();
|
|
1438
1501
|
var Comparator = require_comparator();
|
|
1439
1502
|
var { ANY } = Comparator;
|
|
@@ -1499,21 +1562,21 @@ var files = (() => {
|
|
|
1499
1562
|
}
|
|
1500
1563
|
});
|
|
1501
1564
|
var require_gtr = __commonJS({
|
|
1502
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1565
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/gtr.js"(exports, module2) {
|
|
1503
1566
|
var outside = require_outside();
|
|
1504
1567
|
var gtr = (version, range, options) => outside(version, range, ">", options);
|
|
1505
1568
|
module2.exports = gtr;
|
|
1506
1569
|
}
|
|
1507
1570
|
});
|
|
1508
1571
|
var require_ltr = __commonJS({
|
|
1509
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1572
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/ltr.js"(exports, module2) {
|
|
1510
1573
|
var outside = require_outside();
|
|
1511
1574
|
var ltr = (version, range, options) => outside(version, range, "<", options);
|
|
1512
1575
|
module2.exports = ltr;
|
|
1513
1576
|
}
|
|
1514
1577
|
});
|
|
1515
1578
|
var require_intersects = __commonJS({
|
|
1516
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1579
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/intersects.js"(exports, module2) {
|
|
1517
1580
|
var Range = require_range();
|
|
1518
1581
|
var intersects = (r1, r2, options) => {
|
|
1519
1582
|
r1 = new Range(r1, options);
|
|
@@ -1524,7 +1587,7 @@ var files = (() => {
|
|
|
1524
1587
|
}
|
|
1525
1588
|
});
|
|
1526
1589
|
var require_simplify = __commonJS({
|
|
1527
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1590
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/simplify.js"(exports, module2) {
|
|
1528
1591
|
var satisfies2 = require_satisfies();
|
|
1529
1592
|
var compare2 = require_compare();
|
|
1530
1593
|
module2.exports = (versions, range, options) => {
|
|
@@ -1571,7 +1634,7 @@ var files = (() => {
|
|
|
1571
1634
|
}
|
|
1572
1635
|
});
|
|
1573
1636
|
var require_subset = __commonJS({
|
|
1574
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1637
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/subset.js"(exports, module2) {
|
|
1575
1638
|
var Range = require_range();
|
|
1576
1639
|
var Comparator = require_comparator();
|
|
1577
1640
|
var { ANY } = Comparator;
|
|
@@ -1678,7 +1741,7 @@ var files = (() => {
|
|
|
1678
1741
|
if (higher === c && higher !== gt) {
|
|
1679
1742
|
return false;
|
|
1680
1743
|
}
|
|
1681
|
-
} else if (gt.operator === ">=" && !
|
|
1744
|
+
} else if (gt.operator === ">=" && !c.test(gt.semver)) {
|
|
1682
1745
|
return false;
|
|
1683
1746
|
}
|
|
1684
1747
|
}
|
|
@@ -1693,7 +1756,7 @@ var files = (() => {
|
|
|
1693
1756
|
if (lower === c && lower !== lt) {
|
|
1694
1757
|
return false;
|
|
1695
1758
|
}
|
|
1696
|
-
} else if (lt.operator === "<=" && !
|
|
1759
|
+
} else if (lt.operator === "<=" && !c.test(lt.semver)) {
|
|
1697
1760
|
return false;
|
|
1698
1761
|
}
|
|
1699
1762
|
}
|
|
@@ -1730,7 +1793,7 @@ var files = (() => {
|
|
|
1730
1793
|
}
|
|
1731
1794
|
});
|
|
1732
1795
|
var require_semver2 = __commonJS({
|
|
1733
|
-
"../../node_modules/.pnpm/semver@7.
|
|
1796
|
+
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/index.js"(exports, module2) {
|
|
1734
1797
|
var internalRe = require_re();
|
|
1735
1798
|
var constants2 = require_constants();
|
|
1736
1799
|
var SemVer = require_semver();
|
|
@@ -1758,6 +1821,7 @@ var files = (() => {
|
|
|
1758
1821
|
var lte = require_lte();
|
|
1759
1822
|
var cmp = require_cmp();
|
|
1760
1823
|
var coerce2 = require_coerce();
|
|
1824
|
+
var truncate = require_truncate();
|
|
1761
1825
|
var Comparator = require_comparator();
|
|
1762
1826
|
var Range = require_range();
|
|
1763
1827
|
var satisfies2 = require_satisfies();
|
|
@@ -1796,6 +1860,7 @@ var files = (() => {
|
|
|
1796
1860
|
lte,
|
|
1797
1861
|
cmp,
|
|
1798
1862
|
coerce: coerce2,
|
|
1863
|
+
truncate,
|
|
1799
1864
|
Comparator,
|
|
1800
1865
|
Range,
|
|
1801
1866
|
satisfies: satisfies2,
|
|
@@ -1833,11 +1898,34 @@ var files = (() => {
|
|
|
1833
1898
|
CliForegroundColor2["Reset"] = "\x1B[0m";
|
|
1834
1899
|
return CliForegroundColor2;
|
|
1835
1900
|
})(CliForegroundColor || {});
|
|
1836
|
-
|
|
1901
|
+
function createCliToken(name) {
|
|
1902
|
+
return name;
|
|
1903
|
+
}
|
|
1904
|
+
var ICliUserSessionService_TOKEN = createCliToken("cli-user-session-service");
|
|
1905
|
+
var ICliUsersStoreService_TOKEN = createCliToken("cli-users-store-service");
|
|
1906
|
+
var ICliGroupsStoreService_TOKEN = createCliToken("cli-groups-store-service");
|
|
1907
|
+
var ICliAuthService_TOKEN = createCliToken("cli-auth-service");
|
|
1908
|
+
var ICliCompletionProvider_TOKEN = createCliToken("cli-completion-provider");
|
|
1909
|
+
var ICliDragDropService_TOKEN = createCliToken("cli-drag-drop-service");
|
|
1910
|
+
var ICliFileTransferService_TOKEN = createCliToken("cli-file-transfer-service");
|
|
1911
|
+
var ICliTranslationService_TOKEN = createCliToken("cli-translation-service");
|
|
1912
|
+
var ICliPermissionService_TOKEN = createCliToken("cli-permission-service");
|
|
1913
|
+
var ICliFilePickerProvider_TOKEN = createCliToken("cli-file-picker-provider");
|
|
1914
|
+
var ICliHttpClient_TOKEN = createCliToken("cli-http-client");
|
|
1915
|
+
var ICliUserEventService_TOKEN = createCliToken("cli-user-event-service");
|
|
1916
|
+
var ICliAuditService_TOKEN = createCliToken("cli-audit-service");
|
|
1917
|
+
var ICliAuthorizationService_TOKEN = createCliToken("cli-authorization-service");
|
|
1918
|
+
var ICliPermissionRegistry_TOKEN = createCliToken("cli-permission-registry");
|
|
1919
|
+
var ICliSessionsService_TOKEN = createCliToken("cli-sessions-service");
|
|
1920
|
+
var ICliKeyValueStore_TOKEN = createCliToken("cli-key-value-store");
|
|
1921
|
+
var ICliServerAuthTokenProvider_TOKEN = createCliToken("cli-server-auth-token-provider");
|
|
1922
|
+
var ICliServerAuthService_TOKEN = createCliToken("cli-server-auth-service");
|
|
1923
|
+
var ICliServerManager_TOKEN = createCliToken("cli-server-manager");
|
|
1837
1924
|
function resolveHeaders(provider) {
|
|
1838
1925
|
if (!provider) return {};
|
|
1839
1926
|
return typeof provider === "function" ? provider() : provider;
|
|
1840
1927
|
}
|
|
1928
|
+
var ICliCommandGuard_TOKEN = createCliToken("cli-command-guard");
|
|
1841
1929
|
var CliAccessDeniedError = class _CliAccessDeniedError extends Error {
|
|
1842
1930
|
constructor(message = "permission denied") {
|
|
1843
1931
|
super(message);
|
|
@@ -1849,10 +1937,55 @@ var files = (() => {
|
|
|
1849
1937
|
function isCliAccessDeniedError(error) {
|
|
1850
1938
|
return error instanceof CliAccessDeniedError || !!error && typeof error === "object" && error.name === "CliAccessDeniedError";
|
|
1851
1939
|
}
|
|
1940
|
+
var ICliEventBus_TOKEN = createCliToken("cli-event-bus");
|
|
1852
1941
|
var DefaultLibraryAuthor = {
|
|
1853
1942
|
name: "Nicolae Lupei",
|
|
1854
1943
|
email: "nicolae.lupei@qodalis.com"
|
|
1855
1944
|
};
|
|
1945
|
+
function splitShellWords(text) {
|
|
1946
|
+
const words = [];
|
|
1947
|
+
let current = "";
|
|
1948
|
+
let inWord = false;
|
|
1949
|
+
for (let i = 0; i < text.length; i++) {
|
|
1950
|
+
const ch = text[i];
|
|
1951
|
+
if (ch === "\\" && i + 1 < text.length) {
|
|
1952
|
+
current += text[++i];
|
|
1953
|
+
inWord = true;
|
|
1954
|
+
} else if (ch === "'" && text.indexOf("'", i + 1) !== -1) {
|
|
1955
|
+
const end = text.indexOf("'", i + 1);
|
|
1956
|
+
current += text.slice(i + 1, end);
|
|
1957
|
+
inWord = true;
|
|
1958
|
+
i = end;
|
|
1959
|
+
} else if (ch === '"' && closingDoubleQuote(text, i) !== -1) {
|
|
1960
|
+
const end = closingDoubleQuote(text, i);
|
|
1961
|
+
current += unescapeDoubleQuoted(text.slice(i + 1, end));
|
|
1962
|
+
inWord = true;
|
|
1963
|
+
i = end;
|
|
1964
|
+
} else if (/\s/.test(ch)) {
|
|
1965
|
+
if (inWord) words.push(current);
|
|
1966
|
+
current = "";
|
|
1967
|
+
inWord = false;
|
|
1968
|
+
} else {
|
|
1969
|
+
current += ch;
|
|
1970
|
+
inWord = true;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
if (inWord) words.push(current);
|
|
1974
|
+
return words;
|
|
1975
|
+
}
|
|
1976
|
+
function joinShellWords(text) {
|
|
1977
|
+
return splitShellWords(text).join(" ");
|
|
1978
|
+
}
|
|
1979
|
+
function closingDoubleQuote(text, start) {
|
|
1980
|
+
for (let i = start + 1; i < text.length; i++) {
|
|
1981
|
+
if (text[i] === "\\") i++;
|
|
1982
|
+
else if (text[i] === '"') return i;
|
|
1983
|
+
}
|
|
1984
|
+
return -1;
|
|
1985
|
+
}
|
|
1986
|
+
function unescapeDoubleQuoted(text) {
|
|
1987
|
+
return text.replace(/\\(["\\$`])/g, "$1");
|
|
1988
|
+
}
|
|
1856
1989
|
var semver = __toESM(require_semver2());
|
|
1857
1990
|
var API_VERSION = 2;
|
|
1858
1991
|
var VERSIONS_ENDPOINT = "/api/qcli/versions";
|
|
@@ -1875,12 +2008,18 @@ var files = (() => {
|
|
|
1875
2008
|
* Returns the negotiated API version and the base path for all subsequent calls,
|
|
1876
2009
|
* or null if the server is unreachable or incompatible.
|
|
1877
2010
|
*/
|
|
1878
|
-
static async discover(baseUrl, headers) {
|
|
2011
|
+
static async discover(baseUrl, headers, options) {
|
|
2012
|
+
let response;
|
|
1879
2013
|
try {
|
|
1880
2014
|
const resolved = resolveHeaders(headers);
|
|
1881
|
-
|
|
2015
|
+
response = await fetch(`${baseUrl}${VERSIONS_ENDPOINT}`, {
|
|
1882
2016
|
headers: Object.keys(resolved).length > 0 ? resolved : void 0
|
|
1883
2017
|
});
|
|
2018
|
+
} catch (e) {
|
|
2019
|
+
if (options?.rethrowNetworkErrors) throw e;
|
|
2020
|
+
return null;
|
|
2021
|
+
}
|
|
2022
|
+
try {
|
|
1884
2023
|
if (!response.ok) return null;
|
|
1885
2024
|
const info = await response.json();
|
|
1886
2025
|
const version = this.negotiate(info);
|
|
@@ -1894,6 +2033,60 @@ var files = (() => {
|
|
|
1894
2033
|
}
|
|
1895
2034
|
}
|
|
1896
2035
|
};
|
|
2036
|
+
function writeColumns(context, rows, formatLeft, formatRight) {
|
|
2037
|
+
const width = Math.max(...rows.map(([left]) => left.length)) + 2;
|
|
2038
|
+
for (const [left, right] of rows) {
|
|
2039
|
+
context.writer.writeln(
|
|
2040
|
+
` ${formatLeft(left.padEnd(width))}${formatRight(right)}`
|
|
2041
|
+
);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
function writeUsage(context, rows) {
|
|
2045
|
+
const { writer, translator } = context;
|
|
2046
|
+
writer.writeln(`\u{1F4CB} ${translator.t("cli.common.usage", "Usage:")}`);
|
|
2047
|
+
writeColumns(
|
|
2048
|
+
context,
|
|
2049
|
+
rows,
|
|
2050
|
+
(cmd) => writer.wrapInColor(
|
|
2051
|
+
cmd,
|
|
2052
|
+
"\x1B[36m"
|
|
2053
|
+
/* Cyan */
|
|
2054
|
+
),
|
|
2055
|
+
(text) => text
|
|
2056
|
+
);
|
|
2057
|
+
}
|
|
2058
|
+
function writeExamples(context, rows) {
|
|
2059
|
+
const { writer, translator } = context;
|
|
2060
|
+
writer.writeln(`\u{1F4DD} ${translator.t("cli.common.examples", "Examples:")}`);
|
|
2061
|
+
writeColumns(
|
|
2062
|
+
context,
|
|
2063
|
+
rows,
|
|
2064
|
+
(cmd) => cmd,
|
|
2065
|
+
(comment) => writer.wrapInColor(
|
|
2066
|
+
`# ${comment}`,
|
|
2067
|
+
"\x1B[32m"
|
|
2068
|
+
/* Green */
|
|
2069
|
+
)
|
|
2070
|
+
);
|
|
2071
|
+
}
|
|
2072
|
+
function writeWrapped(context, text, indent = 0) {
|
|
2073
|
+
const cols = context.terminal?.cols ?? 80;
|
|
2074
|
+
const width = Math.max(20, Math.min(cols - 1, 100) - indent);
|
|
2075
|
+
const pad = " ".repeat(indent);
|
|
2076
|
+
let line = "";
|
|
2077
|
+
for (const word of text.split(/\s+/).filter(Boolean)) {
|
|
2078
|
+
if (line && visibleLength2(line) + 1 + visibleLength2(word) > width) {
|
|
2079
|
+
context.writer.writeln(pad + line);
|
|
2080
|
+
line = word;
|
|
2081
|
+
} else {
|
|
2082
|
+
line = line ? `${line} ${word}` : word;
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
if (line) context.writer.writeln(pad + line);
|
|
2086
|
+
}
|
|
2087
|
+
function visibleLength2(text) {
|
|
2088
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
2089
|
+
}
|
|
1897
2090
|
var bootCliModule = async (module2) => {
|
|
1898
2091
|
if (typeof window !== "undefined" && window.__cliModuleRegistry) {
|
|
1899
2092
|
await window.__cliModuleRegistry.register(module2);
|
|
@@ -2712,11 +2905,11 @@ var files = (() => {
|
|
|
2712
2905
|
};
|
|
2713
2906
|
|
|
2714
2907
|
// src/lib/version.ts
|
|
2715
|
-
var LIBRARY_VERSION = "2.0.0-beta.
|
|
2908
|
+
var LIBRARY_VERSION = "2.0.0-beta.18";
|
|
2716
2909
|
var API_VERSION2 = 2;
|
|
2717
2910
|
|
|
2718
2911
|
// src/lib/interfaces/i-file-system-service.ts
|
|
2719
|
-
var IFileSystemService_TOKEN = "cli-file-system-service";
|
|
2912
|
+
var IFileSystemService_TOKEN = createCliToken("cli-file-system-service");
|
|
2720
2913
|
|
|
2721
2914
|
// src/lib/services/indexed-db-file-system.service.ts
|
|
2722
2915
|
var DB_NAME = "qodalis-cli-filesystem";
|
|
@@ -3184,6 +3377,11 @@ var files = (() => {
|
|
|
3184
3377
|
}
|
|
3185
3378
|
const destResolved = this.resolvePath(dest);
|
|
3186
3379
|
const destNode = this.getNode(destResolved);
|
|
3380
|
+
if (srcNode.type === "directory" && (destResolved === srcResolved || destResolved.startsWith(srcResolved + "/"))) {
|
|
3381
|
+
throw new Error(
|
|
3382
|
+
`mv: cannot move '${src}' to a subdirectory of itself, '${dest}'`
|
|
3383
|
+
);
|
|
3384
|
+
}
|
|
3187
3385
|
const srcParts = srcResolved.split("/").filter(Boolean);
|
|
3188
3386
|
const srcParentPath = "/" + srcParts.slice(0, -1).join("/");
|
|
3189
3387
|
const srcParent = this.getNode(srcParentPath);
|
|
@@ -3191,9 +3389,9 @@ var files = (() => {
|
|
|
3191
3389
|
throw new Error(`mv: ${src}: No such file or directory`);
|
|
3192
3390
|
}
|
|
3193
3391
|
this.assertModifyDir(srcParent, srcParentPath, "mv", src);
|
|
3194
|
-
|
|
3195
|
-
(
|
|
3196
|
-
|
|
3392
|
+
if (destResolved === srcResolved || destNode && destNode.type === "directory" && destNode === srcParent) {
|
|
3393
|
+
throw new Error(`mv: '${src}' and '${dest}' are the same file`);
|
|
3394
|
+
}
|
|
3197
3395
|
if (destNode && destNode.type === "directory") {
|
|
3198
3396
|
this.assertModifyDir(destNode, destResolved, "mv", dest);
|
|
3199
3397
|
if (!destNode.children) {
|
|
@@ -3205,7 +3403,7 @@ var files = (() => {
|
|
|
3205
3403
|
if (existingIdx !== -1) {
|
|
3206
3404
|
destNode.children.splice(existingIdx, 1);
|
|
3207
3405
|
}
|
|
3208
|
-
srcParent.children.splice(
|
|
3406
|
+
srcParent.children.splice(srcParent.children.indexOf(srcNode), 1);
|
|
3209
3407
|
destNode.children.push(srcNode);
|
|
3210
3408
|
destNode.modifiedAt = Date.now();
|
|
3211
3409
|
} else {
|
|
@@ -3219,7 +3417,7 @@ var files = (() => {
|
|
|
3219
3417
|
);
|
|
3220
3418
|
}
|
|
3221
3419
|
this.assertModifyDir(destParent, destParentPath, "mv", dest);
|
|
3222
|
-
srcParent.children.splice(
|
|
3420
|
+
srcParent.children.splice(srcParent.children.indexOf(srcNode), 1);
|
|
3223
3421
|
srcNode.name = newName;
|
|
3224
3422
|
if (!destParent.children) {
|
|
3225
3423
|
destParent.children = [];
|
|
@@ -3370,7 +3568,26 @@ var files = (() => {
|
|
|
3370
3568
|
"find",
|
|
3371
3569
|
"head",
|
|
3372
3570
|
"tail",
|
|
3373
|
-
"wc"
|
|
3571
|
+
"wc",
|
|
3572
|
+
"sort",
|
|
3573
|
+
"uniq",
|
|
3574
|
+
"cut",
|
|
3575
|
+
"paste",
|
|
3576
|
+
"tac",
|
|
3577
|
+
"diff",
|
|
3578
|
+
"sed",
|
|
3579
|
+
"awk",
|
|
3580
|
+
"du",
|
|
3581
|
+
"stat",
|
|
3582
|
+
"chmod",
|
|
3583
|
+
"chown",
|
|
3584
|
+
"ln",
|
|
3585
|
+
"tee",
|
|
3586
|
+
"basename",
|
|
3587
|
+
"dirname",
|
|
3588
|
+
"sh",
|
|
3589
|
+
"source",
|
|
3590
|
+
"xargs"
|
|
3374
3591
|
]);
|
|
3375
3592
|
var FilePathCompletionProvider = class {
|
|
3376
3593
|
constructor(fs) {
|
|
@@ -3389,7 +3606,14 @@ var files = (() => {
|
|
|
3389
3606
|
if (token.startsWith("-")) {
|
|
3390
3607
|
return [];
|
|
3391
3608
|
}
|
|
3392
|
-
|
|
3609
|
+
const quote = token.startsWith('"') || token.startsWith("'") ? token[0] : "";
|
|
3610
|
+
const partial = quote ? token.slice(1).replace(new RegExp(`${quote}$`), "") : token;
|
|
3611
|
+
const paths = this.completePath(partial);
|
|
3612
|
+
if (!quote && !paths.some((p) => /\s/.test(p))) {
|
|
3613
|
+
return paths;
|
|
3614
|
+
}
|
|
3615
|
+
const q = quote || '"';
|
|
3616
|
+
return paths.map((p) => p.endsWith("/") ? `${q}${p}` : `${q}${p}${q}`);
|
|
3393
3617
|
}
|
|
3394
3618
|
completePath(partial) {
|
|
3395
3619
|
let dirPath;
|
|
@@ -3433,6 +3657,11 @@ var files = (() => {
|
|
|
3433
3657
|
}
|
|
3434
3658
|
};
|
|
3435
3659
|
|
|
3660
|
+
// src/lib/utils/split-args.ts
|
|
3661
|
+
function splitArgs(raw) {
|
|
3662
|
+
return splitShellWords(raw);
|
|
3663
|
+
}
|
|
3664
|
+
|
|
3436
3665
|
// src/lib/processors/cli-ls-command-processor.ts
|
|
3437
3666
|
var CliLsCommandProcessor = class {
|
|
3438
3667
|
constructor() {
|
|
@@ -3456,41 +3685,63 @@ var files = (() => {
|
|
|
3456
3685
|
description: "Use long listing format",
|
|
3457
3686
|
required: false,
|
|
3458
3687
|
type: "boolean"
|
|
3688
|
+
},
|
|
3689
|
+
{
|
|
3690
|
+
name: "human-readable",
|
|
3691
|
+
aliases: ["h"],
|
|
3692
|
+
description: "With -l, print sizes like 1.5K and 2M",
|
|
3693
|
+
required: false,
|
|
3694
|
+
type: "boolean"
|
|
3459
3695
|
}
|
|
3460
3696
|
];
|
|
3697
|
+
this.humanReadable = false;
|
|
3461
3698
|
}
|
|
3462
3699
|
async processCommand(command, context) {
|
|
3463
3700
|
const fs = context.services.getRequired(
|
|
3464
3701
|
IFileSystemService_TOKEN
|
|
3465
3702
|
);
|
|
3466
|
-
const
|
|
3703
|
+
const paths = splitArgs(command.value || "");
|
|
3467
3704
|
const showAll = command.args["all"] || command.args["a"];
|
|
3468
3705
|
const longFormat = command.args["long"] || command.args["l"];
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3706
|
+
this.humanReadable = !!(command.args["human-readable"] || command.args["h"]);
|
|
3707
|
+
const targets = paths.length > 0 ? paths : [fs.getCurrentDirectory()];
|
|
3708
|
+
const piped = [];
|
|
3709
|
+
targets.forEach((targetPath, index) => {
|
|
3710
|
+
try {
|
|
3711
|
+
const node = fs.getNode(targetPath);
|
|
3712
|
+
const entries = node && node.type !== "directory" ? [{ ...node, name: targetPath }] : fs.listDirectory(targetPath);
|
|
3713
|
+
const filtered = showAll ? entries : entries.filter((e) => !e.name.startsWith("."));
|
|
3714
|
+
if (targets.length > 1) {
|
|
3715
|
+
if (index > 0) context.writer.writeln();
|
|
3716
|
+
context.writer.writeln(`${targetPath}:`);
|
|
3478
3717
|
}
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3718
|
+
if (filtered.length === 0) {
|
|
3719
|
+
return;
|
|
3720
|
+
}
|
|
3721
|
+
filtered.sort((a, b) => {
|
|
3722
|
+
if (a.type !== b.type) {
|
|
3723
|
+
return a.type === "directory" ? -1 : 1;
|
|
3724
|
+
}
|
|
3725
|
+
return a.name.localeCompare(b.name);
|
|
3726
|
+
});
|
|
3727
|
+
if (longFormat) {
|
|
3728
|
+
this.writeLongFormat(filtered, context);
|
|
3729
|
+
} else {
|
|
3730
|
+
this.writeShortFormat(filtered, context);
|
|
3731
|
+
piped.push(...filtered.map((e) => e.name));
|
|
3732
|
+
}
|
|
3733
|
+
} catch (e) {
|
|
3734
|
+
context.writer.writeError(e.message);
|
|
3485
3735
|
}
|
|
3486
|
-
}
|
|
3487
|
-
|
|
3736
|
+
});
|
|
3737
|
+
if (!longFormat && piped.length > 0) {
|
|
3738
|
+
context.process.output(piped.join("\n"));
|
|
3488
3739
|
}
|
|
3489
3740
|
}
|
|
3490
3741
|
writeDescription(context) {
|
|
3491
3742
|
context.writer.writeln(this.description);
|
|
3492
3743
|
context.writer.writeln();
|
|
3493
|
-
context.writer.writeln("Usage: ls [path] [
|
|
3744
|
+
context.writer.writeln("Usage: ls [path...] [-a|--all] [-l|--long] [-h|--human-readable]");
|
|
3494
3745
|
}
|
|
3495
3746
|
writeLongFormat(entries, context) {
|
|
3496
3747
|
const { writer } = context;
|
|
@@ -3499,7 +3750,7 @@ var files = (() => {
|
|
|
3499
3750
|
const perms = entry.permissions || (entry.type === "directory" ? "rwxr-xr-x" : "rw-r--r--");
|
|
3500
3751
|
const owner = entry.ownership?.uid || "-";
|
|
3501
3752
|
const group = entry.ownership?.gid || "-";
|
|
3502
|
-
const size = entry.type
|
|
3753
|
+
const size = entry.type !== "file" ? "-" : this.humanReadable ? this.formatSize(entry.size) : entry.size.toString();
|
|
3503
3754
|
const date = new Date(entry.modifiedAt);
|
|
3504
3755
|
const dateStr = date.toLocaleDateString("en-US", {
|
|
3505
3756
|
month: "short",
|
|
@@ -3513,6 +3764,17 @@ var files = (() => {
|
|
|
3513
3764
|
);
|
|
3514
3765
|
}
|
|
3515
3766
|
}
|
|
3767
|
+
formatSize(bytes) {
|
|
3768
|
+
const units = ["K", "M", "G", "T"];
|
|
3769
|
+
let size = bytes;
|
|
3770
|
+
let unit = "";
|
|
3771
|
+
for (const next of units) {
|
|
3772
|
+
if (size < 1024) break;
|
|
3773
|
+
size /= 1024;
|
|
3774
|
+
unit = next;
|
|
3775
|
+
}
|
|
3776
|
+
return unit ? `${size < 10 ? size.toFixed(1) : Math.round(size)}${unit}` : String(bytes);
|
|
3777
|
+
}
|
|
3516
3778
|
writeShortFormat(entries, context) {
|
|
3517
3779
|
const { writer } = context;
|
|
3518
3780
|
const names = entries.map(
|
|
@@ -3532,11 +3794,30 @@ var files = (() => {
|
|
|
3532
3794
|
this.acceptsRawInput = true;
|
|
3533
3795
|
this.metadata = { icon: "\u{1F4C1}", module: "file management" };
|
|
3534
3796
|
}
|
|
3797
|
+
writeDescription(context) {
|
|
3798
|
+
const t = context.translator;
|
|
3799
|
+
writeWrapped(
|
|
3800
|
+
context,
|
|
3801
|
+
t.t("cli.cd.help.change_current_directory_without", "Change the current directory. Without a path it goes to your home directory. Paths can be absolute (/...), relative to where you are, or start with ~ for home.")
|
|
3802
|
+
);
|
|
3803
|
+
context.writer.writeln();
|
|
3804
|
+
writeUsage(context, [
|
|
3805
|
+
["cd", t.t("cli.cd.help.go_home_directory", "Go to your home directory")],
|
|
3806
|
+
["cd <dir>", t.t("cli.cd.help.go_directory", "Go into a directory")],
|
|
3807
|
+
["cd ..", t.t("cli.cd.help.go_up_one_level", "Go up one level")]
|
|
3808
|
+
]);
|
|
3809
|
+
context.writer.writeln();
|
|
3810
|
+
writeExamples(context, [
|
|
3811
|
+
["cd ~/docs", t.t("cli.cd.help.go_docs_home", "Go to docs in your home")],
|
|
3812
|
+
["cd ../projects", t.t("cli.cd.help.go_sibling_directory", "Go to a sibling directory")],
|
|
3813
|
+
["cd /", t.t("cli.cd.help.go_root", "Go to the root")]
|
|
3814
|
+
]);
|
|
3815
|
+
}
|
|
3535
3816
|
async processCommand(command, context) {
|
|
3536
3817
|
const fs = context.services.getRequired(
|
|
3537
3818
|
IFileSystemService_TOKEN
|
|
3538
3819
|
);
|
|
3539
|
-
const target = command.value || "~";
|
|
3820
|
+
const target = splitArgs(command.value || "").join(" ") || "~";
|
|
3540
3821
|
try {
|
|
3541
3822
|
fs.setCurrentDirectory(target);
|
|
3542
3823
|
await fs.persist();
|
|
@@ -3555,6 +3836,22 @@ var files = (() => {
|
|
|
3555
3836
|
this.version = LIBRARY_VERSION;
|
|
3556
3837
|
this.metadata = { icon: "\u{1F4C2}", module: "file management" };
|
|
3557
3838
|
}
|
|
3839
|
+
writeDescription(context) {
|
|
3840
|
+
const t = context.translator;
|
|
3841
|
+
writeWrapped(
|
|
3842
|
+
context,
|
|
3843
|
+
t.t("cli.pwd.help.print_full_path_directory", "Print the full path of the directory you are in. Relative paths in other commands start from here.")
|
|
3844
|
+
);
|
|
3845
|
+
context.writer.writeln();
|
|
3846
|
+
writeUsage(context, [
|
|
3847
|
+
["pwd", t.t("cli.pwd.help.show_current_directory", "Show the current directory")]
|
|
3848
|
+
]);
|
|
3849
|
+
context.writer.writeln();
|
|
3850
|
+
writeExamples(context, [
|
|
3851
|
+
["pwd", t.t("cli.pwd.help.example_home_user", "For example /home/user")],
|
|
3852
|
+
["cd ~/docs; pwd", t.t("cli.pwd.help.prints_home_user_docs", "Prints /home/user/docs")]
|
|
3853
|
+
]);
|
|
3854
|
+
}
|
|
3558
3855
|
async processCommand(command, context) {
|
|
3559
3856
|
const fs = context.services.getRequired(
|
|
3560
3857
|
IFileSystemService_TOKEN
|
|
@@ -3583,22 +3880,44 @@ var files = (() => {
|
|
|
3583
3880
|
}
|
|
3584
3881
|
];
|
|
3585
3882
|
}
|
|
3883
|
+
writeDescription(context) {
|
|
3884
|
+
const t = context.translator;
|
|
3885
|
+
writeWrapped(
|
|
3886
|
+
context,
|
|
3887
|
+
t.t("cli.mkdir.help.create_new_directory_p", "Create a new directory. With -p, any missing parent directories are created too.")
|
|
3888
|
+
);
|
|
3889
|
+
context.writer.writeln();
|
|
3890
|
+
writeUsage(context, [
|
|
3891
|
+
["mkdir <dir...>", t.t("cli.mkdir.help.create_one_more_directories", "Create one or more directories")],
|
|
3892
|
+
["mkdir -p <path>", t.t("cli.mkdir.help.create_directory_missing_parents", "Create a directory and its missing parents")]
|
|
3893
|
+
]);
|
|
3894
|
+
context.writer.writeln();
|
|
3895
|
+
writeExamples(context, [
|
|
3896
|
+
["mkdir projects", t.t("cli.mkdir.help.create_projects_current_directory", "Create projects in the current directory")],
|
|
3897
|
+
["mkdir -p ~/docs/2026/notes", t.t("cli.mkdir.help.create_whole_path_once", "Create the whole path at once")]
|
|
3898
|
+
]);
|
|
3899
|
+
}
|
|
3586
3900
|
async processCommand(command, context) {
|
|
3587
3901
|
const fs = context.services.getRequired(
|
|
3588
3902
|
IFileSystemService_TOKEN
|
|
3589
3903
|
);
|
|
3590
|
-
const
|
|
3904
|
+
const paths = splitArgs(command.value || "");
|
|
3591
3905
|
const recursive = command.args["parents"] || command.args["p"];
|
|
3592
|
-
if (
|
|
3906
|
+
if (paths.length === 0) {
|
|
3593
3907
|
context.writer.writeError("mkdir: missing operand");
|
|
3594
3908
|
return;
|
|
3595
3909
|
}
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3910
|
+
let changed = false;
|
|
3911
|
+
for (const path of paths) {
|
|
3912
|
+
try {
|
|
3913
|
+
if (recursive && fs.isDirectory(path)) continue;
|
|
3914
|
+
fs.createDirectory(path, recursive);
|
|
3915
|
+
changed = true;
|
|
3916
|
+
} catch (e) {
|
|
3917
|
+
context.writer.writeError(e.message);
|
|
3918
|
+
}
|
|
3601
3919
|
}
|
|
3920
|
+
if (changed) await fs.persist();
|
|
3602
3921
|
}
|
|
3603
3922
|
};
|
|
3604
3923
|
|
|
@@ -3613,38 +3932,58 @@ var files = (() => {
|
|
|
3613
3932
|
this.valueRequired = true;
|
|
3614
3933
|
this.metadata = { icon: "\u{1F5D1}", module: "file management" };
|
|
3615
3934
|
}
|
|
3935
|
+
writeDescription(context) {
|
|
3936
|
+
const t = context.translator;
|
|
3937
|
+
writeWrapped(
|
|
3938
|
+
context,
|
|
3939
|
+
t.t("cli.rmdir.help.remove_empty_directory_refuses", "Remove an empty directory. It refuses to remove a directory that still contains files; use rm -r for that.")
|
|
3940
|
+
);
|
|
3941
|
+
context.writer.writeln();
|
|
3942
|
+
writeUsage(context, [
|
|
3943
|
+
["rmdir <dir...>", t.t("cli.rmdir.help.remove_empty_directories", "Remove empty directories")]
|
|
3944
|
+
]);
|
|
3945
|
+
context.writer.writeln();
|
|
3946
|
+
writeExamples(context, [
|
|
3947
|
+
["rmdir empty-folder", t.t("cli.rmdir.help.remove_directory_current_one", "Remove a directory in the current one")],
|
|
3948
|
+
["rmdir ~/docs/old", t.t("cli.rmdir.help.remove_full_path", "Remove by full path")]
|
|
3949
|
+
]);
|
|
3950
|
+
}
|
|
3616
3951
|
async processCommand(command, context) {
|
|
3617
3952
|
const fs = context.services.getRequired(
|
|
3618
3953
|
IFileSystemService_TOKEN
|
|
3619
3954
|
);
|
|
3620
|
-
const
|
|
3621
|
-
if (
|
|
3955
|
+
const paths = splitArgs(command.value || "");
|
|
3956
|
+
if (paths.length === 0) {
|
|
3622
3957
|
context.writer.writeError("rmdir: missing operand");
|
|
3623
3958
|
return;
|
|
3624
3959
|
}
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3960
|
+
let changed = false;
|
|
3961
|
+
for (const path of paths) {
|
|
3962
|
+
try {
|
|
3963
|
+
const node = fs.getNode(path);
|
|
3964
|
+
if (!node) {
|
|
3965
|
+
context.writer.writeError(
|
|
3966
|
+
`rmdir: ${path}: No such file or directory`
|
|
3967
|
+
);
|
|
3968
|
+
continue;
|
|
3969
|
+
}
|
|
3970
|
+
if (node.type !== "directory") {
|
|
3971
|
+
context.writer.writeError(`rmdir: ${path}: Not a directory`);
|
|
3972
|
+
continue;
|
|
3973
|
+
}
|
|
3974
|
+
if (node.children && node.children.length > 0) {
|
|
3975
|
+
context.writer.writeError(
|
|
3976
|
+
`rmdir: ${path}: Directory not empty`
|
|
3977
|
+
);
|
|
3978
|
+
continue;
|
|
3979
|
+
}
|
|
3980
|
+
fs.remove(path, true);
|
|
3981
|
+
changed = true;
|
|
3982
|
+
} catch (e) {
|
|
3983
|
+
context.writer.writeError(e.message);
|
|
3642
3984
|
}
|
|
3643
|
-
fs.remove(path);
|
|
3644
|
-
await fs.persist();
|
|
3645
|
-
} catch (e) {
|
|
3646
|
-
context.writer.writeError(e.message);
|
|
3647
3985
|
}
|
|
3986
|
+
if (changed) await fs.persist();
|
|
3648
3987
|
}
|
|
3649
3988
|
};
|
|
3650
3989
|
|
|
@@ -3659,24 +3998,55 @@ var files = (() => {
|
|
|
3659
3998
|
this.valueRequired = true;
|
|
3660
3999
|
this.metadata = { icon: "\u{1F4C4}", module: "file management" };
|
|
3661
4000
|
}
|
|
4001
|
+
writeDescription(context) {
|
|
4002
|
+
const t = context.translator;
|
|
4003
|
+
writeWrapped(
|
|
4004
|
+
context,
|
|
4005
|
+
t.t("cli.touch.help.create_empty_file_update", "Create an empty file, or update the modified time of a file that already exists. The parent directory must already exist.")
|
|
4006
|
+
);
|
|
4007
|
+
context.writer.writeln();
|
|
4008
|
+
writeUsage(context, [
|
|
4009
|
+
["touch <file...>", t.t("cli.touch.help.create_files_refresh_their", "Create the files, or refresh their timestamps")]
|
|
4010
|
+
]);
|
|
4011
|
+
context.writer.writeln();
|
|
4012
|
+
writeExamples(context, [
|
|
4013
|
+
["touch notes.txt", t.t("cli.touch.help.create_empty_notes_txt", "Create an empty notes.txt")],
|
|
4014
|
+
["touch ~/docs/todo.md", t.t("cli.touch.help.create_file_docs", "Create a file in ~/docs")]
|
|
4015
|
+
]);
|
|
4016
|
+
}
|
|
3662
4017
|
async processCommand(command, context) {
|
|
3663
4018
|
const fs = context.services.getRequired(
|
|
3664
4019
|
IFileSystemService_TOKEN
|
|
3665
4020
|
);
|
|
3666
|
-
const
|
|
3667
|
-
if (
|
|
4021
|
+
const paths = splitArgs(command.value || "");
|
|
4022
|
+
if (paths.length === 0) {
|
|
3668
4023
|
context.writer.writeError("touch: missing file operand");
|
|
3669
4024
|
return;
|
|
3670
4025
|
}
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
4026
|
+
let changed = false;
|
|
4027
|
+
for (const path of paths) {
|
|
4028
|
+
try {
|
|
4029
|
+
fs.createFile(path);
|
|
4030
|
+
changed = true;
|
|
4031
|
+
} catch (e) {
|
|
4032
|
+
context.writer.writeError(e.message);
|
|
4033
|
+
}
|
|
3676
4034
|
}
|
|
4035
|
+
if (changed) await fs.persist();
|
|
3677
4036
|
}
|
|
3678
4037
|
};
|
|
3679
4038
|
|
|
4039
|
+
// src/lib/utils/lines.ts
|
|
4040
|
+
function splitLines(content) {
|
|
4041
|
+
if (content === "") return [];
|
|
4042
|
+
const lines = content.split("\n");
|
|
4043
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4044
|
+
return lines;
|
|
4045
|
+
}
|
|
4046
|
+
function pipedText(data) {
|
|
4047
|
+
return typeof data === "string" ? data : JSON.stringify(data);
|
|
4048
|
+
}
|
|
4049
|
+
|
|
3680
4050
|
// src/lib/processors/cli-cat-command-processor.ts
|
|
3681
4051
|
var CliCatCommandProcessor = class {
|
|
3682
4052
|
constructor() {
|
|
@@ -3688,22 +4058,58 @@ var files = (() => {
|
|
|
3688
4058
|
this.valueRequired = true;
|
|
3689
4059
|
this.metadata = { icon: "\u{1F4D6}", module: "file management" };
|
|
3690
4060
|
}
|
|
4061
|
+
writeDescription(context) {
|
|
4062
|
+
const t = context.translator;
|
|
4063
|
+
writeWrapped(
|
|
4064
|
+
context,
|
|
4065
|
+
t.t("cli.cat.help.print_contents_one_more", "Print the contents of one or more files, joined in order, or of piped input. Pipe the output into other commands to search, sort or count it.")
|
|
4066
|
+
);
|
|
4067
|
+
context.writer.writeln();
|
|
4068
|
+
writeUsage(context, [
|
|
4069
|
+
["cat <file...>", t.t("cli.cat.help.print_files_one_after", "Print files one after another")],
|
|
4070
|
+
["cat <file> | <command>", t.t("cli.cat.help.send_file_another_command", "Send a file to another command")]
|
|
4071
|
+
]);
|
|
4072
|
+
context.writer.writeln();
|
|
4073
|
+
writeExamples(context, [
|
|
4074
|
+
["cat notes.txt", t.t("cli.cat.help.show_whole_file", "Show the whole file")],
|
|
4075
|
+
["cat app.log | grep error", t.t("cli.cat.help.show_only_lines_error", "Show only lines with error")],
|
|
4076
|
+
["cat names.txt | sort", t.t("cli.cat.help.print_lines_sorted", "Print the lines sorted")]
|
|
4077
|
+
]);
|
|
4078
|
+
}
|
|
3691
4079
|
async processCommand(command, context) {
|
|
3692
4080
|
const fs = context.services.getRequired(
|
|
3693
4081
|
IFileSystemService_TOKEN
|
|
3694
4082
|
);
|
|
3695
|
-
const
|
|
3696
|
-
if (
|
|
4083
|
+
const paths = splitArgs(command.value || "");
|
|
4084
|
+
if (paths.length === 0) {
|
|
4085
|
+
if (command.data != null) {
|
|
4086
|
+
context.writer.writeln(pipedText(command.data));
|
|
4087
|
+
return;
|
|
4088
|
+
}
|
|
3697
4089
|
context.writer.writeError("cat: missing file operand");
|
|
3698
4090
|
return;
|
|
3699
4091
|
}
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
4092
|
+
let output = "";
|
|
4093
|
+
for (const path of paths) {
|
|
4094
|
+
try {
|
|
4095
|
+
if (fs.isDirectory(path)) {
|
|
4096
|
+
context.writer.writeError(`cat: ${path}: Is a directory`);
|
|
4097
|
+
continue;
|
|
4098
|
+
}
|
|
4099
|
+
const content = fs.readFile(path);
|
|
4100
|
+
if (content === null) {
|
|
4101
|
+
context.writer.writeError(
|
|
4102
|
+
`cat: ${path}: No such file or directory`
|
|
4103
|
+
);
|
|
4104
|
+
continue;
|
|
4105
|
+
}
|
|
4106
|
+
output += content;
|
|
4107
|
+
} catch (e) {
|
|
4108
|
+
context.writer.writeError(e.message);
|
|
3704
4109
|
}
|
|
3705
|
-
}
|
|
3706
|
-
|
|
4110
|
+
}
|
|
4111
|
+
if (output !== "") {
|
|
4112
|
+
context.writer.writeln(output.replace(/\n$/, ""));
|
|
3707
4113
|
}
|
|
3708
4114
|
}
|
|
3709
4115
|
};
|
|
@@ -3719,60 +4125,33 @@ var files = (() => {
|
|
|
3719
4125
|
this.extendsProcessor = true;
|
|
3720
4126
|
this.metadata = { icon: "\u{1F4AC}", module: "file management" };
|
|
3721
4127
|
}
|
|
4128
|
+
writeDescription(context) {
|
|
4129
|
+
const t = context.translator;
|
|
4130
|
+
writeWrapped(
|
|
4131
|
+
context,
|
|
4132
|
+
t.t("cli.echo.help.print_text_terminal_add", "Print text to the terminal. Add > file to save it to a file (replacing it) or >> file to add it to the end.")
|
|
4133
|
+
);
|
|
4134
|
+
context.writer.writeln();
|
|
4135
|
+
writeUsage(context, [
|
|
4136
|
+
["echo <text>", t.t("cli.echo.help.print_text", "Print text")],
|
|
4137
|
+
["echo <text> > <file>", t.t("cli.echo.help.write_text_file", "Write text to a file")],
|
|
4138
|
+
["echo <text> >> <file>", t.t("cli.echo.help.append_text_file", "Append text to a file")]
|
|
4139
|
+
]);
|
|
4140
|
+
context.writer.writeln();
|
|
4141
|
+
writeExamples(context, [
|
|
4142
|
+
["echo Hello world", t.t("cli.echo.help.print_greeting", "Print a greeting")],
|
|
4143
|
+
["echo first line > notes.txt", t.t("cli.echo.help.create_replace_notes_txt", "Create or replace notes.txt")],
|
|
4144
|
+
["echo another line >> notes.txt", t.t("cli.echo.help.add_line", "Add a line to it")]
|
|
4145
|
+
]);
|
|
4146
|
+
}
|
|
3722
4147
|
async processCommand(command, context) {
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
if (!hasRedirection) {
|
|
3726
|
-
if (this.originalProcessor) {
|
|
3727
|
-
await this.originalProcessor.processCommand(command, context);
|
|
3728
|
-
} else {
|
|
3729
|
-
context.writer.writeln(afterEcho);
|
|
3730
|
-
}
|
|
4148
|
+
if (this.originalProcessor) {
|
|
4149
|
+
await this.originalProcessor.processCommand(command, context);
|
|
3731
4150
|
return;
|
|
3732
4151
|
}
|
|
3733
|
-
const
|
|
3734
|
-
|
|
3735
|
-
);
|
|
3736
|
-
let text;
|
|
3737
|
-
let filePath;
|
|
3738
|
-
let append = false;
|
|
3739
|
-
const appendMatch = afterEcho.match(/^(.*?)\s*>>\s*(.+)$/);
|
|
3740
|
-
const overwriteMatch = afterEcho.match(/^(.*?)\s*>\s*(.+)$/);
|
|
3741
|
-
if (appendMatch) {
|
|
3742
|
-
text = appendMatch[1].trim();
|
|
3743
|
-
filePath = appendMatch[2].trim();
|
|
3744
|
-
append = true;
|
|
3745
|
-
} else {
|
|
3746
|
-
text = overwriteMatch[1].trim();
|
|
3747
|
-
filePath = overwriteMatch[2].trim();
|
|
3748
|
-
}
|
|
3749
|
-
if (text.startsWith('"') && text.endsWith('"') || text.startsWith("'") && text.endsWith("'")) {
|
|
3750
|
-
text = text.slice(1, -1);
|
|
3751
|
-
}
|
|
3752
|
-
text = text.replace(/\\([\\nrtv0])/g, (_, ch) => {
|
|
3753
|
-
switch (ch) {
|
|
3754
|
-
case "n":
|
|
3755
|
-
return "\n";
|
|
3756
|
-
case "t":
|
|
3757
|
-
return " ";
|
|
3758
|
-
case "r":
|
|
3759
|
-
return "\r";
|
|
3760
|
-
case "v":
|
|
3761
|
-
return "\v";
|
|
3762
|
-
case "0":
|
|
3763
|
-
return "\0";
|
|
3764
|
-
case "\\":
|
|
3765
|
-
return "\\";
|
|
3766
|
-
default:
|
|
3767
|
-
return ch;
|
|
3768
|
-
}
|
|
3769
|
-
});
|
|
3770
|
-
try {
|
|
3771
|
-
fs.writeFile(filePath, text + "\n", append);
|
|
3772
|
-
await fs.persist();
|
|
3773
|
-
} catch (e) {
|
|
3774
|
-
context.writer.writeError(e.message);
|
|
3775
|
-
}
|
|
4152
|
+
const text = joinShellWords(command.value || "");
|
|
4153
|
+
context.writer.writeln(text);
|
|
4154
|
+
context.process.output(text);
|
|
3776
4155
|
}
|
|
3777
4156
|
};
|
|
3778
4157
|
|
|
@@ -3803,35 +4182,58 @@ var files = (() => {
|
|
|
3803
4182
|
}
|
|
3804
4183
|
];
|
|
3805
4184
|
}
|
|
4185
|
+
writeDescription(context) {
|
|
4186
|
+
const t = context.translator;
|
|
4187
|
+
writeWrapped(
|
|
4188
|
+
context,
|
|
4189
|
+
t.t("cli.rm.help.delete_file_directories_only", "Delete a file. Directories are only removed with -r, which deletes everything inside them. Deleted files cannot be recovered.")
|
|
4190
|
+
);
|
|
4191
|
+
context.writer.writeln();
|
|
4192
|
+
writeUsage(context, [
|
|
4193
|
+
["rm <file...>", t.t("cli.rm.help.delete_one_more_files", "Delete one or more files")],
|
|
4194
|
+
["rm -r <dir>", t.t("cli.rm.help.delete_directory_contents", "Delete a directory and its contents")],
|
|
4195
|
+
["rm -f <file>", t.t("cli.rm.help.delete_without_error_if", "Delete without an error if it is missing")]
|
|
4196
|
+
]);
|
|
4197
|
+
context.writer.writeln();
|
|
4198
|
+
writeExamples(context, [
|
|
4199
|
+
["rm notes.bak", t.t("cli.rm.help.delete_one_file", "Delete one file")],
|
|
4200
|
+
["rm -r old-project", t.t("cli.rm.help.delete_whole_directory", "Delete a whole directory")],
|
|
4201
|
+
["rm -f maybe.txt", t.t("cli.rm.help.quiet_if_file_does", "Quiet if the file does not exist")]
|
|
4202
|
+
]);
|
|
4203
|
+
}
|
|
3806
4204
|
async processCommand(command, context) {
|
|
3807
4205
|
const fs = context.services.getRequired(
|
|
3808
4206
|
IFileSystemService_TOKEN
|
|
3809
4207
|
);
|
|
3810
|
-
const
|
|
4208
|
+
const paths = splitArgs(command.value || "");
|
|
3811
4209
|
const recursive = command.args["recursive"] || command.args["r"] || command.args["R"];
|
|
3812
4210
|
const force = command.args["force"] || command.args["f"];
|
|
3813
|
-
if (
|
|
3814
|
-
context.writer.writeError("rm: missing operand");
|
|
4211
|
+
if (paths.length === 0) {
|
|
4212
|
+
if (!force) context.writer.writeError("rm: missing operand");
|
|
3815
4213
|
return;
|
|
3816
4214
|
}
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
4215
|
+
let changed = false;
|
|
4216
|
+
for (const path of paths) {
|
|
4217
|
+
try {
|
|
4218
|
+
if (!fs.exists(path)) {
|
|
4219
|
+
if (!force) {
|
|
4220
|
+
context.writer.writeError(
|
|
4221
|
+
`rm: ${path}: No such file or directory`
|
|
4222
|
+
);
|
|
4223
|
+
}
|
|
4224
|
+
continue;
|
|
3823
4225
|
}
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
4226
|
+
if (fs.isDirectory(path) && !recursive) {
|
|
4227
|
+
context.writer.writeError(`rm: ${path}: Is a directory`);
|
|
4228
|
+
continue;
|
|
4229
|
+
}
|
|
4230
|
+
fs.remove(path, recursive);
|
|
4231
|
+
changed = true;
|
|
4232
|
+
} catch (e) {
|
|
4233
|
+
context.writer.writeError(e.message);
|
|
3829
4234
|
}
|
|
3830
|
-
fs.remove(path, recursive);
|
|
3831
|
-
await fs.persist();
|
|
3832
|
-
} catch (e) {
|
|
3833
|
-
context.writer.writeError(e.message);
|
|
3834
4235
|
}
|
|
4236
|
+
if (changed) await fs.persist();
|
|
3835
4237
|
}
|
|
3836
4238
|
};
|
|
3837
4239
|
|
|
@@ -3851,9 +4253,35 @@ var files = (() => {
|
|
|
3851
4253
|
description: "Copy directories recursively",
|
|
3852
4254
|
required: false,
|
|
3853
4255
|
type: "boolean"
|
|
4256
|
+
},
|
|
4257
|
+
{
|
|
4258
|
+
name: "force",
|
|
4259
|
+
aliases: ["f"],
|
|
4260
|
+
description: "Overwrite existing files (always done; accepted for -rf)",
|
|
4261
|
+
required: false,
|
|
4262
|
+
type: "boolean"
|
|
3854
4263
|
}
|
|
3855
4264
|
];
|
|
3856
4265
|
}
|
|
4266
|
+
writeDescription(context) {
|
|
4267
|
+
const t = context.translator;
|
|
4268
|
+
writeWrapped(
|
|
4269
|
+
context,
|
|
4270
|
+
t.t("cli.cp.help.copy_file_new_path", "Copy a file to a new path, or into an existing directory. Copying a directory needs -r, which copies everything inside it. A file already at the destination is replaced.")
|
|
4271
|
+
);
|
|
4272
|
+
context.writer.writeln();
|
|
4273
|
+
writeUsage(context, [
|
|
4274
|
+
["cp <source> <dest>", t.t("cli.cp.help.copy_file_new_name", "Copy a file to a new name")],
|
|
4275
|
+
["cp <source...> <dir>", t.t("cli.cp.help.copy_files_directory", "Copy files into a directory")],
|
|
4276
|
+
["cp -r <dir> <dest>", t.t("cli.cp.help.copy_directory_contents", "Copy a directory and its contents")]
|
|
4277
|
+
]);
|
|
4278
|
+
context.writer.writeln();
|
|
4279
|
+
writeExamples(context, [
|
|
4280
|
+
["cp notes.txt notes.bak", t.t("cli.cp.help.make_backup_copy", "Make a backup copy")],
|
|
4281
|
+
["cp report.txt ~/docs", t.t("cli.cp.help.copy_docs", "Copy into ~/docs")],
|
|
4282
|
+
["cp -r project project-copy", t.t("cli.cp.help.duplicate_whole_directory", "Duplicate a whole directory")]
|
|
4283
|
+
]);
|
|
4284
|
+
}
|
|
3857
4285
|
async processCommand(command, context) {
|
|
3858
4286
|
const fs = context.services.getRequired(
|
|
3859
4287
|
IFileSystemService_TOKEN
|
|
@@ -3867,18 +4295,26 @@ var files = (() => {
|
|
|
3867
4295
|
);
|
|
3868
4296
|
return;
|
|
3869
4297
|
}
|
|
3870
|
-
const
|
|
3871
|
-
const
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
}
|
|
3876
|
-
|
|
4298
|
+
const dest = parts[parts.length - 1];
|
|
4299
|
+
const sources = parts.slice(0, -1);
|
|
4300
|
+
if (sources.length > 1 && !fs.isDirectory(dest)) {
|
|
4301
|
+
context.writer.writeError(`cp: target '${dest}' is not a directory`);
|
|
4302
|
+
return;
|
|
4303
|
+
}
|
|
4304
|
+
let changed = false;
|
|
4305
|
+
for (const src of sources) {
|
|
4306
|
+
try {
|
|
4307
|
+
fs.copy(src, dest, recursive);
|
|
4308
|
+
changed = true;
|
|
4309
|
+
} catch (e) {
|
|
4310
|
+
context.writer.writeError(e.message);
|
|
4311
|
+
}
|
|
3877
4312
|
}
|
|
4313
|
+
if (changed) await fs.persist();
|
|
3878
4314
|
}
|
|
3879
4315
|
parseArgs(command) {
|
|
3880
4316
|
const raw = command.value || "";
|
|
3881
|
-
return raw
|
|
4317
|
+
return splitArgs(raw).filter(Boolean);
|
|
3882
4318
|
}
|
|
3883
4319
|
};
|
|
3884
4320
|
|
|
@@ -3892,6 +4328,24 @@ var files = (() => {
|
|
|
3892
4328
|
this.acceptsRawInput = true;
|
|
3893
4329
|
this.metadata = { icon: "\u{1F4E6}", module: "file management" };
|
|
3894
4330
|
}
|
|
4331
|
+
writeDescription(context) {
|
|
4332
|
+
const t = context.translator;
|
|
4333
|
+
writeWrapped(
|
|
4334
|
+
context,
|
|
4335
|
+
t.t("cli.mv.help.move_rename_file_directory", "Move or rename a file or directory. If the destination is an existing directory, the source is moved into it; otherwise it is renamed. A file already at the destination is replaced.")
|
|
4336
|
+
);
|
|
4337
|
+
context.writer.writeln();
|
|
4338
|
+
writeUsage(context, [
|
|
4339
|
+
["mv <source> <dest>", t.t("cli.mv.help.rename_file_directory", "Rename a file or directory")],
|
|
4340
|
+
["mv <source...> <dir>", t.t("cli.mv.help.move_them_directory", "Move them into a directory")]
|
|
4341
|
+
]);
|
|
4342
|
+
context.writer.writeln();
|
|
4343
|
+
writeExamples(context, [
|
|
4344
|
+
["mv draft.txt final.txt", t.t("cli.mv.help.rename_file", "Rename a file")],
|
|
4345
|
+
["mv final.txt ~/docs", t.t("cli.mv.help.move_docs", "Move it into ~/docs")],
|
|
4346
|
+
["mv old-dir new-dir", t.t("cli.mv.help.rename_directory", "Rename a directory")]
|
|
4347
|
+
]);
|
|
4348
|
+
}
|
|
3895
4349
|
async processCommand(command, context) {
|
|
3896
4350
|
const fs = context.services.getRequired(
|
|
3897
4351
|
IFileSystemService_TOKEN
|
|
@@ -3902,18 +4356,26 @@ var files = (() => {
|
|
|
3902
4356
|
context.writer.writeln("Usage: mv <source> <destination>");
|
|
3903
4357
|
return;
|
|
3904
4358
|
}
|
|
3905
|
-
const
|
|
3906
|
-
const
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
}
|
|
3911
|
-
|
|
4359
|
+
const dest = parts[parts.length - 1];
|
|
4360
|
+
const sources = parts.slice(0, -1);
|
|
4361
|
+
if (sources.length > 1 && !fs.isDirectory(dest)) {
|
|
4362
|
+
context.writer.writeError(`mv: target '${dest}' is not a directory`);
|
|
4363
|
+
return;
|
|
4364
|
+
}
|
|
4365
|
+
let changed = false;
|
|
4366
|
+
for (const src of sources) {
|
|
4367
|
+
try {
|
|
4368
|
+
fs.move(src, dest);
|
|
4369
|
+
changed = true;
|
|
4370
|
+
} catch (e) {
|
|
4371
|
+
context.writer.writeError(e.message);
|
|
4372
|
+
}
|
|
3912
4373
|
}
|
|
4374
|
+
if (changed) await fs.persist();
|
|
3913
4375
|
}
|
|
3914
4376
|
parseArgs(command) {
|
|
3915
4377
|
const raw = command.value || "";
|
|
3916
|
-
return raw
|
|
4378
|
+
return splitArgs(raw).filter(Boolean);
|
|
3917
4379
|
}
|
|
3918
4380
|
};
|
|
3919
4381
|
|
|
@@ -3946,11 +4408,29 @@ var files = (() => {
|
|
|
3946
4408
|
}
|
|
3947
4409
|
];
|
|
3948
4410
|
}
|
|
4411
|
+
writeDescription(context) {
|
|
4412
|
+
const t = context.translator;
|
|
4413
|
+
writeWrapped(
|
|
4414
|
+
context,
|
|
4415
|
+
t.t("cli.tree.help.draw_directory_everything_below", "Draw a directory and everything below it as a tree, directories first, followed by a count of directories and files. Defaults to the current directory.")
|
|
4416
|
+
);
|
|
4417
|
+
context.writer.writeln();
|
|
4418
|
+
writeUsage(context, [
|
|
4419
|
+
["tree [dir]", t.t("cli.tree.help.show_whole_tree", "Show the whole tree")],
|
|
4420
|
+
["tree -L <n> [dir]", t.t("cli.tree.help.only_levels_deep", "Only <n> levels deep")]
|
|
4421
|
+
]);
|
|
4422
|
+
context.writer.writeln();
|
|
4423
|
+
writeExamples(context, [
|
|
4424
|
+
["tree", t.t("cli.tree.help.tree_current_directory", "Tree of the current directory")],
|
|
4425
|
+
["tree ~/docs", t.t("cli.tree.help.tree_docs", "Tree of ~/docs")],
|
|
4426
|
+
["tree -L 2", t.t("cli.tree.help.top_two_levels_only", "Top two levels only")]
|
|
4427
|
+
]);
|
|
4428
|
+
}
|
|
3949
4429
|
async processCommand(command, context) {
|
|
3950
4430
|
const fs = context.services.getRequired(
|
|
3951
4431
|
IFileSystemService_TOKEN
|
|
3952
4432
|
);
|
|
3953
|
-
const targetPath = command.value || fs.getCurrentDirectory();
|
|
4433
|
+
const targetPath = splitArgs(command.value || "").join(" ") || fs.getCurrentDirectory();
|
|
3954
4434
|
const maxDepth = command.args["depth"] ? parseInt(command.args["depth"]) : command.args["L"] ? parseInt(command.args["L"]) : Infinity;
|
|
3955
4435
|
try {
|
|
3956
4436
|
const node = fs.getNode(targetPath);
|
|
@@ -4047,21 +4527,40 @@ var files = (() => {
|
|
|
4047
4527
|
}
|
|
4048
4528
|
];
|
|
4049
4529
|
}
|
|
4530
|
+
writeDescription(context) {
|
|
4531
|
+
const t = context.translator;
|
|
4532
|
+
writeWrapped(
|
|
4533
|
+
context,
|
|
4534
|
+
t.t("cli.head.help.print_first_lines_file", "Print the first lines of a file, 10 by default. Works on piped input too. With several files, each one gets a ==> name <== header.")
|
|
4535
|
+
);
|
|
4536
|
+
context.writer.writeln();
|
|
4537
|
+
writeUsage(context, [
|
|
4538
|
+
["head <file>", t.t("cli.head.help.first_10_lines", "First 10 lines")],
|
|
4539
|
+
["head -n <count> <file>", t.t("cli.head.help.first_lines", "First <count> lines")],
|
|
4540
|
+
["<command> | head", t.t("cli.head.help.first_lines_piped_input", "First lines of piped input")]
|
|
4541
|
+
]);
|
|
4542
|
+
context.writer.writeln();
|
|
4543
|
+
writeExamples(context, [
|
|
4544
|
+
["head notes.txt", t.t("cli.head.help.show_start_file", "Show the start of a file")],
|
|
4545
|
+
["head -n 3 a.txt b.txt", t.t("cli.head.help.first_3_lines_each", "First 3 lines of each file")],
|
|
4546
|
+
["cat app.log | head -n 20", t.t("cli.head.help.first_20_lines_log", "First 20 lines of the log")]
|
|
4547
|
+
]);
|
|
4548
|
+
}
|
|
4050
4549
|
async processCommand(command, context) {
|
|
4051
4550
|
const fs = context.services.getRequired(
|
|
4052
4551
|
IFileSystemService_TOKEN
|
|
4053
4552
|
);
|
|
4054
|
-
const
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
);
|
|
4553
|
+
const countArg = command.args["lines"] ?? command.args["n"] ?? Object.keys(command.args).find((k) => /^\d+$/.test(k));
|
|
4554
|
+
const parsedCount = parseInt(String(countArg ?? "10"), 10);
|
|
4555
|
+
const count = isNaN(parsedCount) ? 10 : Math.abs(parsedCount);
|
|
4058
4556
|
const paths = this.parsePaths(command);
|
|
4059
4557
|
if (paths.length === 0) {
|
|
4060
4558
|
if (command.data != null) {
|
|
4061
|
-
const
|
|
4062
|
-
const lines = content.split("\n");
|
|
4559
|
+
const lines = splitLines(pipedText(command.data));
|
|
4063
4560
|
const selected = lines.slice(0, count);
|
|
4064
|
-
|
|
4561
|
+
if (selected.length > 0) {
|
|
4562
|
+
context.writer.writeln(selected.join("\n"));
|
|
4563
|
+
}
|
|
4065
4564
|
return;
|
|
4066
4565
|
}
|
|
4067
4566
|
context.writer.writeError("head: missing file operand");
|
|
@@ -4080,9 +4579,11 @@ var files = (() => {
|
|
|
4080
4579
|
if (i > 0) context.writer.writeln();
|
|
4081
4580
|
context.writer.writeln(`==> ${path} <==`);
|
|
4082
4581
|
}
|
|
4083
|
-
const lines = content
|
|
4582
|
+
const lines = splitLines(content);
|
|
4084
4583
|
const selected = lines.slice(0, count);
|
|
4085
|
-
|
|
4584
|
+
if (selected.length > 0) {
|
|
4585
|
+
context.writer.writeln(selected.join("\n"));
|
|
4586
|
+
}
|
|
4086
4587
|
} catch (e) {
|
|
4087
4588
|
context.writer.writeError(`head: ${e.message}`);
|
|
4088
4589
|
}
|
|
@@ -4090,7 +4591,7 @@ var files = (() => {
|
|
|
4090
4591
|
}
|
|
4091
4592
|
parsePaths(command) {
|
|
4092
4593
|
const raw = command.value || "";
|
|
4093
|
-
return raw
|
|
4594
|
+
return splitArgs(raw).filter(Boolean);
|
|
4094
4595
|
}
|
|
4095
4596
|
};
|
|
4096
4597
|
|
|
@@ -4114,21 +4615,40 @@ var files = (() => {
|
|
|
4114
4615
|
}
|
|
4115
4616
|
];
|
|
4116
4617
|
}
|
|
4618
|
+
writeDescription(context) {
|
|
4619
|
+
const t = context.translator;
|
|
4620
|
+
writeWrapped(
|
|
4621
|
+
context,
|
|
4622
|
+
t.t("cli.tail.help.print_last_lines_file", "Print the last lines of a file, 10 by default. Works on piped input too. With several files, each one gets a ==> name <== header.")
|
|
4623
|
+
);
|
|
4624
|
+
context.writer.writeln();
|
|
4625
|
+
writeUsage(context, [
|
|
4626
|
+
["tail <file>", t.t("cli.tail.help.last_10_lines", "Last 10 lines")],
|
|
4627
|
+
["tail -n <count> <file>", t.t("cli.tail.help.last_lines", "Last <count> lines")],
|
|
4628
|
+
["<command> | tail", t.t("cli.tail.help.last_lines_piped_input", "Last lines of piped input")]
|
|
4629
|
+
]);
|
|
4630
|
+
context.writer.writeln();
|
|
4631
|
+
writeExamples(context, [
|
|
4632
|
+
["tail app.log", t.t("cli.tail.help.show_end_log", "Show the end of a log")],
|
|
4633
|
+
["tail -n 5 notes.txt", t.t("cli.tail.help.last_5_lines", "Last 5 lines")],
|
|
4634
|
+
["cat app.log | tail -n 20", t.t("cli.tail.help.last_20_lines_log", "Last 20 lines of the log")]
|
|
4635
|
+
]);
|
|
4636
|
+
}
|
|
4117
4637
|
async processCommand(command, context) {
|
|
4118
4638
|
const fs = context.services.getRequired(
|
|
4119
4639
|
IFileSystemService_TOKEN
|
|
4120
4640
|
);
|
|
4121
|
-
const
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
);
|
|
4641
|
+
const countArg = command.args["lines"] ?? command.args["n"] ?? Object.keys(command.args).find((k) => /^\d+$/.test(k));
|
|
4642
|
+
const parsedCount = parseInt(String(countArg ?? "10"), 10);
|
|
4643
|
+
const count = isNaN(parsedCount) ? 10 : Math.abs(parsedCount);
|
|
4125
4644
|
const paths = this.parsePaths(command);
|
|
4126
4645
|
if (paths.length === 0) {
|
|
4127
4646
|
if (command.data != null) {
|
|
4128
|
-
const
|
|
4129
|
-
const
|
|
4130
|
-
|
|
4131
|
-
|
|
4647
|
+
const lines = splitLines(pipedText(command.data));
|
|
4648
|
+
const selected = count > 0 ? lines.slice(-count) : [];
|
|
4649
|
+
if (selected.length > 0) {
|
|
4650
|
+
context.writer.writeln(selected.join("\n"));
|
|
4651
|
+
}
|
|
4132
4652
|
return;
|
|
4133
4653
|
}
|
|
4134
4654
|
context.writer.writeError("tail: missing file operand");
|
|
@@ -4147,9 +4667,11 @@ var files = (() => {
|
|
|
4147
4667
|
if (i > 0) context.writer.writeln();
|
|
4148
4668
|
context.writer.writeln(`==> ${path} <==`);
|
|
4149
4669
|
}
|
|
4150
|
-
const lines = content
|
|
4151
|
-
const selected = lines.slice(-count);
|
|
4152
|
-
|
|
4670
|
+
const lines = splitLines(content);
|
|
4671
|
+
const selected = count > 0 ? lines.slice(-count) : [];
|
|
4672
|
+
if (selected.length > 0) {
|
|
4673
|
+
context.writer.writeln(selected.join("\n"));
|
|
4674
|
+
}
|
|
4153
4675
|
} catch (e) {
|
|
4154
4676
|
context.writer.writeError(`tail: ${e.message}`);
|
|
4155
4677
|
}
|
|
@@ -4157,7 +4679,7 @@ var files = (() => {
|
|
|
4157
4679
|
}
|
|
4158
4680
|
parsePaths(command) {
|
|
4159
4681
|
const raw = command.value || "";
|
|
4160
|
-
return raw
|
|
4682
|
+
return splitArgs(raw).filter(Boolean);
|
|
4161
4683
|
}
|
|
4162
4684
|
};
|
|
4163
4685
|
|
|
@@ -4195,6 +4717,28 @@ var files = (() => {
|
|
|
4195
4717
|
}
|
|
4196
4718
|
];
|
|
4197
4719
|
}
|
|
4720
|
+
writeDescription(context) {
|
|
4721
|
+
const t = context.translator;
|
|
4722
|
+
writeWrapped(
|
|
4723
|
+
context,
|
|
4724
|
+
t.t("cli.wc.help.count_lines_words_characters", "Count lines, words and characters in files or piped input. With several files, a total line is printed at the end.")
|
|
4725
|
+
);
|
|
4726
|
+
context.writer.writeln();
|
|
4727
|
+
writeUsage(context, [
|
|
4728
|
+
["wc <file...>", t.t("cli.wc.help.lines_words_characters", "Lines, words and characters")],
|
|
4729
|
+
["wc -l <file>", t.t("cli.wc.help.only_line_count", "Only the line count")],
|
|
4730
|
+
["<command> | wc", t.t("cli.wc.help.count_piped_input", "Count piped input")]
|
|
4731
|
+
]);
|
|
4732
|
+
context.writer.writeln();
|
|
4733
|
+
writeExamples(context, [
|
|
4734
|
+
["wc notes.txt", t.t("cli.wc.help.all_three_counts", "All three counts")],
|
|
4735
|
+
["wc -l a.txt b.txt", t.t("cli.wc.help.line_counts_total", "Line counts with a total")],
|
|
4736
|
+
[
|
|
4737
|
+
"cat app.log | grep error | wc -l",
|
|
4738
|
+
t.t("cli.wc.help.how_many_lines_mention", "How many lines mention error")
|
|
4739
|
+
]
|
|
4740
|
+
]);
|
|
4741
|
+
}
|
|
4198
4742
|
async processCommand(command, context) {
|
|
4199
4743
|
const fs = context.services.getRequired(
|
|
4200
4744
|
IFileSystemService_TOKEN
|
|
@@ -4206,10 +4750,9 @@ var files = (() => {
|
|
|
4206
4750
|
const paths = this.parsePaths(command);
|
|
4207
4751
|
if (paths.length === 0) {
|
|
4208
4752
|
if (command.data != null) {
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
const
|
|
4212
|
-
const charCount = content.length;
|
|
4753
|
+
let content = pipedText(command.data);
|
|
4754
|
+
if (content !== "" && !content.endsWith("\n")) content += "\n";
|
|
4755
|
+
const { lineCount, wordCount, charCount } = this.count(content);
|
|
4213
4756
|
const parts = [];
|
|
4214
4757
|
if (showAll || showLines) parts.push(String(lineCount).padStart(8));
|
|
4215
4758
|
if (showAll || showWords) parts.push(String(wordCount).padStart(8));
|
|
@@ -4230,9 +4773,7 @@ var files = (() => {
|
|
|
4230
4773
|
continue;
|
|
4231
4774
|
}
|
|
4232
4775
|
const content = fs.readFile(path) ?? "";
|
|
4233
|
-
const lineCount
|
|
4234
|
-
const wordCount = content.trim() === "" ? 0 : content.trim().split(/\s+/).length;
|
|
4235
|
-
const charCount = content.length;
|
|
4776
|
+
const { lineCount, wordCount, charCount } = this.count(content);
|
|
4236
4777
|
totalLines += lineCount;
|
|
4237
4778
|
totalWords += wordCount;
|
|
4238
4779
|
totalChars += charCount;
|
|
@@ -4255,9 +4796,17 @@ var files = (() => {
|
|
|
4255
4796
|
context.writer.writeln(parts.join(""));
|
|
4256
4797
|
}
|
|
4257
4798
|
}
|
|
4799
|
+
/** Counts like Unix wc: lines are newline characters. */
|
|
4800
|
+
count(content) {
|
|
4801
|
+
return {
|
|
4802
|
+
lineCount: (content.match(/\n/g) ?? []).length,
|
|
4803
|
+
wordCount: content.trim() === "" ? 0 : content.trim().split(/\s+/).length,
|
|
4804
|
+
charCount: content.length
|
|
4805
|
+
};
|
|
4806
|
+
}
|
|
4258
4807
|
parsePaths(command) {
|
|
4259
4808
|
const raw = command.value || "";
|
|
4260
|
-
return raw
|
|
4809
|
+
return splitArgs(raw).filter(Boolean);
|
|
4261
4810
|
}
|
|
4262
4811
|
};
|
|
4263
4812
|
|
|
@@ -4273,7 +4822,13 @@ var files = (() => {
|
|
|
4273
4822
|
this.parameters = [
|
|
4274
4823
|
{
|
|
4275
4824
|
name: "name",
|
|
4276
|
-
description: "Match filename pattern (glob: * and ? supported)",
|
|
4825
|
+
description: "Match filename pattern (glob: * and ? supported), case-sensitive",
|
|
4826
|
+
required: false,
|
|
4827
|
+
type: "string"
|
|
4828
|
+
},
|
|
4829
|
+
{
|
|
4830
|
+
name: "iname",
|
|
4831
|
+
description: "Like --name, but case-insensitive",
|
|
4277
4832
|
required: false,
|
|
4278
4833
|
type: "string"
|
|
4279
4834
|
},
|
|
@@ -4285,20 +4840,42 @@ var files = (() => {
|
|
|
4285
4840
|
},
|
|
4286
4841
|
{
|
|
4287
4842
|
name: "maxdepth",
|
|
4288
|
-
description: "Maximum
|
|
4843
|
+
description: "Maximum depth: 0 is only the start path, 1 its direct children",
|
|
4289
4844
|
required: false,
|
|
4290
4845
|
type: "number"
|
|
4291
4846
|
}
|
|
4292
4847
|
];
|
|
4293
4848
|
}
|
|
4849
|
+
writeDescription(context) {
|
|
4850
|
+
const t = context.translator;
|
|
4851
|
+
writeWrapped(
|
|
4852
|
+
context,
|
|
4853
|
+
t.t("cli.find.help.list_files_directories_under", "List files and directories under a path (the current directory by default), searching all subdirectories. The start path itself is listed first. Filter by name with a glob pattern (* and ?; --name is case-sensitive, --iname is not) or by type.")
|
|
4854
|
+
);
|
|
4855
|
+
context.writer.writeln();
|
|
4856
|
+
writeUsage(context, [
|
|
4857
|
+
["find [path]", t.t("cli.find.help.list_everything_under_path", "List everything under a path")],
|
|
4858
|
+
["find [path] --name <pattern>", t.t("cli.find.help.match_names_against_glob", "Match names against a glob")],
|
|
4859
|
+
["find [path] --iname <pattern>", t.t("cli.find.help.same_ignoring_case", "Same, ignoring case")],
|
|
4860
|
+
["find [path] --type f|d", t.t("cli.find.help.only_files_f_directories", "Only files (f) or directories (d)")]
|
|
4861
|
+
]);
|
|
4862
|
+
context.writer.writeln();
|
|
4863
|
+
writeExamples(context, [
|
|
4864
|
+
["find ~/docs", t.t("cli.find.help.list_everything_docs", "List everything in ~/docs")],
|
|
4865
|
+
['find . --name "*.txt"', t.t("cli.find.help.find_all_txt_files", "Find all .txt files")],
|
|
4866
|
+
["find . --type d --maxdepth 1", t.t("cli.find.help.directories_near_top", "Directories near the top")],
|
|
4867
|
+
['find . --name "*.tmp" | xargs rm', t.t("cli.find.help.delete_all_tmp_files", "Delete all .tmp files")]
|
|
4868
|
+
]);
|
|
4869
|
+
}
|
|
4294
4870
|
async processCommand(command, context) {
|
|
4295
4871
|
const fs = context.services.getRequired(
|
|
4296
4872
|
IFileSystemService_TOKEN
|
|
4297
4873
|
);
|
|
4298
4874
|
const searchPath = this.parseSearchPath(command) || fs.getCurrentDirectory();
|
|
4299
|
-
const namePattern = command.args["name"] || null;
|
|
4300
4875
|
const typeFilter = command.args["type"] || null;
|
|
4301
|
-
const
|
|
4876
|
+
const maxDepthArg = command.args["maxdepth"];
|
|
4877
|
+
const parsedDepth = parseInt(String(maxDepthArg ?? ""), 10);
|
|
4878
|
+
const maxDepth = maxDepthArg != null && maxDepthArg !== true && !isNaN(parsedDepth) ? parsedDepth : Infinity;
|
|
4302
4879
|
try {
|
|
4303
4880
|
const node = fs.getNode(searchPath);
|
|
4304
4881
|
if (!node) {
|
|
@@ -4307,25 +4884,25 @@ var files = (() => {
|
|
|
4307
4884
|
);
|
|
4308
4885
|
return;
|
|
4309
4886
|
}
|
|
4310
|
-
if (node.type !== "directory") {
|
|
4311
|
-
context.writer.writeError(
|
|
4312
|
-
`find: '${searchPath}': Not a directory`
|
|
4313
|
-
);
|
|
4314
|
-
return;
|
|
4315
|
-
}
|
|
4316
4887
|
const resolvedBase = fs.resolvePath(searchPath);
|
|
4317
|
-
const nameRegex =
|
|
4888
|
+
const nameRegex = this.nameRegex(command);
|
|
4318
4889
|
const results = [];
|
|
4319
4890
|
this.fs = fs;
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
resolvedBase
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4891
|
+
const baseName = resolvedBase.split("/").filter(Boolean).pop() ?? "/";
|
|
4892
|
+
if (this.matches(baseName, node.type, nameRegex, typeFilter)) {
|
|
4893
|
+
results.push(resolvedBase);
|
|
4894
|
+
}
|
|
4895
|
+
if (node.type === "directory" && maxDepth > 0) {
|
|
4896
|
+
this.walk(
|
|
4897
|
+
node,
|
|
4898
|
+
resolvedBase,
|
|
4899
|
+
1,
|
|
4900
|
+
maxDepth,
|
|
4901
|
+
nameRegex,
|
|
4902
|
+
typeFilter,
|
|
4903
|
+
results
|
|
4904
|
+
);
|
|
4905
|
+
}
|
|
4329
4906
|
for (const r of results) {
|
|
4330
4907
|
context.writer.writeln(r);
|
|
4331
4908
|
}
|
|
@@ -4333,32 +4910,41 @@ var files = (() => {
|
|
|
4333
4910
|
context.writer.writeError(`find: ${e.message}`);
|
|
4334
4911
|
}
|
|
4335
4912
|
}
|
|
4913
|
+
/** `--name` matches case-sensitively, `--iname` ignoring case. */
|
|
4914
|
+
nameRegex(command) {
|
|
4915
|
+
const name = command.args["name"];
|
|
4916
|
+
if (name != null && name !== true) {
|
|
4917
|
+
return this.globToRegex(String(name), false);
|
|
4918
|
+
}
|
|
4919
|
+
const iname = command.args["iname"];
|
|
4920
|
+
if (iname != null && iname !== true) {
|
|
4921
|
+
return this.globToRegex(String(iname), true);
|
|
4922
|
+
}
|
|
4923
|
+
return null;
|
|
4924
|
+
}
|
|
4925
|
+
matches(name, type, nameRegex, typeFilter) {
|
|
4926
|
+
if (nameRegex && !nameRegex.test(name)) return false;
|
|
4927
|
+
if (typeFilter === "f" && type !== "file") return false;
|
|
4928
|
+
if (typeFilter === "d" && type !== "directory") return false;
|
|
4929
|
+
return true;
|
|
4930
|
+
}
|
|
4336
4931
|
parseSearchPath(command) {
|
|
4337
4932
|
const raw = command.value || "";
|
|
4338
|
-
const tokens = raw
|
|
4933
|
+
const tokens = splitArgs(raw).filter(Boolean);
|
|
4339
4934
|
return tokens.length > 0 ? tokens[0] : null;
|
|
4340
4935
|
}
|
|
4341
|
-
globToRegex(pattern) {
|
|
4936
|
+
globToRegex(pattern, ignoreCase) {
|
|
4342
4937
|
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
4343
4938
|
const regexStr = escaped.replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
4344
|
-
return new RegExp(`^${regexStr}$`, "i");
|
|
4939
|
+
return new RegExp(`^${regexStr}$`, ignoreCase ? "i" : "");
|
|
4345
4940
|
}
|
|
4941
|
+
/** Lists the children of `node`, which are at `depth` (1 = direct children). */
|
|
4346
4942
|
walk(node, currentPath, depth, maxDepth, nameRegex, typeFilter, results) {
|
|
4347
4943
|
const children = this.fs ? readableChildren(this.fs, currentPath) : node.children;
|
|
4348
4944
|
if (!children) return;
|
|
4349
4945
|
for (const child of children) {
|
|
4350
4946
|
const childPath = currentPath === "/" ? `/${child.name}` : `${currentPath}/${child.name}`;
|
|
4351
|
-
|
|
4352
|
-
if (nameRegex && !nameRegex.test(child.name)) {
|
|
4353
|
-
matches = false;
|
|
4354
|
-
}
|
|
4355
|
-
if (typeFilter === "f" && child.type !== "file") {
|
|
4356
|
-
matches = false;
|
|
4357
|
-
}
|
|
4358
|
-
if (typeFilter === "d" && child.type !== "directory") {
|
|
4359
|
-
matches = false;
|
|
4360
|
-
}
|
|
4361
|
-
if (matches) {
|
|
4947
|
+
if (this.matches(child.name, child.type, nameRegex, typeFilter)) {
|
|
4362
4948
|
results.push(childPath);
|
|
4363
4949
|
}
|
|
4364
4950
|
if (child.type === "directory" && depth < maxDepth) {
|
|
@@ -4414,6 +5000,13 @@ var files = (() => {
|
|
|
4414
5000
|
required: false,
|
|
4415
5001
|
type: "boolean"
|
|
4416
5002
|
},
|
|
5003
|
+
{
|
|
5004
|
+
name: "quiet",
|
|
5005
|
+
aliases: ["q"],
|
|
5006
|
+
description: "Print nothing; only the exit status tells whether a line matched",
|
|
5007
|
+
required: false,
|
|
5008
|
+
type: "boolean"
|
|
5009
|
+
},
|
|
4417
5010
|
{
|
|
4418
5011
|
name: "files-with-matches",
|
|
4419
5012
|
aliases: ["l"],
|
|
@@ -4427,9 +5020,50 @@ var files = (() => {
|
|
|
4427
5020
|
description: "Select non-matching lines",
|
|
4428
5021
|
required: false,
|
|
4429
5022
|
type: "boolean"
|
|
5023
|
+
},
|
|
5024
|
+
{
|
|
5025
|
+
name: "word-regexp",
|
|
5026
|
+
aliases: ["w"],
|
|
5027
|
+
description: "Match only whole words",
|
|
5028
|
+
required: false,
|
|
5029
|
+
type: "boolean"
|
|
5030
|
+
},
|
|
5031
|
+
{
|
|
5032
|
+
name: "only-matching",
|
|
5033
|
+
aliases: ["o"],
|
|
5034
|
+
description: "Print only the matched parts, one per line",
|
|
5035
|
+
required: false,
|
|
5036
|
+
type: "boolean"
|
|
5037
|
+
},
|
|
5038
|
+
{
|
|
5039
|
+
name: "extended-regexp",
|
|
5040
|
+
aliases: ["E"],
|
|
5041
|
+
description: "Extended regular expressions (patterns always are)",
|
|
5042
|
+
required: false,
|
|
5043
|
+
type: "boolean"
|
|
4430
5044
|
}
|
|
4431
5045
|
];
|
|
4432
5046
|
}
|
|
5047
|
+
writeDescription(context) {
|
|
5048
|
+
const t = context.translator;
|
|
5049
|
+
writeWrapped(
|
|
5050
|
+
context,
|
|
5051
|
+
t.t("cli.grep.help.print_lines_match_pattern", "Print the lines that match a pattern. The pattern is a regular expression, matches are highlighted, and the input can be files, directories (with -r) or piped text.")
|
|
5052
|
+
);
|
|
5053
|
+
context.writer.writeln();
|
|
5054
|
+
writeUsage(context, [
|
|
5055
|
+
["grep <pattern> <file...>", t.t("cli.grep.help.search_one_more_files", "Search one or more files")],
|
|
5056
|
+
["grep -r <pattern> <dir>", t.t("cli.grep.help.search_every_file_under", "Search every file under a directory")],
|
|
5057
|
+
["<command> | grep <pattern>", t.t("cli.grep.help.filter_piped_input", "Filter piped input")]
|
|
5058
|
+
]);
|
|
5059
|
+
context.writer.writeln();
|
|
5060
|
+
writeExamples(context, [
|
|
5061
|
+
["grep -i error app.log", t.t("cli.grep.help.case_insensitive_search", "Case-insensitive search")],
|
|
5062
|
+
["grep -r -n TODO src", t.t("cli.grep.help.find_todos_line_numbers", "Find TODOs with line numbers")],
|
|
5063
|
+
["grep -v ^# config.txt", t.t("cli.grep.help.hide_comment_lines", "Hide comment lines")],
|
|
5064
|
+
["cat app.log | grep -c ERROR", t.t("cli.grep.help.count_matching_lines", "Count matching lines")]
|
|
5065
|
+
]);
|
|
5066
|
+
}
|
|
4433
5067
|
async processCommand(command, context) {
|
|
4434
5068
|
const fs = context.services.getRequired(
|
|
4435
5069
|
IFileSystemService_TOKEN
|
|
@@ -4440,51 +5074,56 @@ var files = (() => {
|
|
|
4440
5074
|
const countOnly = command.args["count"] || command.args["c"] || false;
|
|
4441
5075
|
const filesOnly = command.args["files-with-matches"] || command.args["l"] || false;
|
|
4442
5076
|
const invert = command.args["invert-match"] || command.args["v"] || false;
|
|
5077
|
+
const wordRegexp = command.args["word-regexp"] || command.args["w"] || false;
|
|
5078
|
+
const onlyMatching = command.args["only-matching"] || command.args["o"] || false;
|
|
5079
|
+
const quiet = command.args["quiet"] || command.args["q"] || false;
|
|
4443
5080
|
const { pattern, paths } = this.parseArgs(command);
|
|
4444
5081
|
if (!pattern) {
|
|
4445
5082
|
context.writer.writeError(
|
|
4446
5083
|
"grep: missing pattern. Usage: grep [options] <pattern> <file>"
|
|
4447
5084
|
);
|
|
5085
|
+
context.process.exit(2, { silent: true });
|
|
5086
|
+
return;
|
|
5087
|
+
}
|
|
5088
|
+
let regex;
|
|
5089
|
+
try {
|
|
5090
|
+
const source = wordRegexp ? `(?<!\\w)(?:${pattern})(?!\\w)` : pattern;
|
|
5091
|
+
regex = new RegExp(source, ignoreCase ? "gi" : "g");
|
|
5092
|
+
} catch {
|
|
5093
|
+
context.writer.writeError(`grep: invalid pattern '${pattern}'`);
|
|
5094
|
+
context.process.exit(2, { silent: true });
|
|
4448
5095
|
return;
|
|
4449
5096
|
}
|
|
4450
5097
|
if (paths.length === 0) {
|
|
4451
5098
|
if (command.data != null) {
|
|
4452
|
-
let regex2;
|
|
4453
|
-
try {
|
|
4454
|
-
regex2 = new RegExp(pattern, ignoreCase ? "gi" : "g");
|
|
4455
|
-
} catch {
|
|
4456
|
-
context.writer.writeError(`grep: invalid pattern '${pattern}'`);
|
|
4457
|
-
return;
|
|
4458
|
-
}
|
|
4459
5099
|
const content = typeof command.data === "string" ? command.data : JSON.stringify(command.data);
|
|
4460
|
-
this.grepContent(content, null,
|
|
5100
|
+
const found2 = this.grepContent(content, null, regex, {
|
|
4461
5101
|
ignoreCase,
|
|
4462
5102
|
showLineNum,
|
|
4463
5103
|
countOnly,
|
|
4464
5104
|
filesOnly,
|
|
4465
|
-
invert
|
|
5105
|
+
invert,
|
|
5106
|
+
onlyMatching,
|
|
5107
|
+
quiet
|
|
4466
5108
|
}, context, false);
|
|
5109
|
+
this.exitStatus(context, found2, false);
|
|
4467
5110
|
return;
|
|
4468
5111
|
}
|
|
4469
5112
|
context.writer.writeError(
|
|
4470
5113
|
"grep: missing file operand. Usage: grep [options] <pattern> <file>"
|
|
4471
5114
|
);
|
|
4472
|
-
|
|
4473
|
-
}
|
|
4474
|
-
let regex;
|
|
4475
|
-
try {
|
|
4476
|
-
regex = new RegExp(pattern, ignoreCase ? "gi" : "g");
|
|
4477
|
-
} catch {
|
|
4478
|
-
context.writer.writeError(`grep: invalid pattern '${pattern}'`);
|
|
5115
|
+
context.process.exit(2, { silent: true });
|
|
4479
5116
|
return;
|
|
4480
5117
|
}
|
|
4481
5118
|
const filePaths = [];
|
|
5119
|
+
let failed = false;
|
|
4482
5120
|
for (const p of paths) {
|
|
4483
5121
|
try {
|
|
4484
5122
|
if (!fs.exists(p)) {
|
|
4485
5123
|
context.writer.writeError(
|
|
4486
5124
|
`grep: ${p}: No such file or directory`
|
|
4487
5125
|
);
|
|
5126
|
+
failed = true;
|
|
4488
5127
|
continue;
|
|
4489
5128
|
}
|
|
4490
5129
|
if (fs.isDirectory(p)) {
|
|
@@ -4492,6 +5131,7 @@ var files = (() => {
|
|
|
4492
5131
|
context.writer.writeError(
|
|
4493
5132
|
`grep: ${p}: Is a directory`
|
|
4494
5133
|
);
|
|
5134
|
+
failed = true;
|
|
4495
5135
|
continue;
|
|
4496
5136
|
}
|
|
4497
5137
|
this.collectFiles(fs, fs.resolvePath(p), fs.getNode(p), filePaths);
|
|
@@ -4500,26 +5140,40 @@ var files = (() => {
|
|
|
4500
5140
|
}
|
|
4501
5141
|
} catch (e) {
|
|
4502
5142
|
context.writer.writeError(`grep: ${e.message}`);
|
|
5143
|
+
failed = true;
|
|
4503
5144
|
}
|
|
4504
5145
|
}
|
|
4505
5146
|
const multiFile = filePaths.length > 1;
|
|
5147
|
+
let found = 0;
|
|
4506
5148
|
for (const filePath of filePaths) {
|
|
4507
5149
|
try {
|
|
4508
5150
|
const content = fs.readFile(filePath) ?? "";
|
|
4509
|
-
this.grepContent(content, filePath, regex, {
|
|
5151
|
+
found += this.grepContent(content, filePath, regex, {
|
|
4510
5152
|
ignoreCase,
|
|
4511
5153
|
showLineNum,
|
|
4512
5154
|
countOnly,
|
|
4513
5155
|
filesOnly,
|
|
4514
|
-
invert
|
|
5156
|
+
invert,
|
|
5157
|
+
onlyMatching,
|
|
5158
|
+
quiet
|
|
4515
5159
|
}, context, multiFile);
|
|
4516
5160
|
} catch (e) {
|
|
4517
5161
|
context.writer.writeError(`grep: ${filePath}: ${e.message}`);
|
|
5162
|
+
failed = true;
|
|
4518
5163
|
}
|
|
4519
5164
|
}
|
|
5165
|
+
this.exitStatus(context, found, failed);
|
|
5166
|
+
}
|
|
5167
|
+
/**
|
|
5168
|
+
* As Unix grep: 0 when a line matched, 1 when none did, 2 after an
|
|
5169
|
+
* error (so `if grep -q ...` and `grep x f && ...` work).
|
|
5170
|
+
*/
|
|
5171
|
+
exitStatus(context, found, failed) {
|
|
5172
|
+
if (found > 0) return;
|
|
5173
|
+
context.process.exit(failed ? 2 : 1, { silent: true });
|
|
4520
5174
|
}
|
|
4521
5175
|
grepContent(content, filePath, regex, options, context, multiFile) {
|
|
4522
|
-
const lines = content
|
|
5176
|
+
const lines = splitLines(content);
|
|
4523
5177
|
let matchCount = 0;
|
|
4524
5178
|
const matchingLines = [];
|
|
4525
5179
|
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
@@ -4532,6 +5186,7 @@ var files = (() => {
|
|
|
4532
5186
|
matchingLines.push({ num: lineIdx + 1, text: line });
|
|
4533
5187
|
}
|
|
4534
5188
|
}
|
|
5189
|
+
if (options.quiet) return matchCount;
|
|
4535
5190
|
if (options.filesOnly) {
|
|
4536
5191
|
if (matchCount > 0 && filePath) {
|
|
4537
5192
|
context.writer.writeln(filePath);
|
|
@@ -4550,6 +5205,18 @@ var files = (() => {
|
|
|
4550
5205
|
parts.push(context.writer.wrapInColor(String(m.num), CliForegroundColor.Green));
|
|
4551
5206
|
parts.push(":");
|
|
4552
5207
|
}
|
|
5208
|
+
if (options.onlyMatching && !options.invert) {
|
|
5209
|
+
regex.lastIndex = 0;
|
|
5210
|
+
const prefix = parts.join("");
|
|
5211
|
+
for (const match of m.text.match(regex) ?? []) {
|
|
5212
|
+
if (match !== "") {
|
|
5213
|
+
context.writer.writeln(
|
|
5214
|
+
prefix + context.writer.wrapInColor(match, CliForegroundColor.Red)
|
|
5215
|
+
);
|
|
5216
|
+
}
|
|
5217
|
+
}
|
|
5218
|
+
continue;
|
|
5219
|
+
}
|
|
4553
5220
|
if (!options.invert) {
|
|
4554
5221
|
regex.lastIndex = 0;
|
|
4555
5222
|
const highlighted = m.text.replace(
|
|
@@ -4563,10 +5230,11 @@ var files = (() => {
|
|
|
4563
5230
|
context.writer.writeln(parts.join(""));
|
|
4564
5231
|
}
|
|
4565
5232
|
}
|
|
5233
|
+
return matchCount;
|
|
4566
5234
|
}
|
|
4567
5235
|
parseArgs(command) {
|
|
4568
5236
|
const raw = command.value || "";
|
|
4569
|
-
const tokens = raw
|
|
5237
|
+
const tokens = splitArgs(raw).filter(Boolean);
|
|
4570
5238
|
if (tokens.length === 0) {
|
|
4571
5239
|
return { pattern: null, paths: [] };
|
|
4572
5240
|
}
|
|
@@ -4616,14 +5284,11 @@ var files = (() => {
|
|
|
4616
5284
|
const fs = context.services.getRequired(
|
|
4617
5285
|
IFileSystemService_TOKEN
|
|
4618
5286
|
);
|
|
4619
|
-
let
|
|
4620
|
-
if (
|
|
4621
|
-
|
|
4622
|
-
const firstSpace = raw.indexOf(" ");
|
|
4623
|
-
if (firstSpace > -1) {
|
|
4624
|
-
filePath = raw.slice(firstSpace + 1).trim();
|
|
4625
|
-
}
|
|
5287
|
+
let words = splitArgs(command.value || "");
|
|
5288
|
+
if (words.length === 0 && command.rawCommand) {
|
|
5289
|
+
words = splitArgs(command.rawCommand).slice(1).filter((w) => !w.startsWith("-"));
|
|
4626
5290
|
}
|
|
5291
|
+
const filePath = words[0] ?? "";
|
|
4627
5292
|
if (!filePath) {
|
|
4628
5293
|
context.writer.writeError("sh: missing file operand");
|
|
4629
5294
|
context.process.exit(1, { silent: true });
|
|
@@ -4656,10 +5321,10 @@ var files = (() => {
|
|
|
4656
5321
|
await executeScript(content, context);
|
|
4657
5322
|
}
|
|
4658
5323
|
writeDescription(context) {
|
|
4659
|
-
const { writer } = context;
|
|
4660
|
-
writer.writeln(this.description);
|
|
5324
|
+
const { writer, translator: t } = context;
|
|
5325
|
+
writer.writeln(t.t("cli.sh.description", this.description));
|
|
4661
5326
|
writer.writeln();
|
|
4662
|
-
writer.writeln("Usage:");
|
|
5327
|
+
writer.writeln(t.t("cli.common.usage", "Usage:"));
|
|
4663
5328
|
writer.writeln(
|
|
4664
5329
|
` ${writer.wrapInColor("sh <script.sh>", CliForegroundColor.Cyan)}`
|
|
4665
5330
|
);
|
|
@@ -4670,74 +5335,48 @@ var files = (() => {
|
|
|
4670
5335
|
` ${writer.wrapInColor(". <script.sh>", CliForegroundColor.Cyan)}`
|
|
4671
5336
|
);
|
|
4672
5337
|
writer.writeln(
|
|
4673
|
-
` ${writer.wrapInColor("./script.sh", CliForegroundColor.Cyan)} (requires execute permission)`
|
|
5338
|
+
` ${writer.wrapInColor("./script.sh", CliForegroundColor.Cyan)} ${t.t("cli.sh.help.requires_execute", "(requires execute permission)")}`
|
|
4674
5339
|
);
|
|
4675
5340
|
writer.writeln();
|
|
4676
|
-
writer.writeln("Script syntax:");
|
|
4677
|
-
writer.writeln(
|
|
4678
|
-
writer.writeln(
|
|
4679
|
-
writer.writeln(
|
|
4680
|
-
writer.writeln(
|
|
4681
|
-
writer.writeln(
|
|
5341
|
+
writer.writeln(t.t("cli.sh.help.script_syntax", "Script syntax:"));
|
|
5342
|
+
writer.writeln(` # ${t.t("cli.sh.help.comments", "Lines starting with # are comments")}`);
|
|
5343
|
+
writer.writeln(` cmd1; cmd2 # ${t.t("cli.sh.help.several_commands", "Several commands on one line")}`);
|
|
5344
|
+
writer.writeln(` VAR=value # ${t.t("cli.sh.help.assignment", "Variable assignment")}`);
|
|
5345
|
+
writer.writeln(` echo $VAR # ${t.t("cli.sh.help.substitution", "Variable substitution")}`);
|
|
5346
|
+
writer.writeln(` set -e # ${t.t("cli.sh.help.stop_on_error", "Stop on error (default)")}`);
|
|
5347
|
+
writer.writeln(` set +e # ${t.t("cli.sh.help.continue_on_errors", "Continue on errors")}`);
|
|
5348
|
+
writer.writeln(` exit [n] # ${t.t("cli.sh.help.exit", "Stop the script with status n")}`);
|
|
5349
|
+
writer.writeln();
|
|
5350
|
+
writer.writeln(t.t("cli.sh.help.control_flow", "Control flow:"));
|
|
5351
|
+
writer.writeln(" if cmd; then ...; elif cmd; then ...; else ...; fi");
|
|
5352
|
+
writer.writeln(" for NAME in a b *.txt; do ...; done");
|
|
5353
|
+
writer.writeln(` while cmd; do ...; done ${t.t("cli.sh.help.until", "(until cmd: the opposite)")}`);
|
|
5354
|
+
writer.writeln(` break / continue [n] # ${t.t("cli.sh.help.break_continue", "Leave / skip in a loop")}`);
|
|
5355
|
+
writer.writeln(` ! cmd # ${t.t("cli.sh.help.negate", "Negate the exit status")}`);
|
|
5356
|
+
writer.writeln(
|
|
5357
|
+
` ${t.t("cli.sh.help.conditions", "Conditions are commands:")} ${writer.wrapInColor("[ -f file ]", CliForegroundColor.Cyan)}, ${writer.wrapInColor('test "$A" = b', CliForegroundColor.Cyan)}, ${writer.wrapInColor("true", CliForegroundColor.Cyan)}, ${writer.wrapInColor("grep x file", CliForegroundColor.Cyan)}`
|
|
5358
|
+
);
|
|
5359
|
+
writer.writeln(` ${t.t("cli.sh.help.conditions_status", "(status 0 = true; see help test). Loops stop after 10000 iterations")}`);
|
|
5360
|
+
writer.writeln(` ${t.t("cli.sh.help.conditions_loops", "of while/until; Ctrl+C stops the script.")}`);
|
|
4682
5361
|
writer.writeln();
|
|
4683
|
-
writer.writeln("Example script:");
|
|
5362
|
+
writer.writeln(t.t("cli.sh.help.example_script", "Example script:"));
|
|
4684
5363
|
writer.writeln(
|
|
4685
5364
|
writer.wrapInColor(
|
|
4686
|
-
" #!/bin/sh\n # Setup script\n NAME=world\n echo Hello $NAME\n mkdir -p /tmp/test\n echo done > /tmp/test/status.txt",
|
|
5365
|
+
" #!/bin/sh\n # Setup script\n NAME=world\n echo Hello $NAME\n mkdir -p /tmp/test\n for f in a b c; do\n echo $f > /tmp/test/$f.txt\n done\n if [ -f /tmp/test/a.txt ]; then\n echo done > /tmp/test/status.txt\n fi",
|
|
4687
5366
|
CliForegroundColor.Green
|
|
4688
5367
|
)
|
|
4689
5368
|
);
|
|
4690
5369
|
}
|
|
4691
5370
|
};
|
|
5371
|
+
var SCRIPT_RUNNER_TOKEN = "cli-script-runner";
|
|
4692
5372
|
async function executeScript(content, context) {
|
|
4693
|
-
const
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
if (!line || line.startsWith("#")) {
|
|
4699
|
-
continue;
|
|
4700
|
-
}
|
|
4701
|
-
if (line === "set -e") {
|
|
4702
|
-
stopOnError = true;
|
|
4703
|
-
continue;
|
|
4704
|
-
}
|
|
4705
|
-
if (line === "set +e") {
|
|
4706
|
-
stopOnError = false;
|
|
4707
|
-
continue;
|
|
4708
|
-
}
|
|
4709
|
-
const assignMatch = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
|
|
4710
|
-
if (assignMatch) {
|
|
4711
|
-
const varName = assignMatch[1];
|
|
4712
|
-
let varValue = assignMatch[2];
|
|
4713
|
-
if (varValue.startsWith('"') && varValue.endsWith('"') || varValue.startsWith("'") && varValue.endsWith("'")) {
|
|
4714
|
-
varValue = varValue.slice(1, -1);
|
|
4715
|
-
}
|
|
4716
|
-
varValue = substituteVariables(varValue, variables);
|
|
4717
|
-
variables[varName] = varValue;
|
|
4718
|
-
continue;
|
|
4719
|
-
}
|
|
4720
|
-
const expanded = substituteVariables(line, variables);
|
|
4721
|
-
await context.executor.executeCommand(expanded, context);
|
|
4722
|
-
const exitCode = context.process.exitCode;
|
|
4723
|
-
if (stopOnError && exitCode !== void 0 && exitCode !== 0) {
|
|
4724
|
-
context.writer.writeError(
|
|
4725
|
-
`sh: script aborted at line: ${line}`
|
|
4726
|
-
);
|
|
4727
|
-
return;
|
|
4728
|
-
}
|
|
5373
|
+
const runner = context.services.get(SCRIPT_RUNNER_TOKEN);
|
|
5374
|
+
if (!runner) {
|
|
5375
|
+
context.writer.writeError("sh: script runner not available (update @qodalis/cli)");
|
|
5376
|
+
context.process.exit(1, { silent: true });
|
|
5377
|
+
return;
|
|
4729
5378
|
}
|
|
4730
|
-
|
|
4731
|
-
function substituteVariables(input, variables) {
|
|
4732
|
-
let result = input.replace(
|
|
4733
|
-
/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,
|
|
4734
|
-
(_, name) => variables[name] ?? ""
|
|
4735
|
-
);
|
|
4736
|
-
result = result.replace(
|
|
4737
|
-
/\$([A-Za-z_][A-Za-z0-9_]*)/g,
|
|
4738
|
-
(_, name) => variables[name] ?? ""
|
|
4739
|
-
);
|
|
4740
|
-
return result;
|
|
5379
|
+
await runner.run(content, context, { name: "sh" });
|
|
4741
5380
|
}
|
|
4742
5381
|
|
|
4743
5382
|
// src/cli-entrypoint.ts
|