Use original-fs instead of manually ignoring ASAR files (fixes #8470)

This commit is contained in:
Benjamin Pasero
2016-06-29 14:44:47 +02:00
parent 2d5c834dec
commit f87c7ffbf2
8 changed files with 33 additions and 84 deletions

View File

@@ -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);
}

View File

@@ -32,8 +32,8 @@ export function mkdirp(path: string, mode?: number): TPromise<boolean> {
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<string> {
return nfcall(fs.realpath, path, null);
}
export function stat(path: string): TPromise<extfs.IRawStat> {
return nfcall(extfs.stat, path);
export function stat(path: string): TPromise<fs.Stats> {
return nfcall(fs.stat, path);
}
export function lstat(path: string): TPromise<extfs.IRawStat> {
return nfcall(extfs.lstat, path);
export function lstat(path: string): TPromise<fs.Stats> {
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<string> {
return nfcall<string>(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 {

View File

@@ -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() ?
{

View File

@@ -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,

View File

@@ -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<boolean> {
return new winjs.TPromise<boolean>((c, e, p) => {
extfs.stat(path,(err, stats) => {
fs.stat(path,(err, stats) => {
if (err) {
return c(false);
}

View File

@@ -107,7 +107,7 @@ function readDir(path: string): winjs.TPromise<string[]> {
function fileExists(path: string): winjs.TPromise<boolean> {
return new winjs.TPromise<boolean>((c, e, p) => {
extfs.stat(path,(err, stats) => {
fs.stat(path,(err, stats) => {
if (err) {
return c(false);
}

View File

@@ -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 = (<extfs.IRawStat>arg1).size;
mtime = (<extfs.IRawStat>arg1).mtime.getTime();
size = (<fs.Stats>arg1).size;
mtime = (<fs.Stats>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<StatResolver> {
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<boolean /* exists */> {
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()) {

View File

@@ -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) {