Skip to main content
Module

std/path/glob.ts

Deno standard library
Go to Latest
File
import { SEP, SEP_PATTERN } from "./constants.ts";import { globrex } from "./globrex.ts";import { join, normalize } from "./mod.ts";import { assert } from "../testing/asserts.ts";
export interface GlobOptions { extended?: boolean; globstar?: boolean;}
export interface GlobToRegExpOptions extends GlobOptions { flags?: string;}
/** * Generate a regex based on glob pattern and options * This was meant to be using the the `fs.walk` function * but can be used anywhere else. * Examples: * * Looking for all the `ts` files: * walkSync(".", { * match: [globToRegExp("*.ts")] * }) * * Looking for all the `.json` files in any subfolder: * walkSync(".", { * match: [globToRegExp(join("a", "**", "*.json"),{ * flags: "g", * extended: true, * globstar: true * })] * }) * * @param glob - Glob pattern to be used * @param options - Specific options for the glob pattern * @returns A RegExp for the glob pattern */export function globToRegExp( glob: string, { extended = false, globstar = true }: GlobToRegExpOptions = {}): RegExp { const result = globrex(glob, { extended, globstar, strict: false, filepath: true, }); assert(result.path != null); return result.path.regex;}
/** Test whether the given string is a glob */export function isGlob(str: string): boolean { const chars: Record<string, string> = { "{": "}", "(": ")", "[": "]" }; /* eslint-disable-next-line max-len */ const regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
if (str === "") { return false; }
let match: RegExpExecArray | null;
while ((match = regex.exec(str))) { if (match[2]) return true; let idx = match.index + match[0].length;
// if an open bracket/brace/paren is escaped, // set the index to the next closing character const open = match[1]; const close = open ? chars[open] : null; if (open && close) { const n = str.indexOf(close, idx); if (n !== -1) { idx = n + 1; } }
str = str.slice(idx); }
return false;}
/** Like normalize(), but doesn't collapse "**\/.." when `globstar` is true. */export function normalizeGlob( glob: string, { globstar = false }: GlobOptions = {}): string { if (!!glob.match(/\0/g)) { throw new Error(`Glob contains invalid characters: "${glob}"`); } if (!globstar) { return normalize(glob); } const s = SEP_PATTERN.source; const badParentPattern = new RegExp( `(?<=(${s}|^)\\*\\*${s})\\.\\.(?=${s}|$)`, "g" ); return normalize(glob.replace(badParentPattern, "\0")).replace(/\0/g, "..");}
/** Like join(), but doesn't collapse "**\/.." when `globstar` is true. */export function joinGlobs( globs: string[], { extended = false, globstar = false }: GlobOptions = {}): string { if (!globstar || globs.length == 0) { return join(...globs); } if (globs.length === 0) return "."; let joined: string | undefined; for (const glob of globs) { const path = glob; if (path.length > 0) { if (!joined) joined = path; else joined += `${SEP}${path}`; } } if (!joined) return "."; return normalizeGlob(joined, { extended, globstar });}