Skip to content

Instantly share code, notes, and snippets.

@mrmlnc
Created August 13, 2017 07:35
Show Gist options
  • Save mrmlnc/1d62a336de0ec83dff643013d9908d71 to your computer and use it in GitHub Desktop.
Save mrmlnc/1d62a336de0ec83dff643013d9908d71 to your computer and use it in GitHub Desktop.
import * as path from 'path';
import * as fs from 'fs';
import * as micromatch from 'micromatch';
import * as io from '../utils/io';
import { ITask, IOptions, IEntry } from '../types';
export type TMatch = string | IEntry;
export type TMatches = TMatch[];
interface ITransferEntries {
directories: string[];
matches: TMatches;
}
/**
* The filter of files.
*/
function fileFilter(filepath: string, patterns: string[]): boolean {
return micromatch.some(filepath, patterns);
}
/**
* The filter of directories.
*/
function directoryFilter(dirpath: string, options: IOptions): boolean {
return true;
}
/**
* Retunrs array of matched entries.
*/
async function getEntries(input: string[], task: ITask, options: IOptions): Promise<ITransferEntries> {
const directories: string[] = [];
const matches: TMatches = [];
return Promise.all(input.map(io.readdir)).then((entries) => {
const listOfStats: Promise<fs.Stats>[] = [];
const listOfEntries: string[] = [];
for (let i = 0; i < entries.length; i++) {
const dir = input[i];
const filespaths = entries[i];
for (let j = 0; j < filespaths.length; j++) {
const filepath = filespaths[j];
const fullpath = dir + '/' + filepath;
listOfStats.push(io.statPath(fullpath));
listOfEntries.push(fullpath);
}
}
return Promise.all(listOfStats).then((stats) => {
for (let i = 0; i < listOfEntries.length; i++) {
const entry = listOfEntries[i];
const stat = stats[i];
if (!options.onlyDirectories && stat.isFile() && fileFilter(entry, task.patterns)) {
matches.push(entry);
continue;
}
if (stat.isDirectory() && directoryFilter(entry, options)) {
directories.push(entry);
if (options.onlyDirectories) {
matches.push(entry);
}
}
}
return { directories, matches };
});
});
}
/**
* Async reader for provided task.
*/
export async function readerAsync(task: ITask, options: IOptions): Promise<TMatches> {
const cwd = path.join(options.cwd, task.base);
let directories: string[] = [cwd];
const matches: TMatches = options.onlyDirectories ? [cwd] : [];
do {
const entries = await getEntries(directories, task, options);
// Update list of directories to the next iteration
directories = entries.directories;
// Concat matches
for (let i = 0; i < entries.matches.length; i++) {
matches.push(entries.matches[i]);
}
} while (directories.length !== 0);
return matches;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment