From f87c7ffbf2db3a2bc464a55a42e3b543d2e29b07 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 29 Jun 2016 14:44:47 +0200 Subject: [PATCH] Use original-fs instead of manually ignoring ASAR files (fixes #8470) --- src/vs/base/node/extfs.ts | 61 ++----------------- src/vs/base/node/pfs.ts | 16 ++--- src/vs/code/electron-main/windows.ts | 4 +- src/vs/workbench/electron-browser/index.html | 1 + .../electron-browser/snippets.contribution.ts | 3 +- .../electron-browser/snippetsTracker.ts | 2 +- .../services/files/node/fileService.ts | 16 ++--- .../services/search/node/fileSearch.ts | 14 ++--- 8 files changed, 33 insertions(+), 84 deletions(-) diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index fcf464ba6cc..4335c7198d7 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -16,58 +16,7 @@ import paths = require('path'); const loop = flow.loop; -const ASAR_EXT = '.asar'; - -export interface IRawStat { - size: number; - mtime: Date; - atime: Date; - mode: number; - isDirectory(): boolean; - isSymbolicLink(): boolean; - isFile(): boolean; -} - -class FakeAsarStat implements IRawStat { - size = 1024; - mode = 0; - mtime = new Date(0); - atime = new Date(0); - - isDirectory(): boolean { return false; } - isSymbolicLink(): boolean { return false; } - isFile(): boolean { return true; } -} - -export function stat(path: string, callback: (error: Error, stat: IRawStat) => void): void { - if (path && paths.extname(path) === ASAR_EXT) { - return callback(null, new FakeAsarStat()); // https://github.com/Microsoft/vscode/issues/646 - } - - return fs.stat(path, callback); -} - -export function statSync(path: string): IRawStat { - if (path && paths.extname(path) === ASAR_EXT) { - return new FakeAsarStat(); // https://github.com/Microsoft/vscode/issues/646 - } - - return fs.statSync(path); -} - -export function lstat(path: string, callback: (error: Error, stat: IRawStat) => void): void { - if (path && paths.extname(path) === ASAR_EXT) { - return callback(null, new FakeAsarStat()); // https://github.com/Microsoft/vscode/issues/646 - } - - return fs.lstat(path, callback); -} - export function readdir(path: string, callback: (error: Error, files: string[]) => void): void { - if (path && paths.extname(path) === ASAR_EXT) { - return callback(null, []); // https://github.com/Microsoft/vscode/issues/646 - } - // Mac: uses NFD unicode form on disk, but we want NFC // See also https://github.com/nodejs/node/issues/2165 if (platform.isMacintosh) { @@ -133,7 +82,7 @@ export function mkdirp(path: string, mode: number, callback: (error: Error) => v } function isDirectory(path: string, callback: (error: Error, isDirectory?: boolean) => void): void { - stat(path, (error: Error, stat: IRawStat) => { + fs.stat(path, (error, stat) => { if (error) { return callback(error); } callback(null, stat.isDirectory()); @@ -145,7 +94,7 @@ export function copy(source: string, target: string, callback: (error: Error) => copiedSources = Object.create(null); } - stat(source, (error, stat) => { + fs.stat(source, (error, stat) => { if (error) { return callback(error); } if (!stat.isDirectory()) { return pipeFs(source, target, stat.mode & 511, callback); } @@ -209,7 +158,7 @@ export function del(path: string, tmpFolder: string, callback: (error: Error) => return callback(null); } - stat(path, (err, stat) => { + fs.stat(path, (err, stat) => { if (err || !stat) { return callback(err); } @@ -253,7 +202,7 @@ function rmRecursive(path: string, callback: (error: Error) => void): void { if (!exists) { callback(null); } else { - lstat(path, (err, stat) => { + fs.lstat(path, (err, stat) => { if (err || !stat) { callback(err); } else if (!stat.isDirectory() || stat.isSymbolicLink() /* !!! never recurse into links when deleting !!! */) { @@ -312,7 +261,7 @@ export function mv(source: string, target: string, callback: (error: Error) => v return callback(err); } - stat(target, (error: Error, stat: IRawStat) => { + fs.stat(target, (error, stat) => { if (error) { return callback(error); } diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index a5ec3782d32..703b0d9dfcd 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -32,8 +32,8 @@ export function mkdirp(path: string, mode?: number): TPromise { const mkdir = () => nfcall(fs.mkdir, path, mode) .then(null, (err: NodeJS.ErrnoException) => { if (err.code === 'EEXIST') { - return nfcall(extfs.stat, path) - .then((stat: extfs.IRawStat) => stat.isDirectory + return nfcall(fs.stat, path) + .then((stat:fs.Stats) => stat.isDirectory ? null : Promise.wrapError(new Error(`'${ path }' exists and is not a directory.`))); } @@ -76,15 +76,15 @@ export function realpath(path: string): TPromise { return nfcall(fs.realpath, path, null); } -export function stat(path: string): TPromise { - return nfcall(extfs.stat, path); +export function stat(path: string): TPromise { + return nfcall(fs.stat, path); } -export function lstat(path: string): TPromise { - return nfcall(extfs.lstat, path); +export function lstat(path: string): TPromise { + return nfcall(fs.lstat, path); } -export function mstat(paths: string[]): TPromise<{ path: string; stats: extfs.IRawStat; }> { +export function mstat(paths: string[]): TPromise<{ path: string; stats: fs.Stats; }> { return doStatMultiple(paths.slice(0)); } @@ -108,7 +108,7 @@ export function readlink(path: string): TPromise { return nfcall(fs.readlink, path); } -function doStatMultiple(paths: string[]): TPromise<{ path: string; stats: extfs.IRawStat; }> { +function doStatMultiple(paths: string[]): TPromise<{ path: string; stats: fs.Stats; }> { let path = paths.shift(); return stat(path).then((value) => { return { diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index e9a3be925f0..9f11a3a76ed 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -6,13 +6,13 @@ 'use strict'; import * as path from 'path'; +import * as fs from 'fs'; import * as platform from 'vs/base/common/platform'; import * as nls from 'vs/nls'; import * as paths from 'vs/base/common/paths'; import * as arrays from 'vs/base/common/arrays'; import * as objects from 'vs/base/common/objects'; import pkg from 'vs/platform/package'; -import extfs = require('vs/base/node/extfs'); import { EventEmitter } from 'events'; import { IStorageService } from 'vs/code/electron-main/storage'; import { IPath, VSCodeWindow, ReadyState, IWindowConfiguration, IWindowState as ISingleWindowState, defaultWindowState } from 'vs/code/electron-main/window'; @@ -811,7 +811,7 @@ export class WindowsManager implements IWindowsService { let candidate = path.normalize(anyPath); try { - let candidateStat = extfs.statSync(candidate); + let candidateStat = fs.statSync(candidate); if (candidateStat) { return candidateStat.isFile() ? { diff --git a/src/vs/workbench/electron-browser/index.html b/src/vs/workbench/electron-browser/index.html index 7cfd8bcbaec..b9db360e17c 100644 --- a/src/vs/workbench/electron-browser/index.html +++ b/src/vs/workbench/electron-browser/index.html @@ -161,6 +161,7 @@ // In the bundled version the nls plugin is packaged with the loader so the NLS Plugins // loads as soon as the loader loads. To be able to have pseudo translation createScript(rootUrl + '/vs/loader.js', function() { + define('fs', ['original-fs'], function(originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code require.config({ baseUrl: rootUrl, 'vs/nls': nlsConfig, diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts b/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts index ee62f07b867..90b3a756765 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts @@ -14,7 +14,6 @@ import workbenchActionRegistry = require('vs/workbench/common/actionRegistry'); import workbenchContributions = require('vs/workbench/common/contributions'); import snippetsTracker = require('./snippetsTracker'); import errors = require('vs/base/common/errors'); -import extfs = require('vs/base/node/extfs'); import {IQuickOpenService, IPickOpenEntry} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import * as JSONContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; @@ -96,7 +95,7 @@ class OpenSnippetsAction extends actions.Action { function fileExists(path: string): winjs.TPromise { return new winjs.TPromise((c, e, p) => { - extfs.stat(path,(err, stats) => { + fs.stat(path,(err, stats) => { if (err) { return c(false); } diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsTracker.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsTracker.ts index 57f16de7033..1fed7856760 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsTracker.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsTracker.ts @@ -107,7 +107,7 @@ function readDir(path: string): winjs.TPromise { function fileExists(path: string): winjs.TPromise { return new winjs.TPromise((c, e, p) => { - extfs.stat(path,(err, stats) => { + fs.stat(path,(err, stats) => { if (err) { return c(false); } diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 8707eb835fb..27b713b9a7a 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -50,7 +50,7 @@ export interface IFileServiceOptions { debugBrkFileWatcherPort?: number; } -function etag(stat: extfs.IRawStat): string; +function etag(stat: fs.Stats): string; function etag(size: number, mtime: number): string; function etag(arg1: any, arg2?: any): string { let size: number; @@ -59,8 +59,8 @@ function etag(arg1: any, arg2?: any): string { size = arg1; mtime = arg2; } else { - size = (arg1).size; - mtime = (arg1).mtime.getTime(); + size = (arg1).size; + mtime = (arg1).mtime.getTime(); } return '"' + crypto.createHash('sha1').update(String(size) + String(mtime)).digest('hex') + '"'; @@ -424,7 +424,7 @@ export class FileService implements IFileService { private toStatResolver(resource: uri): TPromise { let absolutePath = this.toAbsolutePath(resource); - return pfs.stat(absolutePath).then((stat: extfs.IRawStat) => { + return pfs.stat(absolutePath).then((stat: fs.Stats) => { return new StatResolver(resource, stat.isDirectory(), stat.mtime.getTime(), stat.size, this.options.verboseLogging); }); } @@ -528,7 +528,7 @@ export class FileService implements IFileService { private checkFile(absolutePath: string, options: IUpdateContentOptions): TPromise { return pfs.exists(absolutePath).then((exists) => { if (exists) { - return pfs.stat(absolutePath).then((stat: extfs.IRawStat) => { + return pfs.stat(absolutePath).then((stat: fs.Stats) => { if (stat.isDirectory()) { return TPromise.wrapError(new Error('Expected file is actually a directory')); } @@ -723,7 +723,7 @@ export class StatResolver { // for each file in the folder flow.parallel(files, (file: string, clb: (error: Error, children: IFileStat) => void) => { let fileResource = uri.file(paths.resolve(absolutePath, file)); - let fileStat: extfs.IRawStat; + let fileStat: fs.Stats; let $this = this; flow.sequence( @@ -736,10 +736,10 @@ export class StatResolver { }, function stat(): void { - extfs.stat(fileResource.fsPath, this); + fs.stat(fileResource.fsPath, this); }, - function countChildren(fsstat: extfs.IRawStat): void { + function countChildren(fsstat: fs.Stats): void { fileStat = fsstat; if (fileStat.isDirectory()) { diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index 380a808f726..7aa330a5c7c 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -116,7 +116,7 @@ export class FileWalker { return clb(false); } - return extfs.stat(this.filePattern, (error, stat) => { + return fs.stat(this.filePattern, (error, stat) => { return clb(!error && !stat.isDirectory(), stat && stat.size); // only existing files }); } @@ -128,7 +128,7 @@ export class FileWalker { const absolutePath = paths.join(basePath, this.filePattern); - return extfs.stat(absolutePath, (error, stat) => { + return fs.stat(absolutePath, (error, stat) => { return clb(!error && !stat.isDirectory() ? absolutePath : null, stat && stat.size); // only existing files }); } @@ -159,12 +159,12 @@ export class FileWalker { // Use lstat to detect links let currentAbsolutePath = [absolutePath, file].join(paths.sep); - extfs.lstat(currentAbsolutePath, (error, lstat) => { + fs.lstat(currentAbsolutePath, (error, lstat) => { if (error || this.isCanceled || this.isLimitHit) { return clb(null); } - // If the path is a link, we must instead use extfs.stat() to find out if the + // If the path is a link, we must instead use fs.stat() to find out if the // link is a directory or not because lstat will always return the stat of // the link which is always a file. this.statLinkIfNeeded(currentAbsolutePath, lstat, (error, stat) => { @@ -255,15 +255,15 @@ export class FileWalker { return true; } - private statLinkIfNeeded(path: string, lstat: extfs.IRawStat, clb: (error: Error, stat: extfs.IRawStat) => void): void { + private statLinkIfNeeded(path: string, lstat: fs.Stats, clb: (error: Error, stat: fs.Stats) => void): void { if (lstat.isSymbolicLink()) { - return extfs.stat(path, clb); // stat the target the link points to + return fs.stat(path, clb); // stat the target the link points to } return clb(null, lstat); // not a link, so the stat is already ok for us } - private realPathIfNeeded(path: string, lstat: extfs.IRawStat, clb: (error: Error, realpath?: string) => void): void { + private realPathIfNeeded(path: string, lstat: fs.Stats, clb: (error: Error, realpath?: string) => void): void { if (lstat.isSymbolicLink()) { return fs.realpath(path, (error, realpath) => { if (error) {