Skip to content

Commit 0fd9817

Browse files
committed
Deal with case {in,over}sensitivity
1 parent 74e053a commit 0fd9817

File tree

4 files changed

+30
-42
lines changed

4 files changed

+30
-42
lines changed

blueprints/ember-cli-typescript/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = {
4040
}
4141

4242
return {
43-
includes: JSON.stringify(includes, null, 2).replace(/\n/g, '\n '),
43+
includes: JSON.stringify(includes.map(include => `${include}/**/*`), null, 2).replace(/\n/g, '\n '),
4444
pathsFor: dasherizedName => {
4545
let appName = isAddon ? 'dummy' : dasherizedName;
4646
let paths = {

lib/utilities/compile.js

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const chokidar = require('chokidar');
55
const fs = require('fs-extra');
66
const escapeRegex = require('escape-string-regexp');
77
const path = require('path');
8+
const glob = require('glob');
89

910
const trace = require('debug')('ember-cli-typescript:tsc:trace');
1011
const debug = require('debug')('ember-cli-typescript:watcher');
@@ -69,65 +70,51 @@ function diagnosticCallback(callback) {
6970

7071
function buildWatchHooks(project, ts, callbacks) {
7172
let ignorePatterns = ['\\..*?', 'dist', 'tmp', 'node_modules'];
72-
let watchedFiles = new Map();
7373

7474
return Object.assign({}, ts.sys, {
75-
watchFile(file, callback) {
76-
let key = path.resolve(file);
77-
if (!watchedFiles.has(key)) {
78-
debug(`watching file %s`, key);
79-
watchedFiles.set(key, []);
80-
}
81-
82-
watchedFiles.get(key).push(callback);
83-
84-
return {
85-
close() {
86-
let callbacks = watchedFiles.get(key);
87-
if (callbacks.length === 1) {
88-
debug(`unwatching file %s`, key);
89-
watchedFiles.delete(key);
90-
} else {
91-
callbacks.splice(callbacks.indexOf(callback), 1);
92-
}
93-
}
94-
};
95-
},
96-
97-
watchDirectory(dir, callback) {
98-
if (!fs.existsSync(dir)) {
99-
debug(`skipping watch for nonexistent directory %s`, dir);
75+
watchFile: null,
76+
watchDirectory(rawDir, callback) {
77+
if (!fs.existsSync(rawDir)) {
78+
debug(`skipping watch for nonexistent directory %s`, rawDir);
10079
return;
10180
}
10281

82+
let dir = getCanonicalCapitalization(path.resolve(rawDir));
10383
let ignored = buildIgnoreRegex(dir, ignorePatterns);
10484
let watcher = chokidar.watch(dir, { ignored, ignoreInitial: true });
10585
debug(`watching directory %s %o`, dir, { ignored });
10686

10787
watcher.on('all', (type, rawPath) => {
10888
let resolvedPath = path.resolve(rawPath);
10989

110-
if (watchedFiles.has(resolvedPath) && (type === 'change' || type === 'unlink')) {
111-
debug(`%s: watched path %s`, type, resolvedPath);
112-
let kind = type === 'change' ? ts.FileWatcherEventKind.Changed : ts.FileWatcherEventKind.Deleted;
113-
watchedFiles.get(resolvedPath).forEach(callback => callback(resolvedPath, kind));
114-
} else {
115-
debug(`%s: unwatched path %s (for directory watch on %s)`, type, resolvedPath, dir);
116-
callback(resolvedPath);
117-
}
90+
debug(`%s: %s (for directory watch on %s)`, type, resolvedPath, dir);
91+
callback(resolvedPath);
11892

11993
if (resolvedPath.endsWith('.ts') && callbacks.watchedFileChanged) {
12094
callbacks.watchedFileChanged();
12195
}
12296
});
12397

124-
return watcher;
98+
return {
99+
close() {
100+
debug('closing watcher for %s', dir);
101+
watcher.close();
102+
}
103+
};
125104
}
126105
});
127106
}
128107

129108
function buildIgnoreRegex(rootDir, patterns) {
130109
let base = escapeRegex(rootDir);
131110
let sep = `[/\\\\]`;
132-
return new RegExp(`^${base}${sep}(${patterns.join('|')})${sep}`);
111+
return new RegExp(`^${base}${sep}(${patterns.join('|')})${sep}`, 'i');
112+
}
113+
114+
// On case-insensitive file systems, tsc will normalize paths to be all lowercase,
115+
// but chokidar expects the paths it's given to watch to exactly match what it's
116+
// delivered in fs events.
117+
function getCanonicalCapitalization(rawPath) {
118+
let normalized = rawPath.replace(/\\/g, '/').replace(/^[a-z]:/i, '');
119+
return glob.sync(normalized, { nocase: true })[0];
133120
}

node-tests/blueprints/ember-cli-typescript-test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('Acceptance: ember-cli-typescript generator', function() {
7171
expect(tsconfigJson.compilerOptions.inlineSourceMap).to.equal(true);
7272
expect(tsconfigJson.compilerOptions.inlineSources).to.equal(true);
7373

74-
expect(tsconfigJson.include).to.deep.equal(['app', 'tests', 'types']);
74+
expect(tsconfigJson.include).to.deep.equal(['app/**/*', 'tests/**/*', 'types/**/*']);
7575

7676
const projectTypes = file('types/my-app/index.d.ts');
7777
expect(projectTypes).to.exist;
@@ -116,7 +116,7 @@ describe('Acceptance: ember-cli-typescript generator', function() {
116116
'*': ['types/*'],
117117
});
118118

119-
expect(tsconfigJson.include).to.deep.equal(['app', 'addon', 'tests', 'types']);
119+
expect(tsconfigJson.include).to.deep.equal(['app/**/*', 'addon/**/*', 'tests/**/*', 'types/**/*']);
120120

121121
const projectTypes = file('types/dummy/index.d.ts');
122122
expect(projectTypes).to.exist;
@@ -159,7 +159,7 @@ describe('Acceptance: ember-cli-typescript generator', function() {
159159
'*': ['types/*'],
160160
});
161161

162-
expect(json.include).to.deep.equal(['app', 'tests', 'types', 'lib/my-addon-1', 'lib/my-addon-2']);
162+
expect(json.include).to.deep.equal(['app/**/*', 'tests/**/*', 'types/**/*', 'lib/my-addon-1/**/*', 'lib/my-addon-2/**/*']);
163163

164164
const projectTypes = file('types/my-app/index.d.ts');
165165
expect(projectTypes).to.exist;
@@ -194,7 +194,7 @@ describe('Acceptance: ember-cli-typescript generator', function() {
194194
'*': ['types/*'],
195195
});
196196

197-
expect(json.include).to.deep.equal(['app', 'tests', 'types', 'mirage']);
197+
expect(json.include).to.deep.equal(['app/**/*', 'tests/**/*', 'types/**/*', 'mirage/**/*']);
198198
});
199199
});
200200

@@ -224,7 +224,7 @@ describe('Acceptance: ember-cli-typescript generator', function() {
224224
'*': ['types/*'],
225225
});
226226

227-
expect(json.include).to.deep.equal(['app', 'addon', 'tests', 'types']);
227+
expect(json.include).to.deep.equal(['app/**/*', 'addon/**/*', 'tests/**/*', 'types/**/*']);
228228
});
229229
});
230230

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"execa": "^0.9.0",
5454
"exists-sync": "^0.0.4",
5555
"fs-extra": "^5.0.0",
56+
"glob": "^7.1.2",
5657
"inflection": "^1.12.0",
5758
"resolve": "^1.5.0",
5859
"rimraf": "^2.6.2",

0 commit comments

Comments
 (0)