refactor: prefer fs.outputFile to ensureDir + writeFile (#6880)

* refactor: prefer fs.outputFile to ensureDir + writeFile

* fix test

* fix
This commit is contained in:
Joshua Chen 2022-03-09 17:50:33 +08:00 committed by GitHub
parent 73df485aec
commit 23a34c1a07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 66 additions and 108 deletions

View file

@ -6,6 +6,10 @@ Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/blog",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/blog",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/pages/en",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/complex_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/static",
@ -16,10 +20,7 @@ Array [
exports[`migration test complex website: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/css",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages/",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages",
],
]
`;
@ -179,16 +180,6 @@ Array [
}
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_complex_site/src/pages/index.js",
"import Layout from \\"@theme/Layout\\";
import React from \\"react\\";
export default () => {
return <Layout />;
};
",
],
]
`;
@ -198,6 +189,10 @@ Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/blog",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/blog",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/pages/en",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/missing_version_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/static",
@ -208,10 +203,7 @@ Array [
exports[`migration test missing versions: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/css",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages/",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages",
],
]
`;
@ -371,21 +363,15 @@ Array [
}
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_missing_version_site/src/pages/index.js",
"import Layout from \\"@theme/Layout\\";
import React from \\"react\\";
export default () => {
return <Layout />;
};
",
],
]
`;
exports[`migration test simple website: copy 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/website/pages/en",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/website/static",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/static",
@ -396,10 +382,7 @@ Array [
exports[`migration test simple website: mkdirp 1`] = `
Array [
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/css",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages/",
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages",
],
]
`;
@ -560,24 +543,14 @@ Array [
}
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/migrated_simple_site/src/pages/index.js",
"import Layout from \\"@theme/Layout\\";
import React from \\"react\\";
export default () => {
return <Layout />;
};
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-commands.md",
"---
id: commands
title: CLI Commands
---
## Doc ",
## Doc
",
],
Array [
"<PROJECT_ROOT>/packages/docusaurus-migrate/src/__tests__/__fixtures__/simple_website/docs/api-doc-markdown.md",
@ -585,8 +558,8 @@ title: CLI Commands
id: doc-markdown
title: Markdown Features
---
## Doc",
## Doc
",
],
]
`;

View file

