Skip to content

Commit b73abed

Browse files
committed
Merge pull request #649 from blakeembrey/improve-glob-implementation
Move to using `glob` library (optimised globbing)
2 parents c86d5fc + bebc773 commit b73abed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1016
-33305
lines changed

VSProj.njsproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<Folder Include="lib\typings\" />
4040
<Folder Include="lib\typings\atom\" />
4141
<Folder Include="lib\typings\emissary\" />
42-
<Folder Include="lib\typings\glob-expand\" />
42+
<Folder Include="lib\typings\glob\" />
4343
<Folder Include="lib\typings\jquery\" />
4444
<Folder Include="lib\typings\mixto\" />
4545
<Folder Include="lib\typings\mkdirp\" />
@@ -93,4 +93,4 @@
9393
</FlavorProperties>
9494
</VisualStudio>
9595
</ProjectExtensions>
96-
</Project>
96+
</Project>

dist/main/lang/transformers/transformerRegistry.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ function transform(name, code) {
3939
return transformer.transform(code);
4040
}
4141
exports.transform = transform;
42-
var expand = require('glob-expand');
43-
var files = expand({ filter: 'isFile', cwd: __dirname }, [
44-
"./implementations/*.js"
45-
]);
42+
var glob = require('glob');
43+
var files = glob.sync('./implementations/*.js', {
44+
nodir: true,
45+
cwd: __dirname
46+
});
4647
files = files.map(function (f) { return require(f); });

