diff options
Diffstat (limited to 'std/fs/globrex.ts')
-rw-r--r-- | std/fs/globrex.ts | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/std/fs/globrex.ts b/std/fs/globrex.ts deleted file mode 100644 index 5bf0e16a0..000000000 --- a/std/fs/globrex.ts +++ /dev/null @@ -1,326 +0,0 @@ -// This file is ported from globrex@0.1.2 -// MIT License -// Copyright (c) 2018 Terkel Gjervig Nielsen - -const isWin = Deno.build.os === "win"; -const SEP = isWin ? `(\\\\+|\\/)` : `\\/`; -const SEP_ESC = isWin ? `\\\\` : `/`; -const SEP_RAW = isWin ? `\\` : `/`; -const GLOBSTAR = `((?:[^${SEP_ESC}/]*(?:${SEP_ESC}|\/|$))*)`; -const WILDCARD = `([^${SEP_ESC}/]*)`; -const GLOBSTAR_SEGMENT = `((?:[^${SEP_ESC}/]*(?:${SEP_ESC}|\/|$))*)`; -const WILDCARD_SEGMENT = `([^${SEP_ESC}/]*)`; - -export interface GlobrexOptions { - // Allow ExtGlob features - extended?: boolean; - // When globstar is true, '/foo/**' is equivelant - // to '/foo/*' when globstar is false. - // Having globstar set to true is the same usage as - // using wildcards in bash - globstar?: boolean; - // be laissez faire about mutiple slashes - strict?: boolean; - // Parse as filepath for extra path related features - filepath?: boolean; - // Flag to use in the generated RegExp - flags?: string; -} - -export interface GlobrexResult { - regex: RegExp; - path?: { - regex: RegExp; - segments: RegExp[]; - globstar?: RegExp; - }; -} - -/** - * Convert any glob pattern to a JavaScript Regexp object - * @param glob Glob pattern to convert - * @param opts Configuration object - * @param [opts.extended=false] Support advanced ext globbing - * @param [opts.globstar=false] Support globstar - * @param [opts.strict=true] be laissez faire about mutiple slashes - * @param [opts.filepath=""] Parse as filepath for extra path related features - * @param [opts.flags=""] RegExp globs - * @returns Converted object with string, segments and RegExp object - */ -export function globrex( - glob: string, - { - extended = false, - globstar = false, - strict = false, - filepath = false, - flags = "" - }: GlobrexOptions = {} -): GlobrexResult { - let regex = ""; - let segment = ""; - let pathRegexStr = ""; - const pathSegments = []; - - // If we are doing extended matching, this boolean is true when we are inside - // a group (eg {*.html,*.js}), and false otherwise. - let inGroup = false; - let inRange = false; - - // extglob stack. Keep track of scope - const ext = []; - - interface AddOptions { - split?: boolean; - last?: boolean; - only?: string; - } - - // Helper function to build string and segments - function add( - str: string, - options: AddOptions = { split: false, last: false, only: "" } - ): void { - const { split, last, only } = options; - if (only !== "path") regex += str; - if (filepath && only !== "regex") { - pathRegexStr += str.match(new RegExp(`^${SEP}$`)) ? SEP : str; - if (split) { - if (last) segment += str; - if (segment !== "") { - // change it 'includes' - if (!flags.includes("g")) segment = `^${segment}$`; - pathSegments.push(new RegExp(segment, flags)); - } - segment = ""; - } else { - segment += str; - } - } - } - - let c, n; - for (let i = 0; i < glob.length; i++) { - c = glob[i]; - n = glob[i + 1]; - - if (["\\", "$", "^", ".", "="].includes(c)) { - add(`\\${c}`); - continue; - } - - if (c === "/") { - add(`\\${c}`, { split: true }); - if (n === "/" && !strict) regex += "?"; - continue; - } - - if (c === "(") { - if (ext.length) { - add(c); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === ")") { - if (ext.length) { - add(c); - const type: string | undefined = ext.pop(); - if (type === "@") { - add("{1}"); - } else if (type === "!") { - add("([^/]*)"); - } else { - add(type as string); - } - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "|") { - if (ext.length) { - add(c); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "+") { - if (n === "(" && extended) { - ext.push(c); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "@" && extended) { - if (n === "(") { - ext.push(c); - continue; - } - } - - if (c === "!") { - if (extended) { - if (inRange) { - add("^"); - continue; - } - if (n === "(") { - ext.push(c); - add("(?!"); - i++; - continue; - } - add(`\\${c}`); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "?") { - if (extended) { - if (n === "(") { - ext.push(c); - } else { - add("."); - } - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "[") { - if (inRange && n === ":") { - i++; // skip [ - let value = ""; - while (glob[++i] !== ":") value += glob[i]; - if (value === "alnum") add("(\\w|\\d)"); - else if (value === "space") add("\\s"); - else if (value === "digit") add("\\d"); - i++; // skip last ] - continue; - } - if (extended) { - inRange = true; - add(c); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "]") { - if (extended) { - inRange = false; - add(c); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "{") { - if (extended) { - inGroup = true; - add("("); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "}") { - if (extended) { - inGroup = false; - add(")"); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === ",") { - if (inGroup) { - add("|"); - continue; - } - add(`\\${c}`); - continue; - } - - if (c === "*") { - if (n === "(" && extended) { - ext.push(c); - continue; - } - // Move over all consecutive "*"'s. - // Also store the previous and next characters - const prevChar = glob[i - 1]; - let starCount = 1; - while (glob[i + 1] === "*") { - starCount++; - i++; - } - const nextChar = glob[i + 1]; - if (!globstar) { - // globstar is disabled, so treat any number of "*" as one - add(".*"); - } else { - // globstar is enabled, so determine if this is a globstar segment - const isGlobstar = - starCount > 1 && // multiple "*"'s - // from the start of the segment - [SEP_RAW, "/", undefined].includes(prevChar) && - // to the end of the segment - [SEP_RAW, "/", undefined].includes(nextChar); - if (isGlobstar) { - // it's a globstar, so match zero or more path segments - add(GLOBSTAR, { only: "regex" }); - add(GLOBSTAR_SEGMENT, { only: "path", last: true, split: true }); - i++; // move over the "/" - } else { - // it's not a globstar, so only match one path segment - add(WILDCARD, { only: "regex" }); - add(WILDCARD_SEGMENT, { only: "path" }); - } - } - continue; - } - - add(c); - } - - // When regexp 'g' flag is specified don't - // constrain the regular expression with ^ & $ - if (!flags.includes("g")) { - regex = `^${regex}$`; - segment = `^${segment}$`; - if (filepath) pathRegexStr = `^${pathRegexStr}$`; - } - - const result: GlobrexResult = { regex: new RegExp(regex, flags) }; - - // Push the last segment - if (filepath) { - pathSegments.push(new RegExp(segment, flags)); - result.path = { - regex: new RegExp(pathRegexStr, flags), - segments: pathSegments, - globstar: new RegExp( - !flags.includes("g") ? `^${GLOBSTAR_SEGMENT}$` : GLOBSTAR_SEGMENT, - flags - ) - }; - } - - return result; -} |