@ -11,11 +11,11 @@ import fs from 'fs-extra';
import {posixPath} from '@docusaurus/utils';
async function testMigration(siteDir: string, newDir: string) {
const writeMock = jest.spyOn(fs, 'writeFile').mockImplementation();
const writeMock = jest.spyOn(fs, 'outputFile').mockImplementation();
const mkdirpMock = jest.spyOn(fs, 'mkdirp').mockImplementation();
const mkdirsMock = jest.spyOn(fs, 'mkdirs').mockImplementation();
const copyMock = jest.spyOn(fs, 'copy').mockImplementation();
await migrateDocusaurusProject(siteDir, newDir);
await migrateDocusaurusProject(siteDir, newDir, true, true);
expect(
writeMock.mock.calls.sort((a, b) =>
posixPath(a[0] as string).localeCompare(posixPath(b[0] as string)),

View file

@ -171,7 +171,7 @@ export async function migrateDocusaurusProject(
}
try {
await fs.writeFile(
await fs.outputFile(
path.join(newDir, 'docusaurus.config.js'),
`module.exports=${JSON.stringify(migrationContext.v2Config, null, 2)}`,
);
@ -388,7 +388,7 @@ async function createPages(context: MigrationContext) {
files.map(async (file) => {
const filePath = path.join(newDir, 'src', 'pages', file);
const content = await fs.readFile(filePath, 'utf-8');
await fs.writeFile(filePath, migratePage(content));
await fs.outputFile(filePath, migratePage(content));
}),
);
} catch (err) {
@ -408,8 +408,7 @@ async function createDefaultLandingPage({newDir}: MigrationContext) {
return <Layout />;
};
`;
await fs.mkdirp(`${newDir}/src/pages/`);
await fs.writeFile(`${newDir}/src/pages/index.js`, indexPage);
await fs.outputFile(`${newDir}/src/pages/index.js`, indexPage);
}
async function migrateStaticFiles({siteDir, newDir}: MigrationContext) {
@ -428,7 +427,7 @@ async function migrateBlogFiles(context: MigrationContext) {
await Promise.all(
files.map(async (file) => {
const content = await fs.readFile(file, 'utf-8');
await fs.writeFile(
await fs.outputFile(
file,
sanitizedFileContent(content, shouldMigrateMdFiles),
);
@ -508,7 +507,7 @@ async function migrateVersionedDocs(
files.map(async (pathToFile) => {
if (path.extname(pathToFile) === '.md') {
const content = await fs.readFile(pathToFile, 'utf-8');
await fs.writeFile(
await fs.outputFile(
pathToFile,
sanitizedFileContent(
content.replace(versionRegex, ''),
@ -601,7 +600,7 @@ async function migrateVersionedSidebar(
},
{} as SidebarEntries,
);
await fs.writeFile(
await fs.outputFile(
path.join(
newDir,
'versioned_sidebars',
@ -664,8 +663,10 @@ async function migrateLatestSidebar(context: MigrationContext) {
--ifm-color-primary-darkest: ${primaryColor.darken(0.3).hex()};
}
`;
await fs.mkdirp(path.join(newDir, 'src', 'css'));
await fs.writeFile(path.join(newDir, 'src', 'css', 'customTheme.css'), css);
await fs.outputFile(
path.join(newDir, 'src', 'css', 'customTheme.css'),
css,
);
context.v2Config.presets[0][1].theme.customCss = path.join(
path.relative(newDir, path.join(siteDir, '..')),
'src/css/customTheme.css',
@ -685,7 +686,7 @@ async function migrateLatestDocs(context: MigrationContext) {
files.map(async (file) => {
if (path.extname(file) === '.md') {
const content = await fs.readFile(file, 'utf-8');
await fs.writeFile(
await fs.outputFile(
file,
sanitizedFileContent(content, shouldMigrateMdFiles),
);
@ -725,7 +726,7 @@ async function migratePackageFile(context: MigrationContext): Promise<void> {
...packageFile.dependencies,
...deps,
};
await fs.writeFile(
await fs.outputFile(
path.join(newDir, 'package.json'),
JSON.stringify(packageFile, null, 2),
);
@ -743,7 +744,7 @@ export async function migrateMDToMDX(
files.map(async (filePath) => {
if (path.extname(filePath) === '.md') {
const content = await fs.readFile(filePath, 'utf-8');
await fs.writeFile(filePath, sanitizedFileContent(content, true));
await fs.outputFile(filePath, sanitizedFileContent(content, true));
}
}),
);

View file

@ -194,8 +194,7 @@ describe('writeRedirectFiles', () => {
},
];
await fs.ensureDir(path.dirname(filesMetadata[0].fileAbsolutePath));
await fs.writeFile(
await fs.outputFile(
filesMetadata[0].fileAbsolutePath,
'file already exists!',
);

View file

@ -92,8 +92,7 @@ export async function writeRedirectFile(
'The redirect plugin is not supposed to override existing files.',
);
}
await fs.ensureDir(path.dirname(file.fileAbsolutePath));
await fs.writeFile(
await fs.outputFile(
file.fileAbsolutePath,
file.fileContent,
// Hard security to prevent file overrides

View file

@ -13,7 +13,7 @@ import {
mapAsyncSequential,
readOutputHTMLFile,
} from '@docusaurus/utils';
import cheerio from 'cheerio';
import {load as cheerioLoad} from 'cheerio';
import type {DocusaurusConfig} from '@docusaurus/types';
import path from 'path';
import fs from 'fs-extra';
@ -78,7 +78,7 @@ async function generateBlogFeed({
outDir,
siteConfig.trailingSlash,
);
const $ = cheerio.load(content);
const $ = cheerioLoad(content);
const feedItem: FeedItem = {
title: metadataTitle,

View file

@ -186,8 +186,7 @@ describe('docsVersion', () => {
test('first time versioning', async () => {
const copyMock = jest.spyOn(fs, 'copy').mockImplementation();
const ensureMock = jest.spyOn(fs, 'ensureDir').mockImplementation();
const writeMock = jest.spyOn(fs, 'writeFile');
const writeMock = jest.spyOn(fs, 'outputFile');
let versionedSidebar;
let versionedSidebarPath;
writeMock.mockImplementationOnce((filepath, content) => {
@ -238,13 +237,11 @@ describe('docsVersion', () => {
copyMock.mockRestore();
writeMock.mockRestore();
consoleMock.mockRestore();
ensureMock.mockRestore();
});
test('not the first time versioning', async () => {
const copyMock = jest.spyOn(fs, 'copy').mockImplementation();
const ensureMock = jest.spyOn(fs, 'ensureDir').mockImplementation();
const writeMock = jest.spyOn(fs, 'writeFile');
const writeMock = jest.spyOn(fs, 'outputFile');
let versionedSidebar;
let versionedSidebarPath;
writeMock.mockImplementationOnce((filepath, content) => {
@ -295,15 +292,13 @@ describe('docsVersion', () => {
copyMock.mockRestore();
writeMock.mockRestore();
consoleMock.mockRestore();
ensureMock.mockRestore();
});
test('second docs instance versioning', async () => {
const pluginId = 'community';
const copyMock = jest.spyOn(fs, 'copy').mockImplementation();
const ensureMock = jest.spyOn(fs, 'ensureDir').mockImplementation();
const writeMock = jest.spyOn(fs, 'writeFile');
const writeMock = jest.spyOn(fs, 'outputFile');
let versionedSidebar;
let versionedSidebarPath;
writeMock.mockImplementationOnce((filepath, content) => {
@ -350,6 +345,5 @@ describe('docsVersion', () => {
copyMock.mockRestore();
writeMock.mockRestore();
consoleMock.mockRestore();
ensureMock.mockRestore();
});
});

View file

@ -47,8 +47,7 @@ async function createVersionedSidebarFile({
versionedSidebarsDir,
`version-${version}-sidebars.json`,
);
await fs.ensureDir(path.dirname(newSidebarFile));
await fs.writeFile(
await fs.outputFile(
newSidebarFile,
`${JSON.stringify(sidebars, null, 2)}\n`,
'utf8',
@ -140,8 +139,7 @@ export async function cliDocsVersionCommand(
// Update versions.json file.
versions.unshift(version);
await fs.ensureDir(path.dirname(versionsJSONFile));
await fs.writeFile(
await fs.outputFile(
versionsJSONFile,
`${JSON.stringify(versions, null, 2)}\n`,
);

View file

@ -140,7 +140,7 @@ ${warning}
async function readMessagesFile(filePath) {
if (!(await fs.pathExists(filePath))) {
logger.info`File path=${filePath} not found. Creating new translation base file.`;
await fs.writeFile(filePath, '{}\n');
await fs.outputFile(filePath, '{}\n');
}
return JSON.parse((await fs.readFile(filePath)).toString());
}

View file

@ -120,7 +120,7 @@ describe('readOutputHTMLFile', () => {
});
test('generate', async () => {
const writeMock = jest.spyOn(fs, 'writeFile').mockImplementation(() => {});
const writeMock = jest.spyOn(fs, 'outputFile').mockImplementation(() => {});
const existsMock = jest.spyOn(fs, 'pathExists');
const readMock = jest.spyOn(fs, 'readFile');

View file

@ -88,9 +88,9 @@ describe('mapAsyncSequential', () => {
test('map sequentially', async () => {
const itemToTimeout: Record<string, number> = {
'1': 50,
'2': 150,
'3': 100,
'1': 200,
'2': 600,
'3': 400,
};
const items = Object.keys(itemToTimeout);
@ -112,14 +112,14 @@ describe('mapAsyncSequential', () => {
const timeTotal = timeAfter - timeBefore;
const totalTimeouts = _.sum(Object.values(itemToTimeout));
expect(timeTotal).toBeGreaterThanOrEqual(totalTimeouts - 20);
expect(timeTotal).toBeGreaterThanOrEqual(totalTimeouts - 100);
expect(itemMapStartsAt['1']).toBeGreaterThanOrEqual(0);
expect(itemMapStartsAt['2']).toBeGreaterThanOrEqual(
itemMapEndsAt['1'] - 20,
itemMapEndsAt['1'] - 100,
);
expect(itemMapStartsAt['3']).toBeGreaterThanOrEqual(
itemMapEndsAt['2'] - 20,
itemMapEndsAt['2'] - 100,
);
});
});
@ -135,7 +135,7 @@ describe('findAsyncSequential', () => {
const items = ['1', '2', '3'];
const findFn = jest.fn(async (item: string) => {
await sleep(50);
await sleep(400);
return item === '2';
});
@ -148,8 +148,8 @@ describe('findAsyncSequential', () => {
expect(findFn).toHaveBeenNthCalledWith(2, '2');
const timeTotal = timeAfter - timeBefore;
expect(timeTotal).toBeGreaterThanOrEqual(80);
expect(timeTotal).toBeLessThan(120);
expect(timeTotal).toBeGreaterThanOrEqual(600);
expect(timeTotal).toBeLessThan(1000);
});
});

View file

@ -22,8 +22,7 @@ export async function generate(
const filepath = path.join(generatedFilesDir, file);
if (skipCache) {
await fs.ensureDir(path.dirname(filepath));
await fs.writeFile(filepath, content);
await fs.outputFile(filepath, content);
return;
}
@ -41,8 +40,7 @@ export async function generate(
const currentHash = createHash('md5').update(content).digest('hex');
if (lastHash !== currentHash) {
await fs.ensureDir(path.dirname(filepath));
await fs.writeFile(filepath, content);
await fs.outputFile(filepath, content);
fileHash.set(filepath, currentHash);
}
}

View file

@ -144,8 +144,7 @@ export default function ${wrapperComponentName}(props) {
}
`;
await fs.ensureDir(path.dirname(toPath));
await fs.writeFile(toPath, content);
await fs.outputFile(toPath, content);
return {createdFiles: [toPath]};
}

View file

@ -552,8 +552,7 @@ describe('extractSiteSourceCodeTranslations', () => {
SRC_DIR_NAME,
'site-component-1.jsx',
);
await fs.ensureDir(path.dirname(siteComponentFile1));
await fs.writeFile(
await fs.outputFile(
siteComponentFile1,
`
import Translate from '@docusaurus/Translate';
@ -586,8 +585,7 @@ export default function MySiteComponent1() {
const plugin1Dir = await createTmpDir();
const plugin1File1 = path.join(plugin1Dir, 'subpath', 'file1.jsx');
await fs.ensureDir(path.dirname(plugin1File1));
await fs.writeFile(
await fs.outputFile(
plugin1File1,
`
import {translate} from '@docusaurus/Translate';
@ -606,8 +604,7 @@ export default function MyComponent() {
`,
);
const plugin1File2 = path.join(plugin1Dir, 'src', 'theme', 'file2.jsx');
await fs.ensureDir(path.dirname(plugin1File2));
await fs.writeFile(
await fs.outputFile(
plugin1File2,
`
import {translate} from '@docusaurus/Translate';
@ -624,8 +621,7 @@ export default function MyComponent() {
// This one should not be found! On purpose!
const plugin1File3 = path.join(plugin1Dir, 'unscannedFolder', 'file3.jsx');
await fs.ensureDir(path.dirname(plugin1File3));
await fs.writeFile(
await fs.outputFile(
plugin1File3,
`
import {translate} from '@docusaurus/Translate';
@ -643,8 +639,7 @@ export default function MyComponent() {
const plugin2Dir = await createTmpDir();
const plugin2File = path.join(plugin1Dir, 'subpath', 'file.tsx');
await fs.ensureDir(path.dirname(plugin2File));
await fs.writeFile(
await fs.outputFile(
plugin2File,
`
import Translate, {translate} from '@docusaurus/Translate';

View file

@ -131,8 +131,10 @@ Maybe you should remove them? ${unknownKeys}`;
} translations will be written at path=${toMessageRelativeFilePath(
filePath,
)}.`;
await fs.ensureDir(path.dirname(filePath));
await fs.writeFile(filePath, `${JSON.stringify(mergedContent, null, 2)}\n`);
await fs.outputFile(
filePath,
`${JSON.stringify(mergedContent, null, 2)}\n`,
);
}
}