dist/main/tsconfig/tsconfig.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ function errorWithDetails(error, details) {
6262
}
6363
var fs = require('fs');
6464
var path = require('path');
65-
var expand = require('glob-expand');
65+
var glob = require('glob');
6666
var os = require('os');
6767
var formatting = require('./formatting');
6868
var projectFileName = 'tsconfig.json';
@@ -71,7 +71,7 @@ var defaultFilesGlob = [
7171
"**/*.tsx",
7272
"!node_modules/**",
7373
];
74-
var invisibleFilesGlob = ["**/*.ts", "**/*.tsx"];
74+
var invisibleFilesGlob = '{**/*.ts,**/*.tsx}';
7575
exports.defaults = {
7676
target: ts.ScriptTarget.ES5,
7777
module: ts.ModuleKind.CommonJS,
@@ -214,18 +214,21 @@ function getProjectSync(pathOrSrcFile) {
214214
if (!projectSpec.compilerOptions)
215215
projectSpec.compilerOptions = {};
216216
var cwdPath = path.relative(process.cwd(), path.dirname(projectFile));
217-
if (!projectSpec.files && !projectSpec.filesGlob) {
218-
var toExpand = invisibleFilesGlob;
219-
if (projectSpec.exclude) {
220-
toExpand = toExpand.concat(projectSpec.exclude.map(function (exclude) { return ("!" + exclude + "/**"); }));
221-
}
217+
var filesGlob = invisibleFilesGlob;
218+
var ignore = [];
219+
if (Array.isArray(projectSpec.filesGlob)) {
220+
filesGlob = projectSpec.filesGlob.length === 1 ? projectSpec.filesGlob[0] : "{" + projectSpec.filesGlob.join(',') + "}";
222221
}
223-
if (projectSpec.filesGlob) {
224-
var toExpand = projectSpec.filesGlob;
222+
else if (projectSpec.exclude) {
223+
ignore = projectSpec.exclude.map(function (path) { return (path + "/**"); });
225224
}
226-
if (toExpand) {
225+
if (filesGlob) {
227226
try {
228-
projectSpec.files = expand({ filter: 'isFile', cwd: cwdPath }, toExpand);
227+
projectSpec.files = glob.sync(filesGlob, {
228+
cwd: cwdPath,
229+
ignore: ignore,
230+
nodir: true
231+
});
229232
}
230233
catch (ex) {
231234
throw errorWithDetails(new Error(exports.errors.GET_PROJECT_GLOB_EXPAND_FAILED), { glob: projectSpec.filesGlob, projectFilePath: fsu.consistentPath(projectFile), errorMessage: ex.message });

lib/main/lang/transformers/transformerRegistry.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import utils = require("../utils");
22
import {Transformer, TransformerDelimiter, FileTransformationDetails} from "./transformer";
33

44
/**
5-
* Transformers should push themeselves into this registry.
5+
* Transformers should push themeselves into this registry.
66
* This is so that the registry does not depend on the transformers
77
* As that will cause a circular reference
88
*/
@@ -37,18 +37,18 @@ export function getInitialTransformation(code: string): FileTransformationDetail
3737

3838
while (true) {
3939
let remainingCode = code.substr(processedSrcUpto);
40-
// Get the next transform that exist in this file:
40+
// Get the next transform that exist in this file:
4141
var matches = transformFinderRegex.exec(remainingCode);
4242
// No more transforms:
4343
if (!matches || !matches.length || matches.length < 2) return { transforms };
4444
// Found one!
4545
var nextTransformName = matches.slice[1];
4646
// Update the processedUpto
4747
}
48-
48+
4949
/**
5050
* TODO: for each transform we note down the src start and src end
51-
* Then we transform the src code. This gives a dest start (initially same as src start) and dest end (more or less)
51+
* Then we transform the src code. This gives a dest start (initially same as src start) and dest end (more or less)
5252
* we use this to additionally compute a running (delta) in dest. This delta is used in the next (dest start).
5353
*/
5454

@@ -67,12 +67,13 @@ export function transform(name: string, code: string): { code: string } {
6767
return transformer.transform(code);
6868
}
6969

70-
// Ensure that all the transformers are loaded:
70+
// Ensure that all the transformers are loaded:
7171
// Since nothing depends on these explicitly (don't want a circular ref)
7272
// We need to load them manually:
7373
import * as path from "path";
74-
var expand = require('glob-expand');
75-
let files: string[] = expand({ filter: 'isFile', cwd: __dirname }, [
76-
"./implementations/*.js"
77-
]);
78-
files = files.map(f=> require(f));
74+
var glob = require('glob');
75+
let files: string[] = glob.sync('./implementations/*.js', {
76+
nodir: true,
77+
cwd: __dirname
78+
});
79+
files = files.map(f=> require(f));

lib/main/tsconfig/tsconfig.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ function errorWithDetails<T>(error: Error, details: T): Error {
196196

197197
import fs = require('fs');
198198
import path = require('path');
199-
import expand = require('glob-expand');
199+
import glob = require('glob');
200200
import os = require('os');
201201
import formatting = require('./formatting');
202202

@@ -212,7 +212,7 @@ var defaultFilesGlob = [
212212
/**
213213
* This is what we use when the user doens't specify a files / filesGlob
214214
*/
215-
var invisibleFilesGlob = ["**/*.ts", "**/*.tsx"];
215+
var invisibleFilesGlob = '{**/*.ts,**/*.tsx}';
216216

217217
export var defaults: ts.CompilerOptions = {
218218
target: ts.ScriptTarget.ES5,
@@ -390,18 +390,22 @@ export function getProjectSync(pathOrSrcFile: string): TypeScriptProjectFileDeta
390390
// Our customizations for "tsconfig.json"
391391
// Use grunt.file.expand type of logic
392392
var cwdPath = path.relative(process.cwd(), path.dirname(projectFile));
393-
if (!projectSpec.files && !projectSpec.filesGlob) { // If there is no files and no filesGlob, we create an invisible one.
394-
var toExpand = invisibleFilesGlob;
395-
if(projectSpec.exclude){
396-
toExpand = toExpand.concat(projectSpec.exclude.map((exclude) => `!${exclude}/**`));
397-
}
398-
}
399-
if (projectSpec.filesGlob) { // If there is a files glob we will use that
400-
var toExpand = projectSpec.filesGlob
393+
var filesGlob = invisibleFilesGlob;
394+
var ignore = [];
395+
396+
if (Array.isArray(projectSpec.filesGlob)) {
397+
filesGlob = projectSpec.filesGlob.length === 1 ? projectSpec.filesGlob[0] : `{${projectSpec.filesGlob.join(',')}}`;
398+
} else if (projectSpec.exclude) {
399+
ignore = projectSpec.exclude.map(path => `${path}/**`)
401400
}
402-
if (toExpand) { // Expand whatever needs expanding
401+
402+
if (filesGlob) { // Expand whatever needs expanding
403403
try {
404-
projectSpec.files = expand({ filter: 'isFile', cwd: cwdPath }, toExpand);
404+
projectSpec.files = glob.sync(filesGlob, {
405+
cwd: cwdPath,
406+
ignore: ignore,
407+
nodir: true
408+
});
405409
}
406410
catch (ex) {
407411
throw errorWithDetails<GET_PROJECT_GLOB_EXPAND_FAILED_Details>(

lib/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@
105105
"./typings/codemirror.d.ts",
106106
"./typings/d3/d3.d.ts",
107107
"./typings/emissary/emissary.d.ts",
108-
"./typings/glob-expand/glob-expand.d.ts",
108+
"./typings/glob/glob.d.ts",
109109
"./typings/htmltojsx/htmltojsx.d.ts",
110110
"./typings/jquery/jquery.d.ts",
111111
"./typings/minimatch.d.ts",
112+
"./typings/minimatch/minimatch.d.ts",
112113
"./typings/mixto/mixto.d.ts",
113114
"./typings/mkdirp/mkdirp.d.ts",
114115
"./typings/mustache.d.ts",

lib/tsd.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874"
3131
},
3232
"node/node.d.ts": {
33-
"commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874"
33+
"commit": "66f88ec51858bb21bc375fa91a963c04bc09401e"
3434
},
3535
"q/Q.d.ts": {
3636
"commit": "69bdfb0884020e41f17a1dd80ad4c77de2636874"
@@ -52,6 +52,12 @@
5252
},
5353
"htmltojsx/htmltojsx.d.ts": {
5454
"commit": "1632606f82cfbaf89d4b96b8dccacfaf2a6ae2f3"
55+
},
56+
"glob/glob.d.ts": {
57+
"commit": "66f88ec51858bb21bc375fa91a963c04bc09401e"
58+
},
59+
"minimatch/minimatch.d.ts": {
60+
"commit": "66f88ec51858bb21bc375fa91a963c04bc09401e"
5561
}
5662
}
5763
}

lib/typings/glob-expand/glob-expand.d.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

lib/typings/glob/glob.d.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Type definitions for Glob 5.0.10
2+
// Project: https://github.com/isaacs/node-glob
3+
// Definitions by: vvakame <https://github.com/vvakame/>
4+
// Definitions: https://github.com/borisyankov/DefinitelyTyped
5+
6+
/// <reference path="../node/node.d.ts" />
7+
/// <reference path="../minimatch/minimatch.d.ts" />
8+
9+
declare module "glob" {
10+
11+
import events = require("events");
12+
import fs = require('fs');
13+
import minimatch = require("minimatch");
14+
15+
function G(pattern: string, cb: (err: Error, matches: string[]) => void): void;
16+
function G(pattern: string, options: G.IOptions, cb: (err: Error, matches: string[]) => void): void;
17+
18+
module G {
19+
function sync(pattern: string, options?: IOptions): string[];
20+
21+
function hasMagic(pattern: string, options?: IOptions): boolean;
22+
23+
var Glob: IGlobStatic;
24+
var GlobSync: IGlobSyncStatic;
25+
26+
interface IOptions extends minimatch.IOptions {
27+
cwd?: string;
28+
root?: string;
29+
dot?: boolean;
30+
nomount?: boolean;
31+
mark?: boolean;
32+
nosort?: boolean;
33+
stat?: boolean;
34+
silent?: boolean;
35+
strict?: boolean;
36+
cache?: { [path: string]: any /* boolean | string | string[] */ };
37+
statCache?: { [path: string]: fs.Stats };
38+
symlinks?: any;
39+
sync?: boolean;
40+
nounique?: boolean;
41+
nonull?: boolean;
42+
debug?: boolean;
43+
nobrace?: boolean;
44+
noglobstar?: boolean;
45+
noext?: boolean;
46+
nocase?: boolean;
47+
matchBase?: any;
48+
nodir?: boolean;
49+
ignore?: any; /* string | string[] */
50+
follow?: boolean;
51+
realpath?: boolean;
52+
nonegate?: boolean;
53+
nocomment?: boolean;
54+
55+
/** Deprecated. */
56+
globDebug?: boolean;
57+
}
58+
59+
interface IGlobStatic extends events.EventEmitter {
60+
new (pattern: string, cb?: (err: Error, matches: string[]) => void): IGlob;
61+
new (pattern: string, options: IOptions, cb?: (err: Error, matches: string[]) => void): IGlob;
62+
prototype: IGlob;
63+
}
64+
65+
interface IGlobSyncStatic {
66+
new (pattern: string, options?: IOptions): IGlobBase
67+
prototype: IGlobBase;
68+
}
69+
70+
interface IGlobBase {
71+
minimatch: minimatch.IMinimatch;
72+
options: IOptions;
73+
aborted: boolean;
74+
cache: { [path: string]: any /* boolean | string | string[] */ };
75+
statCache: { [path: string]: fs.Stats };
76+
symlinks: { [path: string]: boolean };
77+
realpathCache: { [path: string]: string };
78+
found: string[];
79+
}
80+
81+
interface IGlob extends IGlobBase, events.EventEmitter {
82+
pause(): void;
83+
resume(): void;
84+
abort(): void;
85+
86+
/** Deprecated. */
87+
EOF: any;
88+
/** Deprecated. */
89+
paused: boolean;
90+
/** Deprecated. */
91+
maxDepth: number;
92+
/** Deprecated. */
93+
maxLength: number;
94+
/** Deprecated. */
95+
changedCwd: boolean;
96+
/** Deprecated. */
97+
cwd: string;
98+
/** Deprecated. */
99+
root: string;
100+
/** Deprecated. */
101+
error: any;
102+
/** Deprecated. */
103+
matches: string[];
104+
/** Deprecated. */
105+
log(...args: any[]): void;
106+
/** Deprecated. */
107+
emitMatch(m: any): void;
108+
}
109+
}
110+
111+
export = G;
112+
}

lib/typings/minimatch/minimatch.d.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Type definitions for Minimatch 2.0.8
2+
// Project: https://github.com/isaacs/minimatch
3+
// Definitions by: vvakame <https://github.com/vvakame/>
4+
// Definitions: https://github.com/borisyankov/DefinitelyTyped
5+
6+
declare module "minimatch" {
7+
8+
function M(target: string, pattern: string, options?: M.IOptions): boolean;
9+
10+
module M {
11+
function match(list: string[], pattern: string, options?: IOptions): string[];
12+
function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean;
13+
function makeRe(pattern: string, options?: IOptions): RegExp;
14+
15+
var Minimatch: IMinimatchStatic;
16+
17+
interface IOptions {
18+
debug?: boolean;
19+
nobrace?: boolean;
20+
noglobstar?: boolean;
21+
dot?: boolean;
22+
noext?: boolean;
23+
nocase?: boolean;
24+
nonull?: boolean;
25+
matchBase?: boolean;
26+
nocomment?: boolean;
27+
nonegate?: boolean;
28+
flipNegate?: boolean;
29+
}
30+
31+
interface IMinimatchStatic {
32+
new (pattern: string, options?: IOptions): IMinimatch;
33+
prototype: IMinimatch;
34+
}
35+
36+
interface IMinimatch {
37+
pattern: string;
38+
options: IOptions;
39+
/** 2-dimensional array of regexp or string expressions. */
40+
set: any[][]; // (RegExp | string)[][]
41+
regexp: RegExp;
42+
negate: boolean;
43+
comment: boolean;
44+
empty: boolean;
45+
46+
makeRe(): RegExp; // regexp or boolean
47+
match(fname: string): boolean;
48+
matchOne(files: string[], pattern: string[], partial: boolean): boolean;
49+
50+
/** Deprecated. For internal use. */
51+
debug(): void;
52+
/** Deprecated. For internal use. */
53+
make(): void;
54+
/** Deprecated. For internal use. */
55+
parseNegate(): void;
56+
/** Deprecated. For internal use. */
57+
braceExpand(pattern: string, options: IOptions): void;
58+
/** Deprecated. For internal use. */
59+
parse(pattern: string, isSub?: boolean): void;
60+
}
61+
}
62+
63+
export = M;
64+
}

0 commit comments

Comments
 (0)