• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env node
2"use strict";
3Object.defineProperty(exports, "__esModule", { value: true });
4const foreground_child_1 = require("foreground-child");
5const fs_1 = require("fs");
6const jackspeak_1 = require("jackspeak");
7const index_js_1 = require("./index.js");
8const package_json_1 = require("../package.json");
9const j = (0, jackspeak_1.jack)({
10    usage: 'glob [options] [<pattern> [<pattern> ...]]'
11})
12    .description(`
13    Glob v${package_json_1.version}
14
15    Expand the positional glob expression arguments into any matching file
16    system paths found.
17  `)
18    .opt({
19    cmd: {
20        short: 'c',
21        hint: 'command',
22        description: `Run the command provided, passing the glob expression
23                    matches as arguments.`,
24    },
25})
26    .flag({
27    all: {
28        short: 'A',
29        description: `By default, the glob cli command will not expand any
30                    arguments that are an exact match to a file on disk.
31
32                    This prevents double-expanding, in case the shell expands
33                    an argument whose filename is a glob expression.
34
35                    For example, if 'app/*.ts' would match 'app/[id].ts', then
36                    on Windows powershell or cmd.exe, 'glob app/*.ts' will
37                    expand to 'app/[id].ts', as expected. However, in posix
38                    shells such as bash or zsh, the shell will first expand
39                    'app/*.ts' to a list of filenames. Then glob will look
40                    for a file matching 'app/[id].ts' (ie, 'app/i.ts' or
41                    'app/d.ts'), which is unexpected.
42
43                    Setting '--all' prevents this behavior, causing glob
44                    to treat ALL patterns as glob expressions to be expanded,
45                    even if they are an exact match to a file on disk.
46
47                    When setting this option, be sure to enquote arguments
48                    so that the shell will not expand them prior to passing
49                    them to the glob command process.
50      `,
51    },
52    absolute: {
53        short: 'a',
54        description: 'Expand to absolute paths',
55    },
56    'dot-relative': {
57        short: 'd',
58        description: `Prepend './' on relative matches`,
59    },
60    mark: {
61        short: 'm',
62        description: `Append a / on any directories matched`,
63    },
64    posix: {
65        short: 'x',
66        description: `Always resolve to posix style paths, using '/' as the
67                    directory separator, even on Windows. Drive letter
68                    absolute matches on Windows will be expanded to their
69                    full resolved UNC maths, eg instead of 'C:\\foo\\bar',
70                    it will expand to '//?/C:/foo/bar'.
71      `,
72    },
73    follow: {
74        short: 'f',
75        description: `Follow symlinked directories when expanding '**'`,
76    },
77    realpath: {
78        short: 'R',
79        description: `Call 'fs.realpath' on all of the results. In the case
80                    of an entry that cannot be resolved, the entry is
81                    omitted. This incurs a slight performance penalty, of
82                    course, because of the added system calls.`,
83    },
84    stat: {
85        short: 's',
86        description: `Call 'fs.lstat' on all entries, whether required or not
87                    to determine if it's a valid match.`,
88    },
89    'match-base': {
90        short: 'b',
91        description: `Perform a basename-only match if the pattern does not
92                    contain any slash characters. That is, '*.js' would be
93                    treated as equivalent to '**/*.js', matching js files
94                    in all directories.
95      `,
96    },
97    dot: {
98        description: `Allow patterns to match files/directories that start
99                    with '.', even if the pattern does not start with '.'
100      `,
101    },
102    nobrace: {
103        description: 'Do not expand {...} patterns',
104    },
105    nocase: {
106        description: `Perform a case-insensitive match. This defaults to
107                    'true' on macOS and Windows platforms, and false on
108                    all others.
109
110                    Note: 'nocase' should only be explicitly set when it is
111                    known that the filesystem's case sensitivity differs
112                    from the platform default. If set 'true' on
113                    case-insensitive file systems, then the walk may return
114                    more or less results than expected.
115      `,
116    },
117    nodir: {
118        description: `Do not match directories, only files.
119
120                    Note: to *only* match directories, append a '/' at the
121                    end of the pattern.
122      `,
123    },
124    noext: {
125        description: `Do not expand extglob patterns, such as '+(a|b)'`,
126    },
127    noglobstar: {
128        description: `Do not expand '**' against multiple path portions.
129                    Ie, treat it as a normal '*' instead.`,
130    },
131    'windows-path-no-escape': {
132        description: `Use '\\' as a path separator *only*, and *never* as an
133                    escape character. If set, all '\\' characters are
134                    replaced with '/' in the pattern.`,
135    },
136})
137    .num({
138    'max-depth': {
139        short: 'D',
140        description: `Maximum depth to traverse from the current
141                    working directory`,
142    },
143})
144    .opt({
145    cwd: {
146        short: 'C',
147        description: 'Current working directory to execute/match in',
148        default: process.cwd(),
149    },
150    root: {
151        short: 'r',
152        description: `A string path resolved against the 'cwd', which is
153                    used as the starting point for absolute patterns that
154                    start with '/' (but not drive letters or UNC paths
155                    on Windows).
156
157                    Note that this *doesn't* necessarily limit the walk to
158                    the 'root' directory, and doesn't affect the cwd
159                    starting point for non-absolute patterns. A pattern
160                    containing '..' will still be able to traverse out of
161                    the root directory, if it is not an actual root directory
162                    on the filesystem, and any non-absolute patterns will
163                    still be matched in the 'cwd'.
164
165                    To start absolute and non-absolute patterns in the same
166                    path, you can use '--root=' to set it to the empty
167                    string. However, be aware that on Windows systems, a
168                    pattern like 'x:/*' or '//host/share/*' will *always*
169                    start in the 'x:/' or '//host/share/' directory,
170                    regardless of the --root setting.
171      `,
172    },
173    platform: {
174        description: `Defaults to the value of 'process.platform' if
175                    available, or 'linux' if not. Setting --platform=win32
176                    on non-Windows systems may cause strange behavior!`,
177        validate: v => new Set([
178            'aix',
179            'android',
180            'darwin',
181            'freebsd',
182            'haiku',
183            'linux',
184            'openbsd',
185            'sunos',
186            'win32',
187            'cygwin',
188            'netbsd',
189        ]).has(v),
190    },
191})
192    .optList({
193    ignore: {
194        short: 'i',
195        description: `Glob patterns to ignore`,
196    },
197})
198    .flag({
199    debug: {
200        short: 'v',
201        description: `Output a huge amount of noisy debug information about
202                    patterns as they are parsed and used to match files.`,
203    },
204})
205    .flag({
206    help: {
207        short: 'h',
208        description: 'Show this usage information',
209    },
210});
211try {
212    const { positionals, values } = j.parse();
213    if (values.help) {
214        console.log(j.usage());
215        process.exit(0);
216    }
217    if (positionals.length === 0)
218        throw 'No patterns provided';
219    const patterns = values.all
220        ? positionals
221        : positionals.filter(p => !(0, fs_1.existsSync)(p));
222    const matches = values.all ? [] : positionals.filter(p => (0, fs_1.existsSync)(p));
223    const stream = (0, index_js_1.globStream)(patterns, {
224        absolute: values.absolute,
225        cwd: values.cwd,
226        dot: values.dot,
227        dotRelative: values['dot-relative'],
228        follow: values.follow,
229        ignore: values.ignore,
230        mark: values.mark,
231        matchBase: values['match-base'],
232        maxDepth: values['max-depth'],
233        nobrace: values.nobrace,
234        nocase: values.nocase,
235        nodir: values.nodir,
236        noext: values.noext,
237        noglobstar: values.noglobstar,
238        platform: values.platform,
239        realpath: values.realpath,
240        root: values.root,
241        stat: values.stat,
242        debug: values.debug,
243        posix: values.posix,
244    });
245    const cmd = values.cmd;
246    if (!cmd) {
247        matches.forEach(m => console.log(m));
248        stream.on('data', f => console.log(f));
249    }
250    else {
251        stream.on('data', f => matches.push(f));
252        stream.on('end', () => (0, foreground_child_1.foregroundChild)(cmd, matches, { shell: true }));
253    }
254}
255catch (e) {
256    console.error(j.usage());
257    console.error(e instanceof Error ? e.message : String(e));
258    process.exit(1);
259}
260//# sourceMappingURL=bin.js.map