Skip to content

Commit cb794f2

Browse files
committed
Followed symlinks
1 parent a574058 commit cb794f2

File tree

3 files changed

+76
-26
lines changed

3 files changed

+76
-26
lines changed

lib/Host.js

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33
var commondir = require('commondir');
44
var events = require('events');
55
var fs = require('fs');
6+
var realpath = require('fs.realpath')
67
var log = require('util').debuglog(require('../package').name);
78
var os = require('os');
89
var path = require('path');
910
var util = require('util');
1011

1112
module.exports = function (ts) {
12-
function replaceFileExtension(file, extension) {
13-
return file.replace(/\.\w+$/i, extension);
14-
}
15-
1613
function Host(currentDirectory, outputDirectory, languageVersion) {
1714
this.currentDirectory = this.getCanonicalFileName(path.resolve(currentDirectory));
1815
this.outputDirectory = this.getCanonicalFileName(path.resolve(outputDirectory));
@@ -49,7 +46,7 @@ module.exports = function (ts) {
4946
filename
5047
)
5148
));
52-
var canonical = this._currentCanonical(filename);
49+
var canonical = this._toCurrentCanonical(filename);
5350
log('Parsing %s', canonical);
5451

5552
var text;
@@ -94,7 +91,7 @@ module.exports = function (ts) {
9491
if (filename === '__lib.d.ts') {
9592
return this.libDefault;
9693
}
97-
var canonical = this._currentCanonical(filename);
94+
var canonical = this._toCurrentCanonical(filename);
9895
if (this.files[canonical]) {
9996
return this.files[canonical].ts;
10097
}
@@ -108,9 +105,19 @@ module.exports = function (ts) {
108105
};
109106

110107
Host.prototype.writeFile = function (filename, data) {
111-
var canonical = this._currentCanonical(filename);
112-
log('Cache write %s', canonical);
113-
this.output[canonical] = data;
108+
109+
var outputCanonical = this._toCurrentCanonical(filename);
110+
log('Cache write %s', outputCanonical);
111+
this.output[outputCanonical] = data;
112+
113+
var sourceCanonical = this._toSourceCanonical(outputCanonical);
114+
var sourceFollowed = this._follow(path.dirname(sourceCanonical)) + '/' + path.basename(sourceCanonical);
115+
116+
if (sourceFollowed !== sourceCanonical) {
117+
outputCanonical = this._toOutputCanonical(sourceFollowed);
118+
log('Cache write (followed) %s', outputCanonical);
119+
this.output[outputCanonical] = data;
120+
}
114121
};
115122

116123
Host.prototype.getCurrentDirectory = function () {
@@ -138,13 +145,6 @@ module.exports = function (ts) {
138145
return ts.sys.readFile(filename);
139146
};
140147

141-
Host.prototype._currentCanonical = function (filename) {
142-
return this.getCanonicalFileName(path.resolve(
143-
this.currentDirectory,
144-
filename
145-
));
146-
}
147-
148148
Host.prototype._rootDir = function () {
149149
var dirs = [];
150150
for (var filename in this.files) {
@@ -169,25 +169,70 @@ module.exports = function (ts) {
169169
return rootFilenames;
170170
}
171171

172-
Host.prototype._output = function (filename, extension) {
172+
Host.prototype._output = function (filename) {
173+
174+
var outputCanonical = this._toOutputCanonical(filename);
175+
log('Cache read %s', outputCanonical);
176+
177+
var output = this.output[outputCanonical];
178+
if (!output) {
179+
log('Cache miss on %s', outputCanonical);
180+
}
181+
return output;
182+
}
183+
184+
Host.prototype._toCurrentCanonical = function (filename) {
185+
return this.getCanonicalFileName(path.resolve(
186+
this.currentDirectory,
187+
filename
188+
));
189+
}
190+
191+
Host.prototype._toOutputCanonical = function (filename) {
173192

174-
var inputCanonical = this._currentCanonical(filename);
193+
var sourceCanonical = this._toCurrentCanonical(filename);
175194
var outputRelative = path.relative(
176195
this._rootDir(),
177-
replaceFileExtension(inputCanonical, extension)
196+
sourceCanonical
178197
);
179198
var outputCanonical = this.getCanonicalFileName(path.resolve(
180199
this.outputDirectory,
181200
outputRelative
182201
));
183-
log('Cache read %s', outputCanonical);
202+
return outputCanonical;
203+
}
184204

185-
var output = this.output[outputCanonical];
186-
if (!output) {
187-
log('Cache miss on %s', outputCanonical);
188-
}
189-
return output;
205+
Host.prototype._toSourceCanonical = function (filename) {
206+
207+
var outputCanonical = this._toCurrentCanonical(filename);
208+
var outputRelative = path.relative(
209+
this.outputDirectory,
210+
outputCanonical
211+
);
212+
var sourceCanonical = this.getCanonicalFileName(path.resolve(
213+
this._rootDir(),
214+
outputRelative
215+
));
216+
return sourceCanonical;
190217
}
191218

219+
Host.prototype._follow = function (filename) {
220+
221+
filename = this._toCurrentCanonical(filename);
222+
var parts = [];
223+
224+
while (!/^(\/|\w:\/|\w:\\)$/i.test(filename)) {
225+
226+
var stats = fs.lstatSync(filename);
227+
if (stats.isSymbolicLink()) {
228+
filename = realpath.realpathSync(filename);
229+
} else {
230+
parts.unshift(path.basename(filename));
231+
filename = path.dirname(filename);
232+
}
233+
}
234+
return ts.normalizeSlashes(filename + parts.join('/'));
235+
};
236+
192237
return Host;
193238
};

lib/Tsifier.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ module.exports = function (ts) {
3434
return (/\.d\.ts$/i).test(file);
3535
}
3636

37+
function replaceFileExtension(file, extension) {
38+
return file.replace(/\.\w+$/i, extension);
39+
}
40+
3741
function fileExists(file) {
3842
try {
3943
var stats = fs.lstatSync(file);
@@ -274,7 +278,7 @@ module.exports = function (ts) {
274278
Tsifier.prototype.getCompiledFile = function (inputFile, alreadyMissedCache) {
275279
var self = this;
276280
var outputExtension = (self.opts.jsx === ts.JsxEmit.Preserve && isTsx(inputFile)) ? '.jsx' : '.js';
277-
var output = self.host._output(inputFile, outputExtension);
281+
var output = self.host._output(replaceFileExtension(inputFile, outputExtension));
278282

279283
if (!output) {
280284
if (alreadyMissedCache)

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"eslint": "^2.7.0",
4040
"event-stream": "^3.3.1",
4141
"fs-extra": "^0.28.0",
42+
"fs.realpath": "^1.0.0",
4243
"node-foo": "^0.2.3",
4344
"semver": "^5.1.0",
4445
"source-map": "^0.5.3",

0 commit comments

Comments
 (0)