docusaurus/website/_dogfooding/testSwizzleThemeClassic.mjs
Joshua Chen b31220032b
refactor(theme-classic): migrate to tsc for build (#7447)
* refactor(theme-classic): migrate to tsc for build

* fix
2022-05-18 20:08:09 +08:00

156 lines
4.2 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import path from 'path';
import fs from 'fs-extra';
import {fileURLToPath} from 'url';
import logger from '@docusaurus/logger';
import ClassicTheme from '@docusaurus/theme-classic';
// Unsafe imports
import {readComponentNames} from '@docusaurus/core/lib/commands/swizzle/components.js';
import {normalizeSwizzleConfig} from '@docusaurus/core/lib/commands/swizzle/config.js';
import {wrap, eject} from '@docusaurus/core/lib/commands/swizzle/actions.js';
const swizzleConfig = normalizeSwizzleConfig(ClassicTheme.getSwizzleConfig());
const action = process.env.SWIZZLE_ACTION ?? 'eject';
const typescript = process.env.SWIZZLE_TYPESCRIPT === 'true';
const dirname = path.dirname(fileURLToPath(import.meta.url));
const classicThemePathBase = path.join(
dirname,
'../../packages/docusaurus-theme-classic',
);
const themePath = swizzleConfig
? path.join(classicThemePathBase, 'src/theme')
: path.join(classicThemePathBase, 'lib/theme');
const toPath = path.join(dirname, '_swizzle_theme_tests');
console.log('\n');
console.log('Swizzle test script');
console.log('Args', {
action,
typescript,
dirname,
themePath,
toPath,
swizzleConfig,
});
console.log('\n');
await fs.remove(toPath);
let componentNames = await readComponentNames(themePath);
const componentsNotFound = Object.keys(swizzleConfig.components).filter(
(componentName) => !componentNames.includes(componentName),
);
if (componentsNotFound.length > 0) {
logger.error(
`${
componentsNotFound.length
} components exist in the swizzle config but do not exist in practice.
Please double-check or clean up these components from the config:
- ${componentsNotFound.join('\n- ')}
`,
);
process.exit(1);
}
// TODO temp workaround: non-comps should be forbidden to wrap
if (action === 'wrap') {
const WrapBlocklist = [
'Layout', // Due to theme-fallback?
];
componentNames = componentNames.filter((componentName) => {
const blocked = WrapBlocklist.includes(componentName);
if (blocked) {
logger.warn(`${componentName} is blocked and will not be wrapped`);
}
return !blocked;
});
}
function getActionStatus(componentName) {
const actionStatus =
swizzleConfig.components[componentName]?.actions[action] ?? 'unsafe';
if (!actionStatus) {
throw new Error(
`Unexpected: missing action ${action} for ${componentName}`,
);
}
return actionStatus;
}
for (const componentName of componentNames) {
const executeAction = () => {
const baseParams = {
action,
siteDir: toPath,
themePath,
componentName,
};
switch (action) {
case 'wrap':
return wrap({
...baseParams,
importType: 'init', // For these tests, "theme-original" imports are causing an expected infinite loop
typescript,
});
case 'eject':
return eject(baseParams);
default:
throw new Error(`Unknown action: ${action}`);
}
};
const actionStatus = getActionStatus(componentName);
if (actionStatus === 'forbidden') {
logger.warn(
`${componentName} is marked as forbidden for action ${action} => skipping`,
);
continue;
}
const result = await executeAction();
const safetyLog =
actionStatus === 'unsafe' ? logger.red('unsafe') : logger.green('safe');
console.log(
`${componentName} ${action} (${safetyLog}) => ${
result.createdFiles.length
} file${result.createdFiles.length > 1 ? 's' : ''} written`,
);
}
logger.success(`
End of the Swizzle test script.
Now try to build the site and see if it works!
`);
const componentsWithMissingConfigs = componentNames.filter(
(componentName) => !swizzleConfig.components[componentName],
);
// TODO require theme exhaustive config, fail fast?
// (at least for our classic theme?)
// TODO provide util so that theme authors can also check exhaustiveness?
if (componentsWithMissingConfigs.length > 0) {
logger.warn(
`${componentsWithMissingConfigs.length} components have no swizzle config.
Sample: ${componentsWithMissingConfigs.slice(0, 5).join(', ')} ...
`,
);
}