mirror of https://github.com/status-im/metro.git
RM fastfs.js: @flow
Reviewed By: cpojer Differential Revision: D4118175 fbshipit-source-id: ad9d1f98bcde0c1be17d36c74c3662e6e55165f8
This commit is contained in:
parent
d730928b0c
commit
4fe80636fb
|
@ -5,7 +5,10 @@
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
@ -15,8 +18,34 @@ const {EventEmitter} = require('events');
|
||||||
|
|
||||||
const NOT_FOUND_IN_ROOTS = 'NotFoundInRootsError';
|
const NOT_FOUND_IN_ROOTS = 'NotFoundInRootsError';
|
||||||
|
|
||||||
|
interface Activity {
|
||||||
|
startEvent(title: string, m: mixed, opts: mixed): mixed,
|
||||||
|
endEvent(activity: mixed): void,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FileWatcher {
|
||||||
|
on(event: 'all', handler: (type: string, filePath: string, rootPath: string, fstat: fs.Stats) => void): void,
|
||||||
|
}
|
||||||
|
|
||||||
class Fastfs extends EventEmitter {
|
class Fastfs extends EventEmitter {
|
||||||
constructor(name, roots, fileWatcher, files, {ignore, activity}) {
|
|
||||||
|
_name: string;
|
||||||
|
_fileWatcher: FileWatcher;
|
||||||
|
_ignore: (filePath: string) => boolean;
|
||||||
|
_roots: Array<File>;
|
||||||
|
_fastPaths: {[filePath: string]: File};
|
||||||
|
_activity: mixed;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
name: string,
|
||||||
|
roots: Array<string>,
|
||||||
|
fileWatcher: FileWatcher,
|
||||||
|
files: Array<string>,
|
||||||
|
{ignore, activity}: {
|
||||||
|
ignore: (filePath: string) => boolean,
|
||||||
|
activity: Activity,
|
||||||
|
},
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this._name = name;
|
this._name = name;
|
||||||
this._fileWatcher = fileWatcher;
|
this._fileWatcher = fileWatcher;
|
||||||
|
@ -68,7 +97,7 @@ class Fastfs extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stat(filePath) {
|
stat(filePath: string) {
|
||||||
return Promise.resolve().then(() => this._getFile(filePath).stat());
|
return Promise.resolve().then(() => this._getFile(filePath).stat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +106,10 @@ class Fastfs extends EventEmitter {
|
||||||
.filter(filePath => !this._fastPaths[filePath].isDir);
|
.filter(filePath => !this._fastPaths[filePath].isDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
findFilesByExts(exts, { ignore } = {}) {
|
findFilesByExts(
|
||||||
|
exts: Array<string>,
|
||||||
|
{ignore}: {ignore: (filePath: string) => boolean} = {},
|
||||||
|
) {
|
||||||
return this.getAllFiles()
|
return this.getAllFiles()
|
||||||
.filter(filePath => (
|
.filter(filePath => (
|
||||||
exts.indexOf(path.extname(filePath).substr(1)) !== -1 &&
|
exts.indexOf(path.extname(filePath).substr(1)) !== -1 &&
|
||||||
|
@ -85,11 +117,11 @@ class Fastfs extends EventEmitter {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
matchFilesByPattern(pattern) {
|
matchFilesByPattern(pattern: RegExp) {
|
||||||
return this.getAllFiles().filter(file => file.match(pattern));
|
return this.getAllFiles().filter(file => file.match(pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
readFile(filePath) {
|
readFile(filePath: string) {
|
||||||
const file = this._getFile(filePath);
|
const file = this._getFile(filePath);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
throw new Error(`Unable to find file with path: ${filePath}`);
|
throw new Error(`Unable to find file with path: ${filePath}`);
|
||||||
|
@ -97,10 +129,11 @@ class Fastfs extends EventEmitter {
|
||||||
return file.read();
|
return file.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
closest(filePath, name) {
|
closest(filePath: string, name: string) {
|
||||||
for (let file = this._getFile(filePath).parent;
|
for (let file = this._getFile(filePath).parent;
|
||||||
file;
|
file;
|
||||||
file = file.parent) {
|
file = file.parent) {
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
if (file.children[name]) {
|
if (file.children[name]) {
|
||||||
return file.children[name].path;
|
return file.children[name].path;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +141,7 @@ class Fastfs extends EventEmitter {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileExists(filePath) {
|
fileExists(filePath: string) {
|
||||||
let file;
|
let file;
|
||||||
try {
|
try {
|
||||||
file = this._getFile(filePath);
|
file = this._getFile(filePath);
|
||||||
|
@ -122,7 +155,7 @@ class Fastfs extends EventEmitter {
|
||||||
return file && !file.isDir;
|
return file && !file.isDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirExists(filePath) {
|
dirExists(filePath: string) {
|
||||||
let file;
|
let file;
|
||||||
try {
|
try {
|
||||||
file = this._getFile(filePath);
|
file = this._getFile(filePath);
|
||||||
|
@ -136,12 +169,13 @@ class Fastfs extends EventEmitter {
|
||||||
return file && file.isDir;
|
return file && file.isDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
matches(dir, pattern) {
|
matches(dir: string, pattern: RegExp) {
|
||||||
const dirFile = this._getFile(dir);
|
const dirFile = this._getFile(dir);
|
||||||
if (!dirFile.isDir) {
|
if (!dirFile.isDir) {
|
||||||
throw new Error(`Expected file ${dirFile.path} to be a directory`);
|
throw new Error(`Expected file ${dirFile.path} to be a directory`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
return Object.keys(dirFile.children)
|
return Object.keys(dirFile.children)
|
||||||
.filter(name => name.match(pattern))
|
.filter(name => name.match(pattern))
|
||||||
.map(name => path.join(dirFile.path, name));
|
.map(name => path.join(dirFile.path, name));
|
||||||
|
@ -161,6 +195,7 @@ class Fastfs extends EventEmitter {
|
||||||
const root = this._getRoot(filePath);
|
const root = this._getRoot(filePath);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
const error = new Error(`File ${filePath} not found in any of the roots`);
|
const error = new Error(`File ${filePath} not found in any of the roots`);
|
||||||
|
/* $FlowFixMe: Monkey-patching Error. */
|
||||||
error.type = NOT_FOUND_IN_ROOTS;
|
error.type = NOT_FOUND_IN_ROOTS;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +245,16 @@ class Fastfs extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
class File {
|
class File {
|
||||||
constructor(filePath, isDir) {
|
|
||||||
|
path: string;
|
||||||
|
isDir: boolean;
|
||||||
|
children: ?{[filePath: string]: File};
|
||||||
|
parent: ?File;
|
||||||
|
|
||||||
|
_read: ?Promise<string>;
|
||||||
|
_stat: ?Promise<fs.Stats>;
|
||||||
|
|
||||||
|
constructor(filePath: string, isDir: boolean) {
|
||||||
this.path = filePath;
|
this.path = filePath;
|
||||||
this.isDir = isDir;
|
this.isDir = isDir;
|
||||||
this.children = this.isDir ? Object.create(null) : null;
|
this.children = this.isDir ? Object.create(null) : null;
|
||||||
|
@ -243,16 +287,19 @@ class File {
|
||||||
return this._stat;
|
return this._stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
addChild(file, fileMap) {
|
addChild(file: File, fileMap: {[filePath: string]: File}) {
|
||||||
const parts = file.path.substr(this.path.length + 1).split(path.sep);
|
const parts = file.path.substr(this.path.length + 1).split(path.sep);
|
||||||
if (parts.length === 1) {
|
if (parts.length === 1) {
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
this.children[parts[0]] = file;
|
this.children[parts[0]] = file;
|
||||||
file.parent = this;
|
file.parent = this;
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
} else if (this.children[parts[0]]) {
|
} else if (this.children[parts[0]]) {
|
||||||
this.children[parts[0]].addChild(file, fileMap);
|
this.children[parts[0]].addChild(file, fileMap);
|
||||||
} else {
|
} else {
|
||||||
const dir = new File(this.path + path.sep + parts[0], true);
|
const dir = new File(this.path + path.sep + parts[0], true);
|
||||||
dir.parent = this;
|
dir.parent = this;
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
this.children[parts[0]] = dir;
|
this.children[parts[0]] = dir;
|
||||||
fileMap[dir.path] = dir;
|
fileMap[dir.path] = dir;
|
||||||
dir.addChild(file, fileMap);
|
dir.addChild(file, fileMap);
|
||||||
|
@ -275,6 +322,7 @@ class File {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* $FlowFixMe: will crash if not `isDir`, see constructor */
|
||||||
file = file.children[fileName];
|
file = file.children[fileName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,6 +338,7 @@ class File {
|
||||||
throw new Error(`No parent to delete ${this.path} from`);
|
throw new Error(`No parent to delete ${this.path} from`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* $FlowFixMe: will crash if parent is not `isDir`, see constructor */
|
||||||
delete this.parent.children[path.basename(this.path)];
|
delete this.parent.children[path.basename(this.path)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue