From f9f81cb92d9eb1dceaa0e5f77e7d8e6271cad5a1 Mon Sep 17 00:00:00 2001 From: eric sciple Date: Wed, 8 Jan 2020 16:07:06 -0500 Subject: [PATCH] . --- .../glob/__tests__/internal-globber.test.ts | 42 +++++++------------ packages/glob/src/glob.ts | 8 +++- .../glob/src/internal-glob-options-helper.ts | 2 +- packages/glob/src/internal-glob-options.ts | 5 ++- packages/glob/src/internal-globber.ts | 39 ++++++----------- 5 files changed, 39 insertions(+), 57 deletions(-) diff --git a/packages/glob/__tests__/internal-globber.test.ts b/packages/glob/__tests__/internal-globber.test.ts index eb778b88..9508628c 100644 --- a/packages/glob/__tests__/internal-globber.test.ts +++ b/packages/glob/__tests__/internal-globber.test.ts @@ -38,7 +38,7 @@ describe('globber', () => { const originalCwd = process.cwd() try { process.chdir(path.join(root, 'first-cwd')) - const globber = await DefaultGlobber.parse('*') + const globber = await DefaultGlobber.create('*') process.chdir(path.join(root, 'second-cwd')) expect(globber.getSearchPaths()).toEqual([path.join(root, 'first-cwd')]) const itemPaths = await globber.glob() @@ -175,7 +175,7 @@ describe('globber', () => { // todo: ? expect(itemPaths[2]).toBe(path.join(root, 'symDir', 'symDir')); }) - it('does not follow symlink when followSymbolicLink=false', async () => { + it('does not follow symlink when followSymbolicLinks=false', async () => { // Create the following layout: // // /realDir @@ -192,7 +192,7 @@ describe('globber', () => { path.join(root, 'symDir') ) - const itemPaths = await glob(root) + const itemPaths = await glob(root, {followSymbolicLinks: false}) expect(itemPaths).toEqual([ root, path.join(root, 'realDir'), @@ -201,7 +201,7 @@ describe('globber', () => { ]) }) - it('does not follow symlink when search path is symlink and followSymbolicLink=false', async () => { + it('does not follow symlink when search path is symlink and followSymbolicLinks=false', async () => { // Create the following layout: // realDir // realDir/file @@ -217,7 +217,9 @@ describe('globber', () => { path.join(root, 'symDir') ) - const itemPaths = await glob(path.join(root, 'symDir')) + const itemPaths = await glob(path.join(root, 'symDir'), { + followSymbolicLinks: false + }) expect(itemPaths).toEqual([path.join(root, 'symDir')]) }) @@ -406,20 +408,6 @@ describe('globber', () => { ]) }) - it('parses options', async () => { - let globber: Globber - globber = await DefaultGlobber.parse( - `--follow-symbolic-links${os.EOL}/foo/*` - ) - expect(globber.options.followSymbolicLinks).toBeTruthy() - expect(globber.getSearchPaths()).toHaveLength(1) - globber = await DefaultGlobber.parse(`/foo/*`) // sanity check - expect(globber.options.implicitDescendants === undefined).toBeTruthy() - expect(globber.options.followSymbolicLinks === undefined).toBeTruthy() - expect(globber.options.omitBrokenSymbolicLinks === undefined).toBeTruthy() - expect(globber.getSearchPaths()).toHaveLength(1) - }) - it('returns broken symlink when followSymbolicLinks=false', async () => { // Create the following layout: // @@ -443,7 +431,7 @@ describe('globber', () => { path.join(root, 'symDir') ) - const itemPaths = await glob(root) + const itemPaths = await glob(root, {followSymbolicLinks: false}) expect(itemPaths).toEqual([ root, path.join(root, 'brokenSym'), @@ -465,7 +453,7 @@ describe('globber', () => { const brokenSymPath = path.join(root, 'brokenSym') await createSymlinkDir(path.join(root, 'noSuch'), brokenSymPath) - const itemPaths = await glob(brokenSymPath) + const itemPaths = await glob(brokenSymPath, {followSymbolicLinks: false}) expect(itemPaths).toEqual([brokenSymPath]) }) @@ -753,13 +741,15 @@ async function createSymlinkDir(real: string, link: string): Promise { } } -async function getSearchPaths(input: string): Promise { - const globber: Globber = await DefaultGlobber.parse(input) +async function getSearchPaths(patterns: string): Promise { + const globber: Globber = await DefaultGlobber.create(patterns) return globber.getSearchPaths() } -async function glob(input: string, options?: GlobOptions): Promise { - const globber: Globber = await DefaultGlobber.parse(input) - globber.options = {...(globber.options || {}), ...(options || {})} +async function glob( + patterns: string, + options?: GlobOptions +): Promise { + const globber: Globber = await DefaultGlobber.create(patterns, options) return await globber.glob() } diff --git a/packages/glob/src/glob.ts b/packages/glob/src/glob.ts index 9bd9f276..02fc9cc1 100644 --- a/packages/glob/src/glob.ts +++ b/packages/glob/src/glob.ts @@ -7,7 +7,11 @@ export {Globber, GlobOptions} * Constructs a globber * * @param patterns Patterns separated by newlines + * @param options Glob options */ -export async function create(patterns: string): Promise { - return await DefaultGlobber.parse(patterns) +export async function create( + patterns: string, + options?: GlobOptions +): Promise { + return await DefaultGlobber.create(patterns, options) } diff --git a/packages/glob/src/internal-glob-options-helper.ts b/packages/glob/src/internal-glob-options-helper.ts index 0848bd38..3c81b671 100644 --- a/packages/glob/src/internal-glob-options-helper.ts +++ b/packages/glob/src/internal-glob-options-helper.ts @@ -6,7 +6,7 @@ import {GlobOptions} from './internal-glob-options' */ export function getOptions(copy?: GlobOptions): GlobOptions { const result: GlobOptions = { - followSymbolicLinks: false, + followSymbolicLinks: true, implicitDescendants: true, omitBrokenSymbolicLinks: true } diff --git a/packages/glob/src/internal-glob-options.ts b/packages/glob/src/internal-glob-options.ts index 6086951e..54d8b544 100644 --- a/packages/glob/src/internal-glob-options.ts +++ b/packages/glob/src/internal-glob-options.ts @@ -3,9 +3,10 @@ */ export interface GlobOptions { /** - * Indicates whether to follow symbolic links + * Indicates whether to follow symbolic links. Generally should set to false + * when deleting files. * - * @default false + * @default true */ followSymbolicLinks?: boolean diff --git a/packages/glob/src/internal-globber.ts b/packages/glob/src/internal-globber.ts index 35615a2f..a84d298d 100644 --- a/packages/glob/src/internal-globber.ts +++ b/packages/glob/src/internal-globber.ts @@ -16,11 +16,6 @@ export {GlobOptions} * Used to match files and directories */ export interface Globber { - /** - * Controls globbing behavior - */ - options: GlobOptions - /** * Returns the search path preceeding the first glob segment, from each pattern. * Duplicates and descendants of other paths are filtered out. @@ -47,11 +42,13 @@ export interface Globber { } export class DefaultGlobber implements Globber { - options: GlobOptions = {} + private readonly options: GlobOptions private readonly patterns: Pattern[] = [] private readonly searchPaths: string[] = [] - private constructor() {} + private constructor(options?: GlobOptions) { + this.options = globOptionsHelper.getOptions(options) + } getSearchPaths(): string[] { // Return a copy @@ -157,35 +154,25 @@ export class DefaultGlobber implements Globber { } /** - * Parses the input options and patterns to construct a new GlobberImpl instance. + * Constructs a DefaultGlobber */ - static async parse(input: string): Promise { - const result = new DefaultGlobber() + static async create( + patterns: string, + options?: GlobOptions + ): Promise { + const result = new DefaultGlobber(options) if (IS_WINDOWS) { - input = input.replace(/\r\n/g, '\n') - input = input.replace(/\r/g, '\n') + patterns = patterns.replace(/\r\n/g, '\n') + patterns = patterns.replace(/\r/g, '\n') } - const lines = input.split('\n').map(x => x.trim()) + const lines = patterns.split('\n').map(x => x.trim()) for (const line of lines) { // Empty or comment if (!line || line.startsWith('#')) { continue } - // Options - else if (line.startsWith('-')) { - const options = line.split(/ +/g) - for (const option of options) { - switch (option) { - case '--follow-symbolic-links': - result.options.followSymbolicLinks = true - break - default: - throw new Error(`Unknown glob options '${option}'`) - } - } - } // Pattern else { result.patterns.push(new Pattern(line))