diff --git a/.vscode/launch.json b/.vscode/launch.json index 394d6235..8d3636d2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,11 +7,13 @@ "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}"], + "args": [ + "--disable-extensions", + "--extensionDevelopmentPath=${workspaceRoot}" + ], "stopOnEntry": false, "sourceMaps": true, "outFiles": ["${workspaceRoot}/out/**/*.js"], - "preLaunchTask": "build" }, { "name": "Launch Tests", diff --git a/src/model.ts b/src/model.ts index bed92de2..25db5ab8 100644 --- a/src/model.ts +++ b/src/model.ts @@ -1,4 +1,4 @@ -import * as fs from "fs"; +import { Stats } from "fs"; import * as path from "path"; import { commands, @@ -31,6 +31,7 @@ import { isDescendant, normalizePath } from "./util"; +import { exists, readDir, stat } from "./util/async_fs"; import { matchAll } from "./util/globMatch"; export class Model implements IDisposable { @@ -269,7 +270,13 @@ export class Model implements IDisposable { return; } - let isSvnFolder = fs.existsSync(path + "/.svn"); + let isSvnFolder = false; + + try { + isSvnFolder = await exists(path + "/.svn"); + } catch (error) { + // error + } // If open only a subpath. if (!isSvnFolder && level === 0) { @@ -277,7 +284,13 @@ export class Model implements IDisposable { while (pathParts.length > 0) { pathParts.pop(); const topPath = pathParts.join("/") + "/.svn"; - isSvnFolder = fs.existsSync(topPath); + + try { + isSvnFolder = await exists(topPath); + } catch (error) { + // error + } + if (isSvnFolder) { break; } @@ -320,11 +333,26 @@ export class Model implements IDisposable { const newLevel = level + 1; if (newLevel <= this.maxDepth) { - for (const file of fs.readdirSync(path)) { + let files: string[] | Buffer[] = []; + + try { + files = await readDir(path); + } catch (error) { + return; + } + + for (const file of files) { const dir = path + "/" + file; + let stats: Stats; + + try { + stats = await stat(dir); + } catch (error) { + continue; + } if ( - fs.statSync(dir).isDirectory() && + stats.isDirectory() && !matchAll(dir, this.ignoreList, { dot: true }) ) { await this.tryOpenRepository(dir, newLevel); diff --git a/src/util/async_fs.ts b/src/util/async_fs.ts new file mode 100644 index 00000000..a61446cb --- /dev/null +++ b/src/util/async_fs.ts @@ -0,0 +1,31 @@ +import * as fs from "fs"; + +export function readDir(path: string): Promise { + return new Promise((resolve, reject) => { + fs.readdir(path, (err, files) => { + if (err) { + reject(err); + } + + resolve(files); + }); + }); +} + +export function stat(path: string): Promise { + return new Promise((resolve, reject) => { + fs.stat(path, (err, stats) => { + if (err) { + reject(err); + } + + resolve(stats); + }); + }); +} + +export function exists(path: string): Promise { + return new Promise((resolve, reject) => { + fs.access(path, err => (err ? reject(err) : resolve(true))); + }); +}