From 8a02dda6f44fbf1190dc8b4a1b287e974fee7cba Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Sat, 28 Sep 2019 17:32:41 +0100 Subject: [PATCH] prettier: Refactor to use expandGlob() Regression. The prettier tests will fail until expandGlob() is fixed since they try to match absolute paths outside of CWD. --- prettier/main.ts | 101 +++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/prettier/main.ts b/prettier/main.ts index 1afda89d1fbad..0def522d433b8 100755 --- a/prettier/main.ts +++ b/prettier/main.ts @@ -23,11 +23,12 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // This script formats the given source files. If the files are omitted, it // formats the all files in the repository. -const { args, exit, readFile, writeFile, stdout, stdin, readAll } = Deno; -import { glob, isGlob, GlobOptions } from "../fs/glob.ts"; -import { walk, WalkInfo } from "../fs/walk.ts"; +import { ExpandGlobOptions, expandGlob, glob } from "../fs/glob.ts"; +import { isAbsolute, join } from "../fs/path/mod.ts"; +import { WalkInfo } from "../fs/walk.ts"; import { parse } from "../flags/mod.ts"; import { prettier, prettierPlugins } from "./prettier.ts"; +const { args, cwd, exit, readAll, readFile, stdin, stdout, writeFile } = Deno; const HELP_MESSAGE = ` Formats the given files. If no arg is passed, then formats the all files. @@ -289,65 +290,57 @@ async function formatFromStdin( /** * Get the files to format. - * @param selectors The glob patterns to select the files. - * eg `cmd/*.ts` to select all the typescript files in cmd + * @param include The glob patterns to select the files. + * eg `"cmd/*.ts"` to select all the typescript files in cmd * directory. - * eg `cmd/run.ts` to select `cmd/run.ts` file as only. - * @param ignore The glob patterns to ignore files. - * eg `*_test.ts` to ignore all the test file. - * @param options options to pass to `glob(selector, options)` + * eg `"cmd/run.ts"` to select `cmd/run.ts` file as only. + * @param exclude The glob patterns to ignore files. + * eg `"*_test.ts"` to ignore all the test file. + * @param root The directory from which to apply default globs. * @returns returns an async iterable object */ -function getTargetFiles( - selectors: string[], - ignore: string[] = [], - options: GlobOptions = {} +async function* getTargetFiles( + include: string[], + exclude: string[], + root: string = cwd() ): AsyncIterableIterator { - const matchers: Array = []; - - const selectorMap: { [k: string]: boolean } = {}; + const expandGlobOpts: ExpandGlobOptions = { + root, + extended: true, + globstar: true, + filepath: true + }; - for (const selector of selectors) { - // If the selector already exists then ignore it. - if (selectorMap[selector]) continue; - selectorMap[selector] = true; - if (isGlob(selector) || selector === ".") { - matchers.push(glob(selector, options)); - } else { - matchers.push(selector); + // TODO: We use the `g` flag here to support path prefixes when specifying + // excludes. Replace with a solution that does this more correctly. + const excludePathPatterns = exclude.map( + (s: string): RegExp => + glob(isAbsolute(s) ? s : join(root, s), { ...expandGlobOpts, flags: "g" }) + ); + const shouldInclude = ({ filename }: WalkInfo): boolean => + !excludePathPatterns.some((p: RegExp): boolean => !!filename.match(p)); + + async function* expandDirectory(d: string): AsyncIterableIterator { + for await (const walkInfo of expandGlob("**/*", { + ...expandGlobOpts, + root: d, + includeDirs: false + })) { + if (shouldInclude(walkInfo)) { + yield walkInfo; + } } } - const skip = ignore.map((i: string): RegExp => glob(i, options)); - - return (async function*(): AsyncIterableIterator { - for (const match of matchers) { - if (typeof match === "string") { - const fileInfo = await Deno.stat(match); - - if (fileInfo.isDirectory()) { - const files = walk(match, { skip }); - - for await (const info of files) { - yield info; - } - } else { - const info: WalkInfo = { - filename: match, - info: fileInfo - }; - - yield info; - } - } else { - const files = walk(".", { match: [match], skip }); - - for await (const info of files) { - yield info; - } + for (const globString of include) { + for await (const walkInfo of expandGlob(globString, expandGlobOpts)) { + if (walkInfo.info.isDirectory()) { + yield* expandDirectory(walkInfo.filename); + } else if (shouldInclude(walkInfo)) { + yield walkInfo; } } - })(); + } } async function main(opts): Promise { @@ -371,12 +364,10 @@ async function main(opts): Promise { console.log(HELP_MESSAGE); exit(0); } - const options: GlobOptions = { flags: "g" }; const files = getTargetFiles( args.length ? args : ["."], - Array.isArray(ignore) ? ignore : [ignore], - options + Array.isArray(ignore) ? ignore : [ignore] ); const tty = Deno.isTTY();