flow-typed
Version:
A repository of high quality flow type definitions
132 lines (119 loc) • 3.32 kB
Flow
// @flow
import mkdirpLib from 'mkdirp';
import {fs, path} from './node.js';
const P = Promise;
export function copyDir(srcPath: string, destPath: string): Promise<void> {
return new Promise((res, rej) => {
fs.copy(srcPath, destPath, err => {
if (err) {
rej(err);
} else {
res();
}
});
});
}
export function copyFile(
srcPath: string,
destPath: string,
preProcessor?: (content: string) => string,
): Promise<void> {
return new Promise((res, rej) => {
if (preProcessor) {
const content = fs.readFileSync(srcPath, 'utf-8');
fs.writeFile(destPath, preProcessor(content), (err: Error) => {
if (err) {
rej(err);
} else {
res();
}
});
} else {
fs.copyFile(srcPath, destPath, err => {
if (err) {
rej(err);
} else {
res();
}
});
}
});
}
export async function getFilesInDir(
dirPath: string,
recursive: boolean = false,
): Promise<Set<string>> {
let dirItems = await fs.readdir(dirPath);
let dirItemStats = await P.all(
dirItems.map(item => fs.stat(path.join(dirPath, item))),
);
const installedLibDefs = new Set();
await P.all(
dirItems.map(async (itemName, idx) => {
const itemStat = dirItemStats[idx];
if (itemStat.isFile()) {
installedLibDefs.add(itemName);
} else if (recursive && itemStat.isDirectory()) {
const itemPath = path.join(dirPath, itemName);
const subDirFiles = await getFilesInDir(itemPath, recursive);
subDirFiles.forEach(subItemName =>
installedLibDefs.add(path.join(itemName, subItemName)),
);
}
}),
);
return installedLibDefs;
}
export function mkdirp(path: string): Promise<*> {
return mkdirpLib(path);
}
export async function recursiveRmdir(dirPath: string): Promise<void> {
let dirItems = await fs.readdir(dirPath);
let dirItemStats = await P.all(
dirItems.map(item => fs.stat(path.join(dirPath, item))),
);
await P.all(
dirItems.map(async (itemName, idx) => {
const itemStat = dirItemStats[idx];
const itemPath = path.join(dirPath, itemName);
if (itemStat.isFile()) {
await fs.unlink(itemPath);
} else {
await recursiveRmdir(itemPath);
await fs.rmdir(itemPath).catch(err => {
if (err.code === 'ENOENT') {
// Ignore ENOENT error
// it's okay if the files are already removed
return;
}
throw err;
});
}
}),
);
return fs.rmdir(dirPath);
}
export async function searchUpDirPath(
startDir: string,
testFn: (path: string) => Promise<boolean>,
): Promise<string | null> {
let currDir = startDir;
let lastDir = null;
while (currDir !== lastDir) {
if (await testFn(currDir)) {
return currDir;
}
lastDir = currDir;
currDir = path.resolve(currDir, '..');
}
return null;
}
/**
* Returns whether a file matches one of the excluded file names
* which would be used by an external system and shouldn't be parsed
* by flow-typed cli.
*/
export function isExcludedFile(item: string): boolean {
// If a user opens definitions dir in finder it will create `.DS_Store`
return ['.DS_Store', 'CODEOWNERS'].includes(item);
}