feat: 🎸 出码模块的 DiskPublisher 改成支持传入自定义 FS

This commit is contained in:
牧毅 2020-08-17 16:45:48 +08:00
parent 8ecc002f65
commit 46c896eacf
2 changed files with 33 additions and 40 deletions

View File

@ -1,16 +1,14 @@
import { import * as defaultFs from 'fs';
IResultDir, import { IResultDir, PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types';
PublisherFactory, import { writeFolder, IFileSystem } from './utils';
IPublisher,
IPublisherFactoryParams, export type { IFileSystem };
PublisherError,
} from '../../types';
import { writeFolder } from './utils';
export interface IDiskFactoryParams extends IPublisherFactoryParams { export interface IDiskFactoryParams extends IPublisherFactoryParams {
outputPath?: string; outputPath?: string;
projectSlug?: string; projectSlug?: string;
createProjectFolder?: boolean; createProjectFolder?: boolean;
fs?: IFileSystem;
} }
export interface IDiskPublisher extends IPublisher<IDiskFactoryParams, string> { export interface IDiskPublisher extends IPublisher<IDiskFactoryParams, string> {
@ -18,11 +16,10 @@ export interface IDiskPublisher extends IPublisher<IDiskFactoryParams, string> {
setOutputPath: (path: string) => void; setOutputPath: (path: string) => void;
} }
export const createDiskPublisher: PublisherFactory< export const createDiskPublisher: PublisherFactory<IDiskFactoryParams, IDiskPublisher> = (
IDiskFactoryParams, params: IDiskFactoryParams = {},
IDiskPublisher ): IDiskPublisher => {
> = (params: IDiskFactoryParams = {}): IDiskPublisher => { let { project, outputPath = './', fs = defaultFs } = params;
let { project, outputPath = './' } = params;
const getProject = (): IResultDir => { const getProject = (): IResultDir => {
if (!project) { if (!project) {
@ -49,19 +46,14 @@ export const createDiskPublisher: PublisherFactory<
const projectOutputPath = options.outputPath || outputPath; const projectOutputPath = options.outputPath || outputPath;
const overrideProjectSlug = options.projectSlug || params.projectSlug; const overrideProjectSlug = options.projectSlug || params.projectSlug;
const createProjectFolder = const createProjectFolder = options.createProjectFolder || params.createProjectFolder;
options.createProjectFolder || params.createProjectFolder;
if (overrideProjectSlug) { if (overrideProjectSlug) {
projectToPublish.name = overrideProjectSlug; projectToPublish.name = overrideProjectSlug;
} }
try { try {
await writeFolder( await writeFolder(projectToPublish, projectOutputPath, createProjectFolder, fs);
projectToPublish,
projectOutputPath,
createProjectFolder,
);
return { success: true, payload: projectOutputPath }; return { success: true, payload: projectOutputPath };
} catch (error) { } catch (error) {
throw new PublisherError(error); throw new PublisherError(error);

View File

@ -1,39 +1,38 @@
import { existsSync, mkdir, writeFile } from 'fs'; import * as systemFs from 'fs';
import { join } from 'path'; import { join } from 'path';
import { IResultDir, IResultFile } from '../../types'; import { IResultDir, IResultFile } from '../../types';
export interface IFileSystem {
existsSync: typeof systemFs.existsSync;
mkdir: typeof systemFs.mkdir;
writeFile: typeof systemFs.writeFile;
}
export const writeFolder = async ( export const writeFolder = async (
folder: IResultDir, folder: IResultDir,
currentPath: string, currentPath: string,
createProjectFolder = true, createProjectFolder = true,
fs: IFileSystem = systemFs,
): Promise<void> => { ): Promise<void> => {
const { name, files, dirs } = folder; const { name, files, dirs } = folder;
const folderPath = createProjectFolder const folderPath = createProjectFolder ? join(currentPath, name) : currentPath;
? join(currentPath, name)
: currentPath;
if (!existsSync(folderPath)) { if (!fs.existsSync(folderPath)) {
await createDirectory(folderPath); await createDirectory(folderPath, fs);
} }
const promises = [ const promises = [writeFilesToFolder(folderPath, files, fs), writeSubFoldersToFolder(folderPath, dirs, fs)];
writeFilesToFolder(folderPath, files),
writeSubFoldersToFolder(folderPath, dirs),
];
await Promise.all(promises); await Promise.all(promises);
}; };
const writeFilesToFolder = async ( const writeFilesToFolder = async (folderPath: string, files: IResultFile[], fs: IFileSystem): Promise<void> => {
folderPath: string, const promises = files.map((file) => {
files: IResultFile[],
): Promise<void> => {
const promises = files.map(file => {
const fileName = file.ext ? `${file.name}.${file.ext}` : file.name; const fileName = file.ext ? `${file.name}.${file.ext}` : file.name;
const filePath = join(folderPath, fileName); const filePath = join(folderPath, fileName);
return writeContentToFile(filePath, file.content); return writeContentToFile(filePath, file.content, 'utf8', fs);
}); });
await Promise.all(promises); await Promise.all(promises);
@ -42,17 +41,18 @@ const writeFilesToFolder = async (
const writeSubFoldersToFolder = async ( const writeSubFoldersToFolder = async (
folderPath: string, folderPath: string,
subFolders: IResultDir[], subFolders: IResultDir[],
fs: IFileSystem,
): Promise<void> => { ): Promise<void> => {
const promises = subFolders.map(subFolder => { const promises = subFolders.map((subFolder) => {
return writeFolder(subFolder, folderPath); return writeFolder(subFolder, folderPath);
}); });
await Promise.all(promises); await Promise.all(promises);
}; };
const createDirectory = (pathToDir: string): Promise<void> => { const createDirectory = (pathToDir: string, fs: IFileSystem): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
mkdir(pathToDir, { recursive: true }, err => { fs.mkdir(pathToDir, { recursive: true }, (err) => {
err ? reject(err) : resolve(); err ? reject(err) : resolve();
}); });
}); });
@ -62,9 +62,10 @@ const writeContentToFile = (
filePath: string, filePath: string,
fileContent: string, fileContent: string,
encoding: string = 'utf8', encoding: string = 'utf8',
fs: IFileSystem,
): Promise<void> => { ): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
writeFile(filePath, fileContent, encoding, err => { fs.writeFile(filePath, fileContent, encoding, (err) => {
err ? reject(err) : resolve(); err ? reject(err) : resolve();
}); });
}); });