diff --git a/packages/caching-compiler/caching-compiler.js b/packages/caching-compiler/caching-compiler.js index e29b5ffb15..2149ddcea1 100644 --- a/packages/caching-compiler/caching-compiler.js +++ b/packages/caching-compiler/caching-compiler.js @@ -178,7 +178,7 @@ CachingCompilerBase = class CachingCompilerBase { // doesn't exist. _readFileOrNull(filename) { try { - return fs.readFile(filename, 'utf8'); + return fs.readFileSync(filename, 'utf8'); } catch (e) { if (e && e.code === 'ENOENT') return null; diff --git a/packages/stylus/plugin/compile-stylus.js b/packages/stylus/plugin/compile-stylus.js index cca6c0d47f..f2c22b53c7 100644 --- a/packages/stylus/plugin/compile-stylus.js +++ b/packages/stylus/plugin/compile-stylus.js @@ -110,7 +110,7 @@ class StylusCompiler extends MultiFileCachingCompiler { if (isAbsolute || isNib || isStylusBuiltIn) { // absolute path? let the default implementation handle this - return fs.readFile(filePath, 'utf8'); + return fs.readFileSync(filePath, 'utf8'); } const parsed = parseImportPath(filePath); diff --git a/tools/files.js b/tools/files.js index d7f6a58bd4..a19d95d751 100644 --- a/tools/files.js +++ b/tools/files.js @@ -1303,6 +1303,8 @@ files.readLinkToMeteorScript = function (linkLocation, platform) { // A helpful file to import for this purpose is colon-converter.js, which also // knows how to convert various configuration file formats. + +files.fsFixPath = {}; /** * Wrap a function from node's fs module to use the right slashes for this OS * and run in a fiber, then assign it to the "files" namespace. Each call @@ -1310,6 +1312,9 @@ files.readLinkToMeteorScript = function (linkLocation, platform) { * until the call is done), unless run outside a Fiber or in noYieldsAllowed, in * which case it uses fs.funcSync. * + * Also creates a simpler version on files.fsFixPath.* that just fixes the path + * and fiberizes the Sync version if possible. + * * @param {String} fsFuncName The name of the node fs function to wrap * @param {Number[]} pathArgIndices Indices of arguments that have paths, these * arguments will be converted to the correct OS slashes @@ -1322,46 +1327,72 @@ files.readLinkToMeteorScript = function (linkLocation, platform) { function wrapFsFunc(fsFuncName, pathArgIndices, options) { options = options || {}; - var fsFunc = fs[fsFuncName]; - var fsFuncSync = fs[fsFuncName + "Sync"]; + const fsFunc = fs[fsFuncName]; + const fsFuncSync = fs[fsFuncName + "Sync"]; - function wrapper(...args) { - for (var j = pathArgIndices.length - 1; j >= 0; --j) { - i = pathArgIndices[j]; - args[i] = files.convertToOSPath(args[i]); - } + function makeWrapper ({alwaysSync, sync}) { + function wrapper(...args) { + for (let j = pathArgIndices.length - 1; j >= 0; --j) { + const i = pathArgIndices[j]; + args[i] = files.convertToOSPath(args[i]); + } - if (Fiber.current && - Fiber.yield && ! Fiber.yield.disallowed) { - var fut = new Future; + const canYield = Fiber.current && Fiber.yield && ! Fiber.yield.disallowed; + const shouldBeSync = alwaysSync || sync; - args.push(function callback(err, value) { - if (options.noErr) { - fut.return(err); - } else if (err) { - fut.throw(err); - } else { - fut.return(value); + if (canYield && shouldBeSync) { + const fut = new Future; + + args.push(function callback(err, value) { + if (options.noErr) { + fut.return(err); + } else if (err) { + fut.throw(err); + } else { + fut.return(value); + } + }); + + fsFunc.apply(fs, args); + + const result = fut.wait(); + return options.modifyReturnValue + ? options.modifyReturnValue(result) + : result; + } else if (shouldBeSync) { + // Should be sync but can't yield: we are not in a Fiber. + // Run the sync version of the fs.* method. + const result = fsFuncSync.apply(fs, args); + return options.modifyReturnValue ? + options.modifyReturnValue(result) : result; + } else if (! sync) { + // wrapping a plain async version + const cb = args[fsFunc.length - 1]; + if (typeof cb === 'function') { + args[fsFunc.length - 1] = function (err, res) { + if (options.modifyReturnValue) { + res = options.modifyReturnValue(res); + } + Fiber(cb.bind(null, err, res)).run(); + }; } - }); + fsFunc.apply(fs, args); + return null; + } - fsFunc.apply(fs, args); - - var result = fut.wait(); - return options.modifyReturnValue - ? options.modifyReturnValue(result) - : result; + throw new Error('unexpected'); } - // If we're not in a Fiber, run the sync version of the fs.* method. - var result = fsFuncSync.apply(fs, args); - return options.modifyReturnValue - ? options.modifyReturnValue(result) - : result; + wrapper.displayName = fsFuncName; + return wrapper; } - wrapper.displayName = fsFuncName; - return files[fsFuncName] = Profile("files." + fsFuncName, wrapper); + files[fsFuncName] = Profile('files.' + fsFuncName, makeWrapper({ alwaysSync: true })); + + files.fsFixPath[fsFuncName] = + Profile('wrapped.fs.' + fsFuncName, makeWrapper({ sync: false })); + files.fsFixPath[fsFuncName + 'Sync'] = + Profile('wrapped.fs.' + fsFuncName + 'Sync', makeWrapper({ sync: true })); } wrapFsFunc("writeFile", [0]); diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js index 20f3efb7e1..2cc8089e96 100644 --- a/tools/isobuild/isopack.js +++ b/tools/isobuild/isopack.js @@ -828,7 +828,7 @@ _.extend(Isopack.prototype, { extname: files.pathExtname, sep: files.pathSep }, - fs: files + fs: files.fsFixPath }; return Plugin; }, diff --git a/tools/tests/apps/local-compiler-plugin/packages/local-plugin/plugin.js b/tools/tests/apps/local-compiler-plugin/packages/local-plugin/plugin.js index 9758047a1d..c99795fef3 100644 --- a/tools/tests/apps/local-compiler-plugin/packages/local-plugin/plugin.js +++ b/tools/tests/apps/local-compiler-plugin/packages/local-plugin/plugin.js @@ -25,14 +25,14 @@ PrintmeCompiler.prototype.processFilesForTarget = function (inputFiles) { }); console.log("PrintmeCompiler invocation", ++self.runCount); if (self.diskCache) { - fs.writeFile(self.diskCache, self.runCount + '\n'); + fs.writeFileSync(self.diskCache, self.runCount + '\n'); } }; PrintmeCompiler.prototype.setDiskCacheDirectory = function (diskCacheDir) { var self = this; self.diskCache = path.join(diskCacheDir, 'cache'); try { - var data = fs.readFile(self.diskCache, 'utf8'); + var data = fs.readFileSync(self.diskCache, 'utf8'); } catch (e) { if (e.code !== 'ENOENT') throw e;