refactor: unify log format with new logger utility (#5994)

Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
Joshua Chen 2021-12-21 00:24:59 +08:00 committed by GitHub
parent faef753730
commit 770418f8d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 717 additions and 650 deletions

View file

@ -122,7 +122,7 @@ module.exports = {
'array-callback-return': WARNING,
camelcase: WARNING,
'no-restricted-syntax': WARNING,
'no-unused-expressions': WARNING,
'no-unused-expressions': [WARNING, {allowTaggedTemplates: true}],
'global-require': WARNING,
'prefer-destructuring': WARNING,
yoda: WARNING,

View file

@ -6,7 +6,9 @@
* LICENSE file in the root directory of this source tree.
*/
const chalk = require('chalk');
// @ts-check
const logger = require('@docusaurus/logger').default;
const semver = require('semver');
const path = require('path');
const program = require('commander');
@ -14,19 +16,15 @@ const {default: init} = require('../lib');
const requiredVersion = require('../package.json').engines.node;
if (!semver.satisfies(process.version, requiredVersion)) {
console.log(
chalk.red(`\nMinimum Node.js version not met :)`) +
chalk.yellow(
`\nYou are using Node.js ${process.version}, Requirement: Node.js ${requiredVersion}.\n`,
),
);
logger.error('Minimum Node.js version not met :(');
logger.info`You are using Node.js number=${process.version}, Requirement: Node.js number=${requiredVersion}.`;
process.exit(1);
}
function wrapCommand(fn) {
return (...args) =>
fn(...args).catch((err) => {
console.error(chalk.red(err.stack));
logger.error(err.stack);
process.exitCode = 1;
});
}
@ -58,8 +56,7 @@ program
program.arguments('<command>').action((cmd) => {
program.outputHelp();
console.log(` ${chalk.red(`\n Unknown command ${chalk.yellow(cmd)}.`)}`);
console.log();
logger.error`Unknown command code=${cmd}.`;
});
program.parse(process.argv);

View file

@ -23,7 +23,7 @@
},
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"@docusaurus/logger": "2.0.0-beta.13",
"commander": "^5.1.0",
"fs-extra": "^10.0.0",
"lodash": "^4.17.20",

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import fs from 'fs-extra';
import {execSync} from 'child_process';
import prompts, {Choice} from 'prompts';
@ -131,12 +131,14 @@ export default async function init(
}
if (!name) {
throw new Error(chalk.red('A website name is required.'));
logger.error('A website name is required.');
process.exit(1);
}
const dest = path.resolve(rootDir, name);
if (fs.existsSync(dest)) {
throw new Error(`Directory already exists at "${dest}"!`);
logger.error`Directory already exists at path=${dest}!`;
process.exit(1);
}
let template = reqTemplate;
@ -171,10 +173,10 @@ export default async function init(
if (url && isValidGitRepoUrl(url)) {
return true;
}
return chalk.red(`Invalid repository URL`);
return logger.red('Invalid repository URL');
},
message:
'Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.\n(e.g: https://github.com/ownerName/repoName.git)',
message: logger.interpolate`Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
(e.g: path=${'https://github.com/ownerName/repoName.git'})`,
});
template = repoPrompt.gitRepoUrl;
} else if (template === 'Local template') {
@ -187,11 +189,11 @@ export default async function init(
if (fs.existsSync(fullDir)) {
return true;
}
return chalk.red(
`The path ${chalk.magenta(fullDir)} does not exist.`,
return logger.red(
logger.interpolate`path=${fullDir} does not exist.`,
);
}
return chalk.red('Please enter a valid path.');
return logger.red('Please enter a valid path.');
},
message:
'Enter a local folder path, relative to the current working directory.',
@ -200,37 +202,34 @@ export default async function init(
}
if (!template) {
throw new Error('Template should not be empty');
logger.error('Template should not be empty');
process.exit(1);
}
console.log(`
${chalk.cyan('Creating new Docusaurus project...')}
`);
logger.info('Creating new Docusaurus project...');
if (isValidGitRepoUrl(template)) {
console.log(`Cloning Git template ${chalk.cyan(template)}...`);
logger.info`Cloning Git template path=${template}...`;
if (
shell.exec(`git clone --recursive ${template} ${dest}`, {silent: true})
.code !== 0
) {
throw new Error(chalk.red(`Cloning Git template ${template} failed!`));
logger.error`Cloning Git template name=${template} failed!`;
process.exit(1);
}
} else if (templates.includes(template)) {
// Docusaurus templates.
if (useTS) {
if (!hasTS(template)) {
throw new Error(
`Template ${template} doesn't provide the Typescript variant.`,
);
logger.error`Template name=${template} doesn't provide the Typescript variant.`;
process.exit(1);
}
template = `${template}${TypeScriptTemplateSuffix}`;
}
try {
await copyTemplate(templatesDir, template, dest);
} catch (err) {
console.log(
`Copying Docusaurus template ${chalk.cyan(template)} failed!`,
);
logger.error`Copying Docusaurus template name=${template} failed!`;
throw err;
}
} else if (fs.existsSync(path.resolve(process.cwd(), template))) {
@ -238,11 +237,12 @@ ${chalk.cyan('Creating new Docusaurus project...')}
try {
await fs.copy(templateDir, dest);
} catch (err) {
console.log(`Copying local template ${templateDir} failed!`);
logger.error`Copying local template path=${templateDir} failed!`;
throw err;
}
} else {
throw new Error('Invalid template.');
logger.error('Invalid template.');
process.exit(1);
}
// Update package.json info.
@ -253,7 +253,7 @@ ${chalk.cyan('Creating new Docusaurus project...')}
private: true,
});
} catch (err) {
console.log(chalk.red('Failed to update package.json.'));
logger.error('Failed to update package.json.');
throw err;
}
@ -275,7 +275,7 @@ ${chalk.cyan('Creating new Docusaurus project...')}
? name
: path.relative(process.cwd(), name);
if (!cliOptions.skipInstall) {
console.log(`Installing dependencies with ${chalk.cyan(pkgManager)}...`);
logger.info`Installing dependencies with name=${pkgManager}...`;
if (
shell.exec(
`cd "${name}" && ${useYarn ? 'yarn' : 'npm install --color always'}`,
@ -288,36 +288,35 @@ ${chalk.cyan('Creating new Docusaurus project...')}
},
).code !== 0
) {
console.error(chalk.red('Dependency installation failed.'));
console.log(`The site directory has already been created, and you can retry by typing:
logger.error('Dependency installation failed.');
logger.info`The site directory has already been created, and you can retry by typing:
${chalk.cyan('cd')} ${cdpath}
${chalk.cyan(`${pkgManager} install`)}`);
code=${`cd ${cdpath}`}
code=${`${pkgManager} install`}`;
process.exit(0);
}
}
console.log(`
Successfully created "${chalk.cyan(cdpath)}".
Inside that directory, you can run several commands:
logger.success`Created path=${cdpath}.`;
logger.info`Inside that directory, you can run several commands:
${chalk.cyan(`${pkgManager} start`)}
code=${`${pkgManager} start`}
Starts the development server.
${chalk.cyan(`${pkgManager} ${useYarn ? '' : 'run '}build`)}
code=${`${pkgManager} ${useYarn ? '' : 'run '}build`}
Bundles your website into static files for production.
${chalk.cyan(`${pkgManager} ${useYarn ? '' : 'run '}serve`)}
code=${`${pkgManager} ${useYarn ? '' : 'run '}serve`}
Serves the built website locally.
${chalk.cyan(`${pkgManager} deploy`)}
code=${`${pkgManager} deploy`}
Publishes the website to GitHub pages.
We recommend that you begin by typing:
${chalk.cyan('cd')} ${cdpath}
${chalk.cyan(`${pkgManager} start`)}
code=${`cd ${cdpath}`}
code=${`${pkgManager} start`}
Happy building awesome websites!
`);
`;
}

View file

@ -0,0 +1,4 @@
copyUntypedFiles.js
.tsbuildinfo
tsconfig*
__tests__

View file

@ -0,0 +1,44 @@
# `@docusaurus/logger`
An encapsulated logger for semantically formatting console messages.
## APIs
It exports a single object as default export: `logger`. `logger` has the following properties:
- Some useful colors.
- Formatters. These functions have the same signature as the formatters of `picocolors`. Note that their implementations are not guaranteed. You should only care about their semantics.
- `path`: formats a file path or URL.
- `id`: formats an identifier.
- `code`: formats a code snippet.
- `subdue`: subdues the text.
- `num`: formats a number.
- The `interpolate` function. It is a template literal tag.
- Logging functions. All logging functions can both be used as functions (in which it has the same usage as `console.log`) or template literal tags.
- `info`: prints information.
- `warn`: prints a warning that should be payed attention to.
- `error`: prints an error (not necessarily halting the program) that signals significant problems.
- `success`: prints a success message.
### Using the template literal tag
The template literal tag evaluates the template and expressions embedded. `interpolate` returns a new string, while other logging functions prints it. Below is a typical usage:
```js
logger.info`Hello name=${name}! You have number=${money} dollars. Here are the ${
items.length > 1 ? 'items' : 'item'
} on the shelf: ${items}
To buy anything, enter code=${'buy x'} where code=${'x'} is the item's name; to quit, press code=${'Ctrl + C'}.`;
```
An embedded expression is optionally preceded by a flag in the form `%[a-z]+` (a percentage sign followed by a few lowercase letters). If it's not preceded by any flag, it's printed out as-is. Otherwise, it's formatted with one of the formatters:
- `path=`: `path`
- `name=`: `id`
- `code=`: `code`
- `subdue=`: `subdue`
- `number=`: `num`
If the expression is an array, it's formatted by `` `\n- ${array.join('\n- ')}\n` `` (note it automatically gets a leading line end). Each member is formatted by itself and the bullet is not formatted. So you would see the above message printed as:
![demo](./demo.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View file

@ -0,0 +1,32 @@
{
"name": "@docusaurus/logger",
"version": "2.0.0-beta.13",
"description": "An encapsulated logger for semantically formatting console messages.",
"main": "./lib/index.js",
"repository": {
"type": "git",
"url": "https://github.com/facebook/docusaurus.git",
"directory": "packages/docusaurus-logger"
},
"bugs": {
"url": "https://github.com/facebook/docusaurus/issues"
},
"scripts": {
"build": "tsc",
"watch": "tsc --watch"
},
"publishConfig": {
"access": "public"
},
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
"tslib": "^2.3.1"
},
"engines": {
"node": ">=14"
},
"devDependencies": {
"@types/supports-color": "^8.1.1"
}
}

View file

@ -0,0 +1,11 @@
/**
* 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.
*/
const chalk = require('chalk');
// Force coloring the output even in CI
module.exports = new chalk.Instance({level: 3});

View file

@ -0,0 +1,73 @@
/**
* 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 logger from '../index';
describe('formatters', () => {
test('path', () => {
expect(logger.path('hey')).toMatchInlineSnapshot(`"hey"`);
});
test('id', () => {
expect(logger.name('hey')).toMatchInlineSnapshot(`"hey"`);
});
test('code', () => {
expect(logger.code('hey')).toMatchInlineSnapshot(`"\`hey\`"`);
});
test('subdue', () => {
expect(logger.subdue('hey')).toMatchInlineSnapshot(`"hey"`);
});
});
describe('interpolate', () => {
test('should format text with variables & arrays', () => {
const name = 'Josh';
const items = [1, 'hi', 'Hmmm'];
expect(logger.interpolate`Hello ${name}! Here are your goodies:${items}`)
.toMatchInlineSnapshot(`
"Hello Josh! Here are your goodies:
- 1
- hi
- Hmmm"
`);
});
test('should recognize valid flags', () => {
expect(
logger.interpolate`The package at path=${'packages/docusaurus'} has number=${10} files. name=${'Babel'} is exported here subdue=${'(as a preset)'} that you can with code=${"require.resolve('@docusaurus/core/lib/babel/preset')"}`,
).toMatchInlineSnapshot(
`"The package at packages/docusaurus has 10 files. Babel is exported here (as a preset) that you can with \`require.resolve('@docusaurus/core/lib/babel/preset')\`"`,
);
});
test('should interpolate arrays with flags', () => {
expect(
logger.interpolate`The following commands are available:code=${[
'docusaurus start',
'docusaurus build',
'docusaurus deploy',
]}`,
).toMatchInlineSnapshot(`
"The following commands are available:
- \`docusaurus start\`
- \`docusaurus build\`
- \`docusaurus deploy\`"
`);
});
test('should print detached flags as-is', () => {
expect(
logger.interpolate`You can use placeholders like code= ${'and it will'} be replaced with the succeeding arguments`,
).toMatchInlineSnapshot(
`"You can use placeholders like code= and it will be replaced with the succeeding arguments"`,
);
});
test('should throw with bad flags', () => {
expect(
() =>
logger.interpolate`I mistyped this: cde=${'this code'} and I will be damned`,
).toThrowErrorMatchingInlineSnapshot(
`"Bad Docusaurus logging message. This is likely an internal bug, please report it."`,
);
});
});

View file

@ -0,0 +1,134 @@
/**
* 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 chalk, {Chalk} from 'chalk';
type InterpolatableValue = string | number | (string | number)[];
const path = (msg: unknown): string => chalk.cyan(chalk.underline(msg));
const name = (msg: unknown): string => chalk.blue(chalk.bold(msg));
const code = (msg: unknown): string => chalk.cyan(`\`${msg}\``);
const subdue: Chalk = chalk.gray;
const num: Chalk = chalk.yellow;
function interpolate(
msgs: TemplateStringsArray,
...values: InterpolatableValue[]
): string {
let res = '';
values.forEach((value, idx) => {
const flag = msgs[idx].match(/[a-z]+=$/);
res += msgs[idx].replace(/[a-z]+=$/, '');
const format = (function () {
if (!flag) {
return (a: string | number) => a;
}
switch (flag[0]) {
case 'path=':
return path;
case 'number=':
return num;
case 'name=':
return name;
case 'subdue=':
return subdue;
case 'code=':
return code;
default:
throw new Error(
'Bad Docusaurus logging message. This is likely an internal bug, please report it.',
);
}
})();
res += Array.isArray(value)
? `\n- ${value.map((v) => format(v)).join('\n- ')}`
: format(value);
});
res += msgs.slice(-1)[0];
return res;
}
function info(msg: unknown): void;
function info(
msg: TemplateStringsArray,
...values: [InterpolatableValue, ...InterpolatableValue[]]
): void;
function info(msg: unknown, ...values: InterpolatableValue[]): void {
console.info(
`${chalk.cyan(chalk.bold('[INFO]'))} ${
values.length === 0
? msg
: interpolate(msg as TemplateStringsArray, ...values)
}`,
);
}
function warn(msg: unknown): void;
function warn(
msg: TemplateStringsArray,
...values: [InterpolatableValue, ...InterpolatableValue[]]
): void;
function warn(msg: unknown, ...values: InterpolatableValue[]): void {
console.warn(
chalk.yellow(
`${chalk.bold('[WARNING]')} ${
values.length === 0
? msg
: interpolate(msg as TemplateStringsArray, ...values)
}`,
),
);
}
function error(msg: unknown): void;
function error(
msg: TemplateStringsArray,
...values: [InterpolatableValue, ...InterpolatableValue[]]
): void;
function error(msg: unknown, ...values: InterpolatableValue[]): void {
console.error(
chalk.red(
`${chalk.bold('[ERROR]')} ${
values.length === 0
? msg
: interpolate(msg as TemplateStringsArray, ...values)
}`,
),
);
}
function success(msg: unknown): void;
function success(
msg: TemplateStringsArray,
...values: [InterpolatableValue, ...InterpolatableValue[]]
): void;
function success(msg: unknown, ...values: InterpolatableValue[]): void {
console.log(
`${chalk.green(chalk.bold('[SUCCESS]'))} ${
values.length === 0
? msg
: interpolate(msg as TemplateStringsArray, ...values)
}`,
);
}
const logger = {
red: chalk.red,
yellow: chalk.yellow,
green: chalk.green,
bold: chalk.bold,
dim: chalk.dim,
path,
name,
code,
subdue,
num,
interpolate,
info,
warn,
error,
success,
};
export default logger;

View file

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"sourceMap": true,
"declarationMap": true,
"rootDir": "src",
"outDir": "lib"
}
}

View file

@ -20,10 +20,10 @@
"dependencies": {
"@babel/parser": "^7.16.4",
"@babel/traverse": "^7.16.3",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",
"@mdx-js/mdx": "^1.6.21",
"@mdx-js/react": "^1.6.21",
"chalk": "^4.1.2",
"escape-html": "^1.0.3",
"file-loader": "^6.2.0",
"fs-extra": "^10.0.0",

View file

@ -7,7 +7,7 @@
import {readFile} from 'fs-extra';
import mdx from '@mdx-js/mdx';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import emoji from 'remark-emoji';
import {
parseFrontMatter,
@ -164,7 +164,7 @@ ${JSON.stringify(frontMatter, null, 2)}`;
if (shouldError) {
return callback(new Error(errorMessage));
} else {
console.warn(chalk.yellow(errorMessage));
logger.warn(errorMessage);
}
}
}

View file

@ -6,7 +6,9 @@
* LICENSE file in the root directory of this source tree.
*/
const chalk = require('chalk');
// @ts-check
const logger = require('@docusaurus/logger').default;
const semver = require('semver');
const cli = require('commander');
const path = require('path');
@ -18,18 +20,14 @@ const {migrateDocusaurusProject, migrateMDToMDX} = require('../lib');
function wrapCommand(fn) {
return (...args) =>
fn(...args).catch((err) => {
console.error(chalk.red(err.stack));
logger.error(err.stack);
process.exitCode = 1;
});
}
if (!semver.satisfies(process.version, requiredVersion)) {
console.log(
chalk.red(`\nMinimum Node.js version not met :(`) +
chalk.yellow(
`\n\nYou are using Node ${process.version}. We require Node.js ${requiredVersion} or up!\n`,
),
);
logger.error('Minimum Node.js version not met :(');
logger.info`You are using Node.js number=${process.version}, Requirement: Node.js number=${requiredVersion}.`;
process.exit(1);
}

View file

@ -24,8 +24,8 @@
},
"dependencies": {
"@babel/preset-env": "^7.16.4",
"@docusaurus/logger": "2.0.0-beta.13",
"@mapbox/hast-util-to-jsx": "^1.0.0",
"chalk": "^4.1.2",
"color": "^4.0.1",
"commander": "^5.1.0",
"fs-extra": "^10.0.0",

View file

@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/
import * as fs from 'fs-extra';
import fs from 'fs-extra';
import importFresh from 'import-fresh';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import glob from 'glob';
import Color from 'color';
@ -79,7 +79,7 @@ export async function migrateDocusaurusProject(
): Promise<void> {
function createMigrationContext(): MigrationContext {
const v1Config = importFresh(`${siteDir}/siteConfig`) as VersionOneConfig;
console.log('Starting migration from v1 to v2...');
logger.info('Starting migration from v1 to v2...');
const partialMigrationContext = {
siteDir,
newDir,
@ -109,85 +109,68 @@ export async function migrateDocusaurusProject(
react: '^17.0.1',
'react-dom': '^17.0.1',
};
let errorCount = 0;
try {
createClientRedirects(siteConfig, deps, config);
console.log(
chalk.green('Successfully created client redirect for non clean URL'),
);
} catch (errorInClientRedirect) {
console.log(
chalk.red(`Error while creating redirects: ${errorInClientRedirect}`),
);
logger.success('Created client redirect for non clean URL');
} catch (e) {
logger.error(`Failed to creating redirects: ${e}`);
errorCount += 1;
}
if (shouldMigratePages) {
try {
createPages(newDir, siteDir);
console.log(
chalk.green(
'Successfully created pages (check migration page for more details)',
),
);
} catch (errorInMigratingPages) {
console.log(
chalk.red(
`Error occurred while creating pages: ${errorInMigratingPages}`,
),
logger.success(
'Created new doc pages (check migration page for more details)',
);
} catch (e) {
logger.error(`Failed to create new doc pages: ${e}`);
errorCount += 1;
}
} else {
try {
createDefaultLandingPage(newDir);
console.log(
chalk.green(
'Successfully created landing page (check migration page for more details)',
),
);
} catch (errorInLandingPage) {
console.log(
chalk.red(
`Error occurred while creating landing page: ${errorInLandingPage}`,
),
logger.success(
'Created landing page (check migration page for more details)',
);
} catch (e) {
logger.error(`Failed to create landing page: ${e}`);
errorCount += 1;
}
}
try {
migrateStaticFiles(siteDir, newDir);
console.log(chalk.green('Successfully migrated static folder'));
} catch (errorInStatic) {
console.log(
chalk.red(`Error occurred while copying static folder: ${errorInStatic}`),
);
logger.success('Migrated static folder');
} catch (e) {
logger.error(`Failed to copy static folder: ${e}`);
errorCount += 1;
}
try {
migrateBlogFiles(siteDir, newDir, classicPreset, shouldMigrateMdFiles);
} catch (errorInMigratingBlogs) {
console.log(
chalk.red(
`Error occurred while migrating blogs: ${errorInMigratingBlogs}`,
),
);
} catch (e) {
logger.error(`Failed to migrate blogs: ${e}`);
errorCount += 1;
}
try {
handleVersioning(siteDir, siteConfig, newDir, config, shouldMigrateMdFiles);
} catch (errorInVersion) {
console.log(
chalk.red(
`Error occurred while migrating versioned docs: ${errorInVersion}`,
),
);
} catch (e) {
logger.error(`Failed to migrate versioned docs: ${e}`);
errorCount += 1;
}
try {
migrateLatestDocs(siteDir, newDir, shouldMigrateMdFiles, classicPreset);
} catch (errorInDoc) {
chalk.red(`Error occurred while migrating docs: ${errorInDoc}`);
} catch (e) {
logger.error(`Failed to migrate docs: ${e}`);
errorCount += 1;
}
try {
migrateLatestSidebar(siteDir, newDir, classicPreset, siteConfig);
} catch (error) {
console.log(chalk.red(`Error occurred while migrating sidebar: ${error}`));
} catch (e) {
logger.error(`Failed to migrate sidebar: ${e}`);
errorCount += 1;
}
try {
@ -195,26 +178,26 @@ export async function migrateDocusaurusProject(
path.join(newDir, 'docusaurus.config.js'),
`module.exports=${JSON.stringify(config, null, 2)}`,
);
console.log(
chalk.green(
`Successfully created a new config file with new navbar and footer config`,
),
);
} catch (error) {
console.log(
chalk.red(`Error occurred while creating config file: ${error}`),
logger.success(
`Created a new config file with new navbar and footer config`,
);
} catch (e) {
logger.error(`Failed to create config file: ${e}`);
errorCount += 1;
}
try {
migratePackageFile(siteDir, deps, newDir);
} catch (error) {
console.log(
chalk.red(
`Error occurred while creating package.json file for project: ${error}`,
),
} catch (e) {
logger.error(
`Error occurred while creating package.json file for project: ${e}`,
);
errorCount += 1;
}
if (errorCount) {
logger.warn`Migration from v1 to v2 failed with number=${errorCount} errors: please check the log above`;
} else {
logger.success('Completed migration from v1 to v2');
}
console.log('Completed migration from v1 to v2');
}
export function createConfigFile({
@ -270,11 +253,9 @@ export function createConfigFile({
customConfigFields[key] = value;
}
});
console.log(
`${chalk.yellow(
'Following Fields from siteConfig.js will be added to docusaurus.config.js in `customFields`',
)}\n${chalk.yellow(Object.keys(customConfigFields).join('\n'))}`,
);
logger.info`Following Fields from path=${'siteConfig.js'} will be added to path=${'docusaurus.config.js'} in code=${'customFields'}: ${Object.keys(
customConfigFields,
)}`;
let v2DocsPath: string | undefined;
if (siteConfig.customDocsPath) {
@ -409,12 +390,12 @@ function createPages(newDir: string, siteDir: string): void {
const content = String(fs.readFileSync(filePath));
fs.writeFileSync(filePath, migratePage(content));
});
} catch (error) {
console.log(chalk.red(`Unable to migrate Pages : ${error}`));
} catch (e) {
logger.error(`Unable to migrate Pages: ${e}`);
createDefaultLandingPage(newDir);
}
} else {
console.log('Ignoring Pages');
logger.info('Ignoring Pages');
}
}
@ -452,13 +433,9 @@ function migrateBlogFiles(
fs.writeFileSync(file, sanitizedFileContent(content, migrateMDFiles));
});
classicPreset.blog.path = 'blog';
console.log(
chalk.green(
`Successfully migrated blogs to version 2 with change in frontmatter`,
),
);
logger.success('Migrated blogs to version 2 with change in front matter');
} else {
console.log(chalk.yellow(`Blog not found. Skipping migration for blog`));
logger.warn('Blog not found. Skipping migration for blog');
}
}
@ -489,18 +466,10 @@ function handleVersioning(
versionRegex,
migrateMDFiles,
);
console.log(
chalk.green(
`Successfully migrated version docs and sidebar. The following doc versions have been created: \n${loadedVersions.join(
'\n',
)}`,
),
);
logger.success`Migrated version docs and sidebar. The following doc versions have been created:name=${loadedVersions}`;
} else {
console.log(
chalk.yellow(
'Versioned docs not found. Skipping migration for versioned docs',
),
logger.warn(
'Versioned docs not found. Skipping migration for versioned docs',
);
}
}
@ -689,9 +658,7 @@ function migrateLatestSidebar(
'sidebars.json',
);
} catch {
console.log(
chalk.yellow(`Sidebar not found. Skipping migration for sidebar`),
);
logger.warn('Sidebar not found. Skipping migration for sidebar');
}
if (siteConfig.colors) {
const primaryColor = Color(siteConfig.colors.primaryColor);
@ -732,11 +699,9 @@ function migrateLatestDocs(
const content = String(fs.readFileSync(file));
fs.writeFileSync(file, sanitizedFileContent(content, migrateMDFiles));
});
console.log(chalk.green(`Successfully migrated docs to version 2`));
logger.success('Migrated docs to version 2');
} else {
console.log(
chalk.yellow(`Docs folder not found. Skipping migration for docs`),
);
logger.warn('Docs folder not found. Skipping migration for docs');
}
}
@ -774,7 +739,7 @@ function migratePackageFile(
path.join(newDir, 'package.json'),
JSON.stringify(packageFile, null, 2),
);
console.log(chalk.green(`Successfully migrated package.json file`));
logger.success('Migrated package.json file');
}
export async function migrateMDToMDX(
@ -790,5 +755,5 @@ export async function migrateMDToMDX(
sanitizedFileContent(String(fs.readFileSync(file)), true),
);
});
console.log(`Successfully migrated ${siteDir} to ${newDir}`);
logger.success`Successfully migrated path=${siteDir} to path=${newDir}`;
}

View file

@ -19,6 +19,7 @@
"license": "MIT",
"dependencies": {
"@docusaurus/core": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",
"@docusaurus/utils-common": "2.0.0-beta.13",
"@docusaurus/utils-validation": "2.0.0-beta.13",

View file

@ -22,7 +22,7 @@ import {
ApplyTrailingSlashParams,
} from '@docusaurus/utils-common';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
export default function collectRedirects(
pluginContext: PluginContext,
@ -99,14 +99,10 @@ function filterUnwantedRedirects(
Object.entries(groupBy(redirects, (redirect) => redirect.from)).forEach(
([from, groupedFromRedirects]) => {
if (groupedFromRedirects.length > 1) {
console.error(
chalk.red(
`@docusaurus/plugin-client-redirects: multiple redirects are created with the same "from" pathname=${from}
It is not possible to redirect the same pathname to multiple destinations:
- ${groupedFromRedirects.map((r) => JSON.stringify(r)).join('\n- ')}
`,
),
);
logger.error`name=${'@docusaurus/plugin-client-redirects'}: multiple redirects are created with the same "from" pathname: path=${from}
It is not possible to redirect the same pathname to multiple destinations: ${groupedFromRedirects.map(
(r) => JSON.stringify(r),
)}`;
}
},
);
@ -117,13 +113,9 @@ It is not possible to redirect the same pathname to multiple destinations:
(redirect) => pluginContext.relativeRoutesPaths.includes(redirect.from),
);
if (redirectsOverridingExistingPath.length > 0) {
console.error(
chalk.red(
`@docusaurus/plugin-client-redirects: some redirects would override existing paths, and will be ignored:
- ${redirectsOverridingExistingPath.map((r) => JSON.stringify(r)).join('\n- ')}
`,
),
);
logger.error`name=${'@docusaurus/plugin-client-redirects'}: some redirects would override existing paths, and will be ignored: ${redirectsOverridingExistingPath.map(
(r) => JSON.stringify(r),
)}`;
}
return collectedRedirects.filter(
(redirect) => !pluginContext.relativeRoutesPaths.includes(redirect.from),

View file

@ -19,10 +19,10 @@
"license": "MIT",
"dependencies": {
"@docusaurus/core": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/mdx-loader": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",
"@docusaurus/utils-validation": "2.0.0-beta.13",
"chalk": "^4.1.2",
"escape-string-regexp": "^4.0.0",
"feed": "^4.2.2",
"fs-extra": "^10.0.0",

View file

@ -6,7 +6,7 @@
*/
import fs from 'fs-extra';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import path from 'path';
import {Author, BlogContentPaths} from './types';
import {findFolderContainingFile} from '@docusaurus/utils';
@ -48,7 +48,7 @@ export async function readAuthorsMapFile(
return validateAuthorsMapFile(unsafeContent);
} catch (e) {
// TODO replace later by error cause: see https://v8.dev/features/error-cause
console.error(chalk.red('The author list file looks invalid!'));
logger.error('The author list file looks invalid!');
throw e;
}
}
@ -88,9 +88,7 @@ export async function getAuthorsMap(
return await readAuthorsMapFile(filePath);
} catch (e) {
// TODO replace later by error cause, see https://v8.dev/features/error-cause
console.error(
chalk.red(`Couldn't read blog authors map at path ${filePath}`),
);
logger.error`Couldn't read blog authors map at path=${filePath}`;
throw e;
}
}

View file

@ -6,7 +6,6 @@
*/
import fs from 'fs-extra';
import chalk from 'chalk';
import path from 'path';
import readingTime from 'reading-time';
import {keyBy, mapValues} from 'lodash';
@ -33,6 +32,7 @@ import {
import {LoadContext} from '@docusaurus/types';
import {validateBlogPostFrontMatter} from './blogFrontMatter';
import {AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors';
import logger from '@docusaurus/logger';
export function truncate(fileString: string, truncateMarker: RegExp): string {
return fileString.split(truncateMarker, 1).shift()!;
@ -151,11 +151,7 @@ async function processBlogSourceFile(
}
if (frontMatter.id) {
console.warn(
chalk.yellow(
`"id" header option is deprecated in ${blogSourceRelative} file. Please use "slug" option instead.`,
),
);
logger.warn`name=${'id'} header option is deprecated in path=${blogSourceRelative} file. Please use name=${'slug'} option instead.`;
}
const parsedBlogFileName = parseBlogFileName(blogSourceRelative);
@ -276,11 +272,7 @@ export async function generateBlogPosts(
authorsMap,
);
} catch (e) {
console.error(
chalk.red(
`Processing of blog source file failed for path "${blogSourceFile}"`,
),
);
logger.error`Processing of blog source file failed for path path=${blogSourceFile}.`;
throw e;
}
}),

View file

@ -19,10 +19,10 @@
"license": "MIT",
"dependencies": {
"@docusaurus/core": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/mdx-loader": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",
"@docusaurus/utils-validation": "2.0.0-beta.13",
"chalk": "^4.1.2",
"combine-promises": "^1.1.0",
"escape-string-regexp": "^4.0.0",
"fs-extra": "^10.0.0",

View file

@ -221,7 +221,11 @@ describe('docsVersion', () => {
getVersionsFilePath(simpleSiteDir, DEFAULT_PLUGIN_ID),
);
expect(versions).toEqual(['1.0.0']);
expect(consoleMock).toHaveBeenCalledWith('[docs]: version 1.0.0 created!');
expect(consoleMock).toHaveBeenCalledWith(
expect.stringMatching(
/.*\[SUCCESS\].* .*\[docs\].*: version .*1\.0\.0.* created!.*/,
),
);
copyMock.mockRestore();
writeMock.mockRestore();
@ -274,7 +278,11 @@ describe('docsVersion', () => {
getVersionsFilePath(versionedSiteDir, DEFAULT_PLUGIN_ID),
);
expect(versions).toEqual(['2.0.0', '1.0.1', '1.0.0', 'withSlugs']);
expect(consoleMock).toHaveBeenCalledWith('[docs]: version 2.0.0 created!');
expect(consoleMock).toHaveBeenCalledWith(
expect.stringMatching(
/.*\[SUCCESS\].* .*\[docs\].*: version .*2\.0\.0.* created!.*/,
),
);
copyMock.mockRestore();
writeMock.mockRestore();
@ -326,7 +334,9 @@ describe('docsVersion', () => {
);
expect(versions).toEqual(['2.0.0', '1.0.0']);
expect(consoleMock).toHaveBeenCalledWith(
'[community]: version 2.0.0 created!',
expect.stringMatching(
/.*\[SUCCESS\].* .*\[community\].*: version .*2.0.0.* created!.*/,
),
);
copyMock.mockRestore();

View file

@ -29,8 +29,7 @@ describe('lastUpdate', () => {
});
test('non-existing file', async () => {
const consoleMock = jest.spyOn(console, 'error');
consoleMock.mockImplementation();
const consoleMock = jest.spyOn(console, 'error').mockImplementation();
const nonExistingFileName = '.nonExisting';
const nonExistingFilePath = path.join(
__dirname,
@ -39,8 +38,8 @@ describe('lastUpdate', () => {
);
expect(await getFileLastUpdate(nonExistingFilePath)).toBeNull();
expect(consoleMock).toHaveBeenCalledTimes(1);
expect(consoleMock.mock.calls[0][0].message).toContain(
' with exit code 128',
expect(consoleMock).toHaveBeenLastCalledWith(
expect.stringMatching(/with exit code 128/),
);
expect(await getFileLastUpdate(null)).toBeNull();
expect(await getFileLastUpdate(undefined)).toBeNull();
@ -60,7 +59,9 @@ describe('lastUpdate', () => {
const lastUpdateData = await getFileLastUpdate(existingFilePath);
expect(lastUpdateData).toBeNull();
expect(consoleMock).toHaveBeenLastCalledWith(
'Sorry, the docs plugin last update options require Git.',
expect.stringMatching(
/.*\[WARNING\].* Sorry, the docs plugin last update options require Git\..*/,
),
);
consoleMock.mockRestore();

View file

@ -15,6 +15,7 @@ import path from 'path';
import type {PathOptions, SidebarOptions} from './types';
import {loadSidebarsFile, resolveSidebarPathOption} from './sidebars';
import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
import logger from '@docusaurus/logger';
function createVersionedSidebarFile({
siteDir,
@ -133,5 +134,5 @@ export function cliDocsVersionCommand(
fs.ensureDirSync(path.dirname(versionsJSONFile));
fs.writeFileSync(versionsJSONFile, `${JSON.stringify(versions, null, 2)}\n`);
console.log(`${pluginIdLogPrefix}: version ${version} created!`);
logger.success`name=${pluginIdLogPrefix}: version name=${version} created!`;
}

View file

@ -7,7 +7,7 @@
import path from 'path';
import fs from 'fs-extra';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {keyBy, last} from 'lodash';
import {
aliasedSitePath,
@ -274,11 +274,7 @@ export function processDocMetadata(args: {
try {
return doProcessDocMetadata(args);
} catch (e) {
console.error(
chalk.red(
`Can't process doc metadata for doc at path "${args.docFile.filePath}" in version "${args.versionMetadata.versionName}"`,
),
);
logger.error`Can't process doc metadata for doc at path path=${args.docFile.filePath} in version name=${args.versionMetadata.versionName}`;
throw e;
}
}

View file

@ -51,7 +51,7 @@ import {
translateLoadedContent,
getLoadedContentTranslationFiles,
} from './translations';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {getVersionTags} from './tags';
import {createVersionRoutes} from './routes';
import type {PropTagsListPage} from '@docusaurus/plugin-content-docs';
@ -203,11 +203,7 @@ export default function pluginContentDocs(
try {
return await doLoadVersion(versionMetadata);
} catch (e) {
console.error(
chalk.red(
`Loading of version failed for version "${versionMetadata.versionName}"`,
),
);
logger.error`Loading of version failed for version name=${versionMetadata.versionName}`;
throw e;
}
}

View file

@ -6,6 +6,7 @@
*/
import shell from 'shelljs';
import logger from '@docusaurus/logger';
type FileLastUpdateData = {timestamp?: number; author?: string};
@ -36,7 +37,7 @@ export async function getFileLastUpdate(
if (!shell.which('git')) {
if (!showedGitRequirementError) {
showedGitRequirementError = true;
console.warn('Sorry, the docs plugin last update options require Git.');
logger.warn('Sorry, the docs plugin last update options require Git.');
}
return null;
@ -51,8 +52,8 @@ export async function getFileLastUpdate(
);
}
return getTimestampAndAuthor(result.stdout.trim());
} catch (error) {
console.error(error);
} catch (e) {
logger.error(e);
}
return null;

View file

@ -19,7 +19,7 @@ import type {
OptionValidationContext,
ValidationResult,
} from '@docusaurus/types';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import admonitions from 'remark-admonitions';
import {DefaultSidebarItemsGenerator} from './sidebars/generator';
import {
@ -157,11 +157,7 @@ export function validateOptions({
};
}
if (options.sidebarCollapsed) {
console.warn(
chalk.yellow(
'The docs plugin config is inconsistent. It does not make sense to use sidebarCollapsible=false and sidebarCollapsed=true at the same time. sidebarCollapsed=false will be ignored.',
),
);
logger.warn`The docs plugin config is inconsistent. It does not make sense to use code=${'sidebarCollapsible: false'} and code=${'sidebarCollapsed: true'} at the same time. code=${'sidebarCollapsed: true'} will be ignored.`;
options = {
...options,
sidebarCollapsed: false,

View file

@ -14,7 +14,7 @@ import {
} from './types';
import type {PropCategoryGeneratedIndex} from '@docusaurus/plugin-content-docs';
import {toVersionMetadataProp} from './props';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
export async function createCategoryGeneratedIndexRoutes({
version,
@ -163,11 +163,7 @@ export async function createVersionRoutes({
try {
return await doCreateVersionRoutes(loadedVersion);
} catch (e) {
console.error(
chalk.red(
`Can't create version routes for version "${loadedVersion.versionName}"`,
),
);
logger.error`Can't create version routes for version name=${loadedVersion.versionName}`;
throw e;
}
}

View file

@ -57,7 +57,7 @@ describe('DefaultSidebarItemsGenerator', () => {
expect(sidebarSlice).toEqual([]);
expect(consoleWarn).toHaveBeenCalledWith(
expect.stringMatching(
/No docs found in dir .: can't auto-generate a sidebar/,
/.*\[WARNING\].* No docs found in .*\..*: can't auto-generate a sidebar\..*/,
),
);
});

View file

@ -16,7 +16,7 @@ import type {
} from './types';
import {sortBy, last} from 'lodash';
import {addTrailingSlash, posixPath} from '@docusaurus/utils';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import path from 'path';
import fs from 'fs-extra';
import Yaml from 'js-yaml';
@ -72,11 +72,7 @@ async function readCategoryMetadataFile(
try {
return validateCategoryMetadataFile(unsafeContent);
} catch (e) {
console.error(
chalk.red(
`The docs sidebar category metadata file looks invalid!\nPath: ${filePath}`,
),
);
logger.error`The docs sidebar category metadata file path=${filePath} looks invalid!`;
throw e;
}
}
@ -134,11 +130,7 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({
const docs = allDocs.filter(isInAutogeneratedDir);
if (docs.length === 0) {
console.warn(
chalk.yellow(
`No docs found in dir ${autogenDir}: can't auto-generate a sidebar.`,
),
);
logger.warn`No docs found in path=${autogenDir}: can't auto-generate a sidebar.`;
}
return docs;
}

View file

@ -33,7 +33,6 @@
"@docusaurus/utils-validation": "2.0.0-beta.13",
"@mdx-js/mdx": "^1.6.21",
"@mdx-js/react": "^1.6.21",
"chalk": "^4.1.2",
"clsx": "^1.1.1",
"copy-text-to-clipboard": "^3.0.1",
"globby": "^11.0.2",

View file

@ -22,6 +22,7 @@
"dependencies": {
"@docsearch/react": "^3.0.0-alpha.39",
"@docusaurus/core": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/theme-common": "2.0.0-beta.13",
"@docusaurus/theme-translations": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",

View file

@ -10,6 +10,7 @@ import fs from 'fs';
import {defaultConfig, compile} from 'eta';
import {normalizeUrl, getSwizzledComponent} from '@docusaurus/utils';
import {readDefaultCodeTranslationMessages} from '@docusaurus/theme-translations';
import logger from '@docusaurus/logger';
import openSearchTemplate from './templates/opensearch';
import {memoize} from 'lodash';
@ -83,9 +84,9 @@ export default function theme(
favicon: favicon ? normalizeUrl([url, baseUrl, favicon]) : null,
}),
);
} catch (err) {
console.error(err);
throw new Error(`Generating OpenSearch file failed: ${err}`);
} catch (e) {
logger.error('Generating OpenSearch file failed.');
throw e;
}
},

View file

@ -23,7 +23,8 @@
"tslib": "^2.3.1"
},
"devDependencies": {
"chalk": "^4.1.2",
"@docusaurus/core": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"lodash": "^4.17.20"
},
"engines": {

View file

@ -5,9 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
// @ts-check
/* eslint-disable import/no-extraneous-dependencies */
const chalk = require('chalk');
const logger = require('@docusaurus/logger').default;
const path = require('path');
const fs = require('fs-extra');
const {mapValues, pickBy, difference, orderBy} = require('lodash');
@ -69,17 +70,10 @@ function sortObjectKeys(obj) {
}, {});
}
function logSection(title) {
console.log(``);
console.log(``);
console.log(`##############################`);
console.log(`## ${chalk.blue(title)}`);
}
function logKeys(keys) {
return `Keys:\n- ${keys.join('\n- ')}`;
}
/**
* @param {string[]} targetDirs
* @returns {Promise<import('@docusaurus/types').TranslationFileContent>}
*/
async function extractThemeCodeMessages(targetDirs = AllThemesSrcDirs) {
// Unsafe import, should we create a package for the translationsExtractor ?
const {
@ -122,7 +116,7 @@ ${warning}
}
async function readMessagesFile(filePath) {
return JSON.parse(await fs.readFile(filePath));
return JSON.parse((await fs.readFile(filePath)).toString());
}
async function writeMessagesFile(filePath, messages) {
@ -130,11 +124,11 @@ async function writeMessagesFile(filePath, messages) {
const content = `${JSON.stringify(sortedMessages, null, 2)}\n`; // \n makes prettier happy
await fs.outputFile(filePath, content);
console.log(
`${path.basename(filePath)} updated (${
Object.keys(sortedMessages).length
} messages)`,
);
logger.info`path=${path.basename(
filePath,
)} updated subdue=${logger.interpolate`(number=${
Object.keys(sortedMessages).length
} messages)`}\n`;
}
async function getCodeTranslationFiles(themeName) {
@ -166,11 +160,8 @@ async function updateBaseFile(baseFile, targetDirs) {
);
if (unknownMessages.length) {
console.log(
chalk.red(`Some messages exist in base locale but were not found by the code extractor!
They won't be removed automatically, so do the cleanup manually if necessary!
${logKeys(unknownMessages)}`),
);
logger.error`Some messages exist in base locale but were not found by the code extractor!
They won't be removed automatically, so do the cleanup manually if necessary! code=${unknownMessages}`;
}
const newBaseMessages = {
@ -210,11 +201,8 @@ async function updateLocaleCodeTranslations(localeFile, baseFileMessages) {
);
if (unknownMessages.length) {
console.log(
chalk.red(`Some localized messages do not exist in base.json!
You may want to delete these!
${logKeys(unknownMessages)}`),
);
logger.error`Some localized messages do not exist in base.json!
You may want to delete these! code=${unknownMessages}`;
}
const newLocaleFileMessages = {
@ -227,10 +215,7 @@ ${logKeys(unknownMessages)}`),
.map(([key]) => key);
if (untranslatedKeys.length) {
console.warn(
chalk.yellow(`Some messages do not seem to be translated!
${logKeys(untranslatedKeys)}`),
);
logger.warn`Some messages do not seem to be translated! code=${untranslatedKeys}`;
}
await writeMessagesFile(localeFile, newLocaleFileMessages);
@ -241,7 +226,7 @@ async function updateCodeTranslations() {
// eslint-disable-next-line no-restricted-syntax
for (const theme of Themes) {
const {baseFile, localesFiles} = await getCodeTranslationFiles(theme.name);
logSection(`Will update base file for ${theme.name}`);
logger.info`Will update base file for name=${theme.name}\n`;
const baseFileMessages = await updateBaseFile(baseFile, theme.src);
const [, newLocale] = process.argv;
@ -250,26 +235,23 @@ async function updateCodeTranslations() {
if (!fs.existsSync(newLocalePath)) {
await writeMessagesFile(newLocalePath, baseFileMessages);
console.error(
chalk.green(
`Locale file ${path.basename(newLocalePath)} have been created.`,
),
);
logger.success`Locale file path=${path.basename(
newLocalePath,
)} have been created.`;
} else {
console.error(
chalk.red(
`Locale file ${path.basename(newLocalePath)} was already created!`,
),
);
logger.warn`Locale file path=${path.basename(
newLocalePath,
)} was already created!`;
}
} else {
// eslint-disable-next-line no-restricted-syntax
for (const localeFile of localesFiles) {
logSection(
`Will update ${path.basename(
path.dirname(localeFile),
)} locale in ${path.basename(localeFile, path.extname(localeFile))}`,
);
logger.info`Will update name=${path.basename(
path.dirname(localeFile),
)} locale in name=${path.basename(
localeFile,
path.extname(localeFile),
)}`;
await updateLocaleCodeTranslations(localeFile, baseFileMessages);
}
@ -280,16 +262,12 @@ async function updateCodeTranslations() {
function run() {
updateCodeTranslations().then(
() => {
console.log('');
console.log(chalk.green('updateCodeTranslations end'));
console.log('');
logger.success('updateCodeTranslations end\n');
},
(e) => {
console.log('');
console.error(chalk.red(`updateCodeTranslations failure: ${e.message}`));
console.log('');
console.error(e.stack);
console.log('');
logger.error(
`\nupdateCodeTranslations failure: ${e.message}\n${e.stack}\n`,
);
process.exit(1);
},
);

View file

@ -18,8 +18,8 @@
},
"license": "MIT",
"dependencies": {
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/utils": "2.0.0-beta.13",
"chalk": "^4.1.2",
"joi": "^17.4.2",
"tslib": "^2.3.1"
},

View file

@ -6,7 +6,7 @@
*/
import Joi from './Joi';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {PluginIdSchema} from './validationSchemas';
// TODO temporary escape hatch for alpha-60: to be removed soon
@ -19,21 +19,14 @@ export const isValidationDisabledEscapeHatch =
process.env.DISABLE_DOCUSAURUS_VALIDATION === 'true';
if (isValidationDisabledEscapeHatch) {
console.error(
chalk.red(
'You should avoid using DISABLE_DOCUSAURUS_VALIDATION escape hatch, this will be removed.',
),
);
logger.error`You should avoid using code=${'DISABLE_DOCUSAURUS_VALIDATION'} escape hatch, this will be removed.`;
}
export const logValidationBugReportHint = (): void => {
console.log(
`\n${chalk.red('A validation error occurred.')}${chalk.cyanBright(
'\nThe validation system was added recently to Docusaurus as an attempt to avoid user configuration errors.' +
'\nWe may have made some mistakes.' +
'\nIf you think your configuration is valid and should keep working, please open a bug report.',
)}\n`,
);
logger.error('A validation error occurred.');
logger.info(`The validation system was added recently to Docusaurus as an attempt to avoid user configuration errors.
We may have made some mistakes.
If you think your configuration is valid and should keep working, please open a bug report.`);
};
export function printWarning(warning?: Joi.ValidationError): void {
@ -41,7 +34,7 @@ export function printWarning(warning?: Joi.ValidationError): void {
const warningMessages = warning.details
.map(({message}) => message)
.join('\n');
console.log(chalk.yellow(warningMessages));
logger.warn(warningMessages);
}
}
@ -63,7 +56,7 @@ export function normalizePluginOptions<T extends {id?: string}>(
if (error) {
logValidationBugReportHint();
if (isValidationDisabledEscapeHatch) {
console.error(error);
logger.error(error);
return options as T;
} else {
throw error;
@ -91,7 +84,7 @@ export function normalizeThemeConfig<T>(
if (error) {
logValidationBugReportHint();
if (isValidationDisabledEscapeHatch) {
console.error(error);
logger.error(error);
return themeConfig as T;
} else {
throw error;
@ -116,19 +109,14 @@ export function validateFrontMatter<T>(
const frontMatterString = JSON.stringify(frontMatter, null, 2);
const errorDetails = error.details;
const invalidFields = errorDetails.map(({path}) => path).join(', ');
const errorMessages = errorDetails
.map(({message}) => ` - ${message}`)
.join('\n');
logValidationBugReportHint();
console.error(
chalk.red(
`The following frontmatter:\n${chalk.yellow(
frontMatterString,
)}\ncontains invalid values for field(s): ${invalidFields}.\n${errorMessages}\n`,
),
);
logger.error`The following frontmatter:
${logger.yellow(frontMatterString)}
contains invalid values for field(s): ${logger.yellow(invalidFields)}.
${errorDetails.map(({message}) => message)}
`;
throw error;
}

View file

@ -18,9 +18,9 @@
},
"license": "MIT",
"dependencies": {
"@docusaurus/logger": "2.0.0-beta.13",
"@mdx-js/runtime": "^1.6.22",
"@svgr/webpack": "^6.0.0",
"chalk": "^4.1.2",
"escape-string-regexp": "^4.0.0",
"file-loader": "^6.2.0",
"fs-extra": "^10.0.0",
@ -44,7 +44,8 @@
"@types/github-slugger": "^1.3.0",
"@types/micromatch": "^4.0.2",
"@types/react-dom": "^17.0.1",
"dedent": "^0.7.0"
"dedent": "^0.7.0",
"tslib": "^2.3.1"
},
"peerDependencies": {
"react": "*",

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import path from 'path';
import {createHash} from 'crypto';
import {camelCase, mapValues} from 'lodash';
@ -369,13 +369,13 @@ export function reportMessage(
case 'ignore':
break;
case 'log':
console.log(chalk.bold.blue('info ') + chalk.blue(message));
logger.info(message);
break;
case 'warn':
console.warn(chalk.bold.yellow('warn ') + chalk.yellow(message));
logger.warn(message);
break;
case 'error':
console.error(chalk.bold.red('error ') + chalk.red(message));
logger.error(message);
break;
case 'throw':
throw new Error(message);

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import fs from 'fs-extra';
import matter from 'gray-matter';
@ -166,10 +166,8 @@ export function parseMarkdownString(
excerpt,
};
} catch (e) {
console.error(
chalk.red(`Error while parsing Markdown frontmatter.
This can happen if you use special characters in frontmatter values (try using double quotes around that value).`),
);
logger.error(`Error while parsing Markdown frontmatter.
This can happen if you use special characters in frontmatter values (try using double quotes around that value).`);
throw e;
}
}

View file

@ -5,7 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/
const chalk = require('chalk');
// @ts-check
const logger = require('@docusaurus/logger').default;
const fs = require('fs-extra');
const semver = require('semver');
const path = require('path');
@ -53,7 +55,7 @@ try {
}
} catch (e) {
// Do not stop cli if this fails, see https://github.com/facebook/docusaurus/issues/5400
console.error(e);
logger.error(e);
}
// We don't want to display update message for canary releases
@ -74,6 +76,7 @@ if (
notifier.config.set('update', notifier.update);
if (ignoreUpdate(notifier.update)) {
// @ts-expect-error: it works
return;
}
@ -91,6 +94,7 @@ if (
? `yarn upgrade ${siteDocusaurusPackagesForUpdate}`
: `npm i ${siteDocusaurusPackagesForUpdate}`;
/** @type {import('boxen').Options} */
const boxenOptions = {
padding: 1,
margin: 1,
@ -100,13 +104,12 @@ if (
};
const docusaurusUpdateMessage = boxen(
`Update available ${chalk.dim(`${notifier.update.current}`)}${chalk.reset(
' → ',
)}${chalk.green(
`${notifier.update.latest}`,
)}\n\nTo upgrade Docusaurus packages with the latest version, run the following command:\n${chalk.cyan(
`${upgradeCommand}`,
)}`,
`Update available ${logger.dim(
`${notifier.update.current}`,
)} ${logger.green(`${notifier.update.latest}`)}
To upgrade Docusaurus packages with the latest version, run the following command:
${logger.code(upgradeCommand)}`,
boxenOptions,
);
@ -115,11 +118,7 @@ if (
// notify user if node version needs to be updated
if (!semver.satisfies(process.version, requiredVersion)) {
console.log(
chalk.red(`\nMinimum Node version not met :(`) +
chalk.yellow(
`\n\nYou are using Node ${process.version}. We require Node ${requiredVersion} or up!\n`,
),
);
logger.error('Minimum Node.js version not met :(');
logger.info`You are using Node.js number=${process.version}, Requirement: Node.js number=${requiredVersion}.`;
process.exit(1);
}

View file

@ -6,7 +6,9 @@
* LICENSE file in the root directory of this source tree.
*/
const chalk = require('chalk');
// @ts-check
const logger = require('@docusaurus/logger').default;
const fs = require('fs');
const cli = require('commander');
const {
@ -219,8 +221,7 @@ cli
cli.arguments('<command>').action((cmd) => {
cli.outputHelp();
console.log(` ${chalk.red(`\n Unknown command ${chalk.yellow(cmd)}.`)}.`);
console.log();
logger.error` Unknown command name=${cmd}.`;
});
function isInternalCommand(command) {
@ -238,6 +239,7 @@ function isInternalCommand(command) {
async function run() {
if (!isInternalCommand(process.argv.slice(2)[0])) {
// @ts-expect-error: Hmmm
await externalCommand(cli, resolveDir('.'));
}
@ -251,6 +253,6 @@ async function run() {
run();
process.on('unhandledRejection', (err) => {
console.error(chalk.red(err.stack));
logger.error(err.stack);
process.exit(1);
});

View file

@ -42,6 +42,7 @@
"@babel/runtime-corejs3": "^7.16.3",
"@babel/traverse": "^7.16.3",
"@docusaurus/cssnano-preset": "2.0.0-beta.13",
"@docusaurus/logger": "2.0.0-beta.13",
"@docusaurus/mdx-loader": "2.0.0-beta.13",
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/utils": "2.0.0-beta.13",
@ -53,7 +54,6 @@
"babel-loader": "^8.2.2",
"babel-plugin-dynamic-import-node": "2.3.0",
"boxen": "^5.0.1",
"chalk": "^4.1.2",
"chokidar": "^3.5.2",
"clean-css": "^5.1.5",
"commander": "^5.1.0",

View file

@ -13,7 +13,7 @@
import {execSync} from 'child_process';
import detect from 'detect-port';
import isRoot from 'is-root';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import prompts from 'prompts';
const isInteractive = process.stdout.isTTY;
@ -68,12 +68,7 @@ function getProcessForPort(port: number): string | null {
const processId = getProcessIdOnPort(port);
const directory = getDirectoryOfProcessById(processId);
const command = getProcessCommand(processId);
return (
chalk.cyan(command) +
chalk.grey(` (pid ${processId})\n`) +
chalk.blue(' in ') +
chalk.cyan(directory)
);
return logger.interpolate`code=${command} subdue=${`(pid ${processId})`} in path=${directory}`;
} catch (e) {
return null;
}
@ -104,11 +99,11 @@ export default async function choosePort(
const question: prompts.PromptObject = {
type: 'confirm',
name: 'shouldChangePort',
message: `${chalk.yellow(
`${message}${
existingProcess ? ` Probably:\n ${existingProcess}` : ''
}`,
)}\n\nWould you like to run the app on another port instead?`,
message: logger.yellow(`${logger.bold('[WARNING]')} ${message}${
existingProcess ? ` Probably:\n ${existingProcess}` : ''
}
Would you like to run the app on another port instead?`),
initial: true,
};
prompts(question).then((answer) => {
@ -119,15 +114,14 @@ export default async function choosePort(
}
});
} else {
console.log(chalk.red(message));
logger.error(message);
resolve(null);
}
}),
(err) => {
throw new Error(
`${chalk.red(`Could not find an open port at ${chalk.bold(host)}.`)}\n${
`Network error message: "${err.message}".` || err
}\n`,
`Could not find an open port at ${host}.
${`Network error message: "${err.message || err}".`}`,
);
},
);

View file

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
// @ts-check
import * as eta from 'eta';
import React from 'react';
import {StaticRouter} from 'react-router-dom';
@ -24,7 +26,7 @@ import {
createStatefulLinksCollector,
ProvideLinksCollector,
} from './LinksCollector';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
// eslint-disable-next-line no-restricted-imports
import {memoize} from 'lodash';
@ -43,21 +45,16 @@ export default async function render(locals) {
try {
return await doRender(locals);
} catch (e) {
console.error(
chalk.red(
`Docusaurus Node/SSR could not render static page with path "${locals.path}" because of following error:\n\n${e.stack}\n`,
),
);
logger.error`Docusaurus Node/SSR could not render static page with path path=${locals.path} because of following error:
${e.stack}`;
const isNotDefinedErrorRegex =
/(window|document|localStorage|navigator|alert|location|buffer|self) is not defined/i;
if (isNotDefinedErrorRegex.test(e.message)) {
console.error(
chalk.green(
'Pro tip: It looks like you are using code that should run on the client-side only.\nTo get around it, try using <BrowserOnly> (https://docusaurus.io/docs/docusaurus-core/#browseronly) or ExecutionEnvironment (https://docusaurus.io/docs/docusaurus-core/#executionenvironment).\nIt might also require to wrap your client code in useEffect hook and/or import a third-party library dynamically (if any).',
),
);
logger.info`It looks like you are using code that should run on the client-side only.
To get around it, try using code=${'<BrowserOnly>'} (path=${'https://docusaurus.io/docs/docusaurus-core/#browseronly'}) or code=${'ExecutionEnvironment'} (path=${'https://docusaurus.io/docs/docusaurus-core/#executionenvironment'}).
It might also require to wrap your client code in code=${'useEffect'} hook and/or import a third-party library dynamically (if any).`;
}
throw new Error('Server-side rendering fails due to the error above.');
@ -142,11 +139,8 @@ async function doRender(locals) {
minifyJS: true,
});
} catch (e) {
console.error(
chalk.red(
`Minification page with path "${locals.path}" failed because of following error:\n\n${e.stack}\n`,
),
);
logger.error`Minification of page path=${locals.path} failed because of following error:
${e.stack}`;
throw e;
}
}

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import CopyWebpackPlugin from 'copy-webpack-plugin';
import fs from 'fs-extra';
import path from 'path';
@ -47,7 +47,6 @@ export default async function build(
isLastLocale: boolean;
}) {
try {
// console.log(chalk.green(`Site successfully built in locale=${locale}`));
return await buildLocale({
siteDir,
locale,
@ -56,7 +55,7 @@ export default async function build(
isLastLocale,
});
} catch (e) {
console.error(`Unable to build website for locale "${locale}".`);
logger.error`Unable to build website for locale name=${locale}.`;
throw e;
}
}
@ -73,12 +72,7 @@ export default async function build(
return tryToBuildLocale({locale: cliOptions.locale, isLastLocale: true});
} else {
if (i18n.locales.length > 1) {
console.log(
chalk.yellow(
`\nWebsite will be built for all these locales:
- ${i18n.locales.join('\n- ')}`,
),
);
logger.info`Website will be built for all these locales: ${i18n.locales}`;
}
// We need the default locale to always be the 1st in the list
@ -112,9 +106,7 @@ async function buildLocale({
}): Promise<string> {
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
console.log(
chalk.blue(`\n[${locale}] Creating an optimized production build...`),
);
logger.info`name=${`[${locale}]`} Creating an optimized production build...`;
const props: Props = await load(siteDir, {
customOutDir: cliOptions.outDir,
@ -238,18 +230,13 @@ async function buildLocale({
baseUrl,
});
console.log(
`${chalk.green(`Success!`)} Generated static files in "${chalk.cyan(
path.relative(process.cwd(), outDir),
)}".`,
);
logger.success`Generated static files in path=${path.relative(
process.cwd(),
outDir,
)}.`;
if (isLastLocale) {
console.log(
`\nUse ${chalk.greenBright(
'`npm run serve`',
)} command to test your build locally.\n`,
);
logger.info`Use code=${'npm run serve'} command to test your build locally.`;
}
if (forceTerminate && isLastLocale && !cliOptions.bundleAnalyzer) {

View file

@ -7,22 +7,20 @@
import fs from 'fs-extra';
import path from 'path';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {
DEFAULT_BUILD_DIR_NAME,
GENERATED_FILES_DIR_NAME,
} from '@docusaurus/utils';
function removePath(fsPath: string) {
return fs
.remove(path.join(fsPath))
.then(() => {
console.log(chalk.green(`Successfully removed "${fsPath}" directory.`));
})
.catch((err) => {
console.error(`Could not remove ${fsPath} directory.`);
console.error(err);
});
async function removePath(fsPath: string) {
try {
fs.remove(path.join(fsPath));
logger.success`Removed the path=${fsPath} directory.`;
} catch (e) {
logger.error`Could not remove path=${fsPath} directory.
${e as string}`;
}
}
export default async function clear(siteDir: string): Promise<unknown> {

View file

@ -7,7 +7,7 @@
import fs from 'fs-extra';
import shell from 'shelljs';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {loadContext} from '../server';
import build from './build';
import {BuildCLIOptions} from '@docusaurus/types';
@ -25,14 +25,10 @@ function obfuscateGitPass(str: string) {
function shellExecLog(cmd: string) {
try {
const result = shell.exec(cmd);
console.log(
`${chalk.cyan('CMD:')} ${obfuscateGitPass(cmd)} ${chalk.cyan(
`(code: ${result.code})`,
)}`,
);
logger.info`code=${obfuscateGitPass(cmd)} subdue=${`code: ${result.code}`}`;
return result;
} catch (e) {
console.log(`${chalk.red('CMD:')} ${obfuscateGitPass(cmd)}`);
logger.error`code=${obfuscateGitPass(cmd)}`;
throw e;
}
}
@ -84,17 +80,13 @@ export default async function deploy(
});
if (typeof siteConfig.trailingSlash === 'undefined') {
console.warn(
chalk.yellow(`
Docusaurus recommendation:
When deploying to GitHub Pages, it is better to use an explicit "trailingSlash" site config.
logger.warn(`When deploying to GitHub Pages, it is better to use an explicit "trailingSlash" site config.
Otherwise, GitHub Pages will add an extra trailing slash to your site urls only on direct-access (not when navigation) with a server redirect.
This behavior can have SEO impacts and create relative link issues.
`),
);
`);
}
console.log('Deploy command invoked...');
logger.info('Deploy command invoked...');
if (!shell.which('git')) {
throw new Error('Git not installed or on the PATH!');
}
@ -135,7 +127,7 @@ This behavior can have SEO impacts and create relative link issues.
`Missing project organization name. Did you forget to define "organizationName" in ${siteConfigPath}? You may also export it via the ORGANIZATION_NAME environment variable.`,
);
}
console.log(`${chalk.cyan('organizationName:')} ${organizationName}`);
logger.info`organizationName: name=${organizationName}`;
const projectName =
process.env.PROJECT_NAME ||
@ -146,7 +138,7 @@ This behavior can have SEO impacts and create relative link issues.
`Missing project name. Did you forget to define "projectName" in ${siteConfigPath}? You may also export it via the PROJECT_NAME environment variable.`,
);
}
console.log(`${chalk.cyan('projectName:')} ${projectName}`);
logger.info`projectName: name=${projectName}`;
// We never deploy on pull request.
const isPullRequest =
@ -173,7 +165,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
const deploymentBranch =
process.env.DEPLOYMENT_BRANCH || siteConfig.deploymentBranch || 'gh-pages';
console.log(`${chalk.cyan('deploymentBranch:')} ${deploymentBranch}`);
logger.info`deploymentBranch: name=${deploymentBranch}`;
const githubHost =
process.env.GITHUB_HOST || siteConfig.githubHost || 'github.com';
@ -199,9 +191,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
);
}
console.log(
`${chalk.cyan('Remote repo URL:')} ${obfuscateGitPass(deploymentRepoURL)}`,
);
logger.info`Remote repo URL: name=${obfuscateGitPass(deploymentRepoURL)}`;
// Check if this is a cross-repo publish.
const crossRepoPublish = !sourceRepoUrl.endsWith(
@ -283,7 +273,7 @@ You can also set the deploymentBranch property in docusaurus.config.js .`);
try {
await runDeploy(await build(siteDir, cliOptions, false));
} catch (buildError) {
console.error(buildError);
logger.error((buildError as Error).message);
process.exit(1);
}
} else {

View file

@ -7,8 +7,7 @@
import http from 'http';
import serveHandler from 'serve-handler';
import boxen from 'boxen';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import path from 'path';
import {loadSiteConfig} from '../server';
import build from './build';
@ -71,18 +70,8 @@ export default async function serve(
});
});
console.log(
boxen(
chalk.green(
`Serving "${cliOptions.dir}" directory at "${servingUrl + baseUrl}".`,
),
{
borderColor: 'green',
padding: 1,
margin: 1,
align: 'center',
},
),
);
logger.success`Serving path=${cliOptions.dir} directory at path=${
servingUrl + baseUrl
}.`;
server.listen(port);
}

View file

@ -6,7 +6,7 @@
*/
import {normalizeUrl, posixPath} from '@docusaurus/utils';
import chalk = require('chalk');
import logger from '@docusaurus/logger';
import chokidar from 'chokidar';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
@ -34,7 +34,7 @@ export default async function start(
): Promise<void> {
process.env.NODE_ENV = 'development';
process.env.BABEL_ENV = 'development';
console.log(chalk.blue('Starting the development server...'));
logger.info('Starting the development server...');
function loadSite() {
return load(siteDir, {
@ -60,9 +60,7 @@ export default async function start(
const urls = prepareUrls(protocol, host, port);
const openUrl = normalizeUrl([urls.localUrlForBrowser, baseUrl]);
console.log(
chalk.cyanBright(`Docusaurus website is running at "${openUrl}".`),
);
logger.success`Docusaurus website is running at path=${openUrl}.`;
// Reload files processing.
const reload = debounce(() => {
@ -70,15 +68,11 @@ export default async function start(
.then(({baseUrl: newBaseUrl}) => {
const newOpenUrl = normalizeUrl([urls.localUrlForBrowser, newBaseUrl]);
if (newOpenUrl !== openUrl) {
console.log(
chalk.cyanBright(
`Docusaurus website is running at "${newOpenUrl}".`,
),
);
logger.success`Docusaurus website is running at path=${newOpenUrl}.`;
}
})
.catch((err) => {
console.error(chalk.red(err.stack));
logger.error(err.stack);
});
}, 500);
const {siteConfig, plugins = []} = props;
@ -170,10 +164,10 @@ export default async function start(
if (process.env.E2E_TEST) {
compiler.hooks.done.tap('done', (stats) => {
if (stats.hasErrors()) {
console.log('E2E_TEST: Project has compiler errors.');
logger.error('E2E_TEST: Project has compiler errors.');
process.exit(1);
}
console.log('E2E_TEST: Project can compile.');
logger.success('E2E_TEST: Project can compile.');
process.exit(0);
});
}

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import fs from 'fs-extra';
import importFresh from 'import-fresh';
import path from 'path';
@ -100,23 +100,18 @@ function themeComponents(
const components = colorCode(themePath, plugin);
if (components.length === 0) {
return `${chalk.red('No component to swizzle.')}`;
return 'No component to swizzle.';
}
return `
${chalk.cyan('Theme components available for swizzle.')}
return `Theme components available for swizzle.
${chalk.green('green =>')} safe: lower breaking change risk
${chalk.red('red =>')} unsafe: higher breaking change risk
${logger.green(logger.bold('green =>'))} safe: lower breaking change risk
${logger.red(logger.bold('red =>'))} unsafe: higher breaking change risk
${components.join('\n')}
`;
}
function formattedThemeNames(themeNames: string[]): string {
return `Themes available for swizzle:\n- ${themeNames.join('\n- ')}`;
}
function colorCode(
themePath: string,
plugin: ImportedPluginModule,
@ -135,8 +130,12 @@ function colorCode(
);
return [
...greenComponents.map((component) => chalk.green(`safe: ${component}`)),
...redComponents.map((component) => chalk.red(`unsafe: ${component}`)),
...greenComponents.map(
(component) => `${logger.green(logger.bold('safe:'))} ${component}`,
),
...redComponents.map(
(component) => `${logger.red(logger.bold('unsafe:'))} ${component}`,
),
];
}
@ -161,27 +160,25 @@ export default async function swizzle(
);
if (!themeName) {
console.log(formattedThemeNames(themeNames));
process.exit(1);
logger.info`Themes available for swizzle: name=${themeNames}`;
return;
}
let pluginModule: ImportedPluginModule;
try {
pluginModule = importFresh(themeName);
} catch {
let suggestion;
let suggestion: string | undefined;
themeNames.forEach((name) => {
if (leven(name, themeName) < 4) {
suggestion = name;
}
});
chalk.red(
`Theme ${themeName} not found. ${
suggestion
? `Did you mean "${suggestion}" ?`
: formattedThemeNames(themeNames)
}`,
);
logger.error`Theme name=${themeName} not found. ${
suggestion
? logger.interpolate`Did you mean name=${suggestion}?`
: logger.interpolate`Themes available for swizzle: ${themeNames}`
}`;
process.exit(1);
}
@ -218,19 +215,17 @@ export default async function swizzle(
: pluginInstance.getThemePath?.();
if (!themePath) {
console.warn(
chalk.yellow(
typescript
? `${themeName} does not provide TypeScript theme code via "getTypeScriptThemePath()".`
: `${themeName} does not provide any theme code.`,
),
logger.warn(
typescript
? logger.interpolate`name=${themeName} does not provide TypeScript theme code via ${'getTypeScriptThemePath()'}.`
: logger.interpolate`name=${themeName} does not provide any theme code.`,
);
process.exit(1);
}
if (!componentName) {
console.warn(themeComponents(themePath, pluginModule));
process.exit(1);
logger.info(themeComponents(themePath, pluginModule));
return;
}
const components = getComponentName(themePath, pluginModule, Boolean(danger));
@ -256,12 +251,8 @@ export default async function swizzle(
if (mostSuitableMatch !== componentName) {
mostSuitableComponent = mostSuitableMatch;
console.log(
chalk.red(`Component "${componentName}" doesn't exist.`),
chalk.yellow(
`"${mostSuitableComponent}" is swizzled instead of "${componentName}".`,
),
);
logger.error`Component name=${componentName} doesn't exist.`;
logger.info`name=${mostSuitableComponent} is swizzled instead of name=${componentName}.`;
}
}
@ -277,40 +268,29 @@ export default async function swizzle(
} else if (fs.existsSync(`${fromPath}.js`)) {
[fromPath, toPath] = [`${fromPath}.js`, `${toPath}.js`];
} else {
let suggestion;
let suggestion: string | undefined;
components.forEach((name) => {
if (leven(name, mostSuitableComponent) < 3) {
suggestion = name;
}
});
console.warn(chalk.red(`Component ${mostSuitableComponent} not found.`));
console.warn(
logger.error`Component name=${mostSuitableComponent} not found. ${
suggestion
? `Did you mean "${suggestion}"?`
: `${themeComponents(themePath, pluginModule)}`,
);
? logger.interpolate`Did you mean name=${suggestion} ?`
: themeComponents(themePath, pluginModule)
}`;
process.exit(1);
}
}
if (!components.includes(mostSuitableComponent) && !danger) {
console.warn(
chalk.red(
`${mostSuitableComponent} is an internal component and has a higher breaking change probability. If you want to swizzle it, use the "--danger" flag.`,
),
);
logger.error`name=${mostSuitableComponent} is an internal component and has a higher breaking change probability. If you want to swizzle it, use the code=${'--danger'} flag.`;
process.exit(1);
}
await fs.copy(fromPath, toPath);
const relativeDir = path.relative(process.cwd(), toPath);
const fromMsg = chalk.blue(
mostSuitableComponent
? `${themeName} ${chalk.yellow(mostSuitableComponent)}`
: themeName,
);
const toMsg = chalk.cyan(relativeDir);
console.log(`\n${chalk.green('Success!')} Copied ${fromMsg} to ${toMsg}.\n`);
logger.success`Copied code=${
mostSuitableComponent ? `${themeName} ${mostSuitableComponent}` : themeName
} to path=${path.relative(process.cwd(), toPath)}.`;
}

View file

@ -6,7 +6,7 @@
*/
import fs from 'fs-extra';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {loadContext, loadPluginConfigs} from '../server';
import initPlugins from '../server/plugins/init';
@ -150,21 +150,10 @@ export default async function writeHeadingIds(
const pathsModified = result.filter(Boolean) as string[];
if (pathsModified.length) {
console.log(
chalk.green(`Heading ids added to Markdown files (${
pathsModified.length
}/${markdownFiles.length} files):
- ${pathsModified.join('\n- ')}`),
);
logger.success`Heading ids added to Markdown files (number=${`${pathsModified.length}/${markdownFiles.length}`} files): ${pathsModified}`;
} else {
console.log(
chalk.yellow(
`${
markdownFiles.length
} Markdown files already have explicit heading IDs. If you intend to overwrite the existing heading IDs, use the ${chalk.cyan(
'--overwrite',
)} option.`,
),
);
logger.warn`number=${
markdownFiles.length
} Markdown files already have explicit heading IDs. If you intend to overwrite the existing heading IDs, use the code=${'--overwrite'} option.`;
}
}

View file

@ -147,7 +147,7 @@ describe('normalizeConfig', () => {
'should accept [function, object] for plugin',
[[function (_context, _options) {}, {it: 'should work'}]],
],
])(`%s for the input of: %p`, (_message, plugins) => {
])(`subdue= for the input of: path=`, (_message, plugins) => {
expect(() => {
normalizeConfig({
plugins,

View file

@ -34,7 +34,6 @@ function loadI18nTest(i18nConfig: I18nConfig, locale?: string) {
}
describe('defaultLocaleConfig', () => {
// @ts-expect-error: wait for TS support of ES2021 feature
const canComputeLabel = typeof Intl.DisplayNames !== 'undefined';
test('returns correct labels', () => {
@ -174,7 +173,7 @@ describe('loadI18n', () => {
'it',
);
expect(consoleSpy.mock.calls[0][0]).toMatch(
/The locale "it" was not found in your site configuration/,
/The locale .*it.* was not found in your site configuration/,
);
});
});

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import logger from '@docusaurus/logger';
import {DocusaurusConfig, I18nConfig} from '@docusaurus/types';
import {DEFAULT_CONFIG_FILE_NAME, STATIC_DIR_NAME} from '@docusaurus/utils';
import {
@ -200,7 +201,7 @@ export function validateConfig(
if (error) {
logValidationBugReportHint();
if (isValidationDisabledEscapeHatch) {
console.error(error);
logger.error(error.message);
return config as DocusaurusConfig;
}

View file

@ -7,9 +7,9 @@
import {I18n, DocusaurusConfig, I18nLocaleConfig} from '@docusaurus/types';
import path from 'path';
import {normalizeUrl, NODE_MAJOR_VERSION} from '@docusaurus/utils';
import {normalizeUrl} from '@docusaurus/utils';
import {getLangDir} from 'rtl-detect';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
function getDefaultLocaleLabel(locale: string) {
// Intl.DisplayNames is ES2021 - Node14+
@ -51,28 +51,14 @@ export async function loadI18n(
const currentLocale = options.locale ?? i18nConfig.defaultLocale;
if (!i18nConfig.locales.includes(currentLocale)) {
console.warn(
chalk.yellow(
`The locale "${currentLocale}" was not found in your site configuration: Available locales are: ${i18nConfig.locales.join(
',',
)}.
Note: Docusaurus only support running one locale at a time.`,
),
);
logger.warn`The locale name=${currentLocale} was not found in your site configuration: Available locales are: ${i18nConfig.locales}
Note: Docusaurus only support running one locale at a time.`;
}
const locales = i18nConfig.locales.includes(currentLocale)
? i18nConfig.locales
: (i18nConfig.locales.concat(currentLocale) as [string, ...string[]]);
if (shouldWarnAboutNodeVersion(NODE_MAJOR_VERSION, locales)) {
console.warn(
chalk.yellow(
`To use Docusaurus i18n, it is strongly advised to use Node.js 14 or later (instead of ${NODE_MAJOR_VERSION}).`,
),
);
}
function getLocaleConfig(locale: string): I18nLocaleConfig {
return {
...getDefaultLocaleConfig(locale),

View file

@ -11,8 +11,8 @@ import {
DEFAULT_CONFIG_FILE_NAME,
GENERATED_FILES_DIR_NAME,
} from '@docusaurus/utils';
import path, {join} from 'path';
import chalk from 'chalk';
import path from 'path';
import logger from '@docusaurus/logger';
import ssrDefaultTemplate from '../client/templates/ssr.html.template';
import loadClientModules from './client-modules';
import loadConfig from './config';
@ -385,9 +385,9 @@ ${Object.keys(registry)
// Version metadata.
const siteMetadata: DocusaurusSiteMetadata = {
docusaurusVersion: getPackageJsonVersion(
join(__dirname, '../../package.json'),
path.join(__dirname, '../../package.json'),
)!,
siteVersion: getPackageJsonVersion(join(siteDir, 'package.json')),
siteVersion: getPackageJsonVersion(path.join(siteDir, 'package.json')),
pluginVersions: {},
};
plugins
@ -446,15 +446,14 @@ function checkDocusaurusPackagesVersion(siteMetadata: DocusaurusSiteMetadata) {
if (
versionInfo.type === 'package' &&
versionInfo.name?.startsWith('@docusaurus/') &&
versionInfo.version &&
versionInfo.version !== docusaurusVersion
) {
// should we throw instead?
// It still could work with different versions
console.warn(
chalk.red(
`Invalid ${plugin} version ${versionInfo.version}.\nAll official @docusaurus/* packages should have the exact same version as @docusaurus/core (${docusaurusVersion}).\nMaybe you want to check, or regenerate your yarn.lock or package-lock.json file?`,
),
);
logger.error`Invalid name=${plugin} version number=${versionInfo.version}.
All official @docusaurus/* packages should have the exact same version as @docusaurus/core (number=${docusaurusVersion}).
Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?`;
}
},
);

View file

@ -20,7 +20,7 @@ import {
InitializedPlugin,
} from '@docusaurus/types';
import initPlugins from './init';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {chain} from 'lodash';
import {localizePluginTranslationFile} from '../translations/translations';
import applyRouteTrailingSlash from './applyRouteTrailingSlash';
@ -211,11 +211,7 @@ export async function loadPlugins({
// TODO remove this deprecated lifecycle soon
// deprecated since alpha-60
// TODO, 1 user reported usage of this lifecycle! https://github.com/facebook/docusaurus/issues/3918
console.error(
chalk.red(
'Plugin routesLoaded lifecycle is deprecated. If you think we should keep this lifecycle, please report here: https://github.com/facebook/docusaurus/issues/3918',
),
);
logger.error`Plugin code=${'routesLoaded'} lifecycle is deprecated. If you think we should keep this lifecycle, please report here: path=${'https://github.com/facebook/docusaurus/issues/3918'}`;
return plugin.routesLoaded(pluginsRouteConfigs);
}),

View file

@ -16,7 +16,7 @@ import {
} from '@docusaurus/types';
import {getPluginI18nPath, toMessageRelativeFilePath} from '@docusaurus/utils';
import {Joi} from '@docusaurus/utils-validation';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
export type WriteTranslationsOptions = {
override?: boolean;
@ -115,11 +115,8 @@ export async function writeTranslationFileContent({
Object.keys(newContent),
);
if (unknownKeys.length > 0) {
console.warn(
chalk.yellow(`Some translation keys looks unknown to us in file ${filePath}
Maybe you should remove them?
- ${unknownKeys.join('\n- ')}`),
);
logger.warn`Some translation keys looks unknown to us in file path=${filePath}.
Maybe you should remove them? ${unknownKeys}`;
}
const mergedContent = mergeTranslationFileContent({
@ -130,16 +127,11 @@ Maybe you should remove them?
// Avoid creating empty translation files
if (Object.keys(mergedContent).length > 0) {
console.log(
`${Object.keys(mergedContent)
.length.toString()
.padStart(
3,
' ',
)} translations will be written at "${toMessageRelativeFilePath(
filePath,
)}".`,
);
logger.info`number=${
Object.keys(mergedContent).length
} translations will be written at path=${toMessageRelativeFilePath(
filePath,
)}.`;
await fs.ensureDir(path.dirname(filePath));
await fs.writeFile(filePath, JSON.stringify(mergedContent, null, 2));
}
@ -290,12 +282,8 @@ export function applyDefaultCodeTranslations({
Object.keys(extractedCodeTranslations),
);
if (unusedDefaultCodeMessages.length > 0) {
console.warn(
chalk.yellow(`Unused default message codes found.
Please report this Docusaurus issue.
- ${unusedDefaultCodeMessages.join('\n- ')}
`),
);
logger.warn`Unused default message codes found.
Please report this Docusaurus issue. name=${unusedDefaultCodeMessages}`;
}
return mapValues(

View file

@ -8,7 +8,7 @@
import fs from 'fs-extra';
import traverse, {Node} from '@babel/traverse';
import generate from '@babel/generator';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {parse, types as t, NodePath, TransformOptions} from '@babel/core';
import {
InitializedPlugin,
@ -115,11 +115,7 @@ function logSourceCodeFileTranslationsWarnings(
) {
sourceCodeFilesTranslations.forEach(({sourceCodeFilePath, warnings}) => {
if (warnings.length > 0) {
console.warn(
`Translation extraction warnings for file path=${sourceCodeFilePath}:\n- ${chalk.yellow(
warnings.join('\n\n- '),
)}`,
);
logger.warn`Translation extraction warnings for file path=${sourceCodeFilePath}: ${warnings}`;
}
});
}
@ -302,7 +298,6 @@ function extractSourceCodeAstTranslations(
return;
}
// console.log('CallExpression', path.node);
const args = path.get('arguments');
if (args.length === 1 || args.length === 2) {
const firstArgPath = args[0];
@ -310,8 +305,6 @@ function extractSourceCodeAstTranslations(
// evaluation allows translate("x" + "y"); to be considered as translate("xy");
const firstArgEvaluated = firstArgPath.evaluate();
// console.log('firstArgEvaluated', firstArgEvaluated);
if (
firstArgEvaluated.confident &&
typeof firstArgEvaluated.value === 'object'

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import path from 'path';
import {Configuration} from 'webpack';
import merge from 'webpack-merge';
@ -45,12 +45,9 @@ export default function createClientConfig(
apply: (compiler) => {
compiler.hooks.done.tap('client:done', (stats) => {
if (stats.hasErrors()) {
console.log(
chalk.red(
'Client bundle compiled with errors therefore further build is impossible.',
),
logger.error(
'Client bundle compiled with errors therefore further build is impossible.',
);
process.exit(1);
}
});

View file

@ -21,7 +21,7 @@ import TerserPlugin from 'terser-webpack-plugin';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import path from 'path';
import crypto from 'crypto';
import chalk from 'chalk';
import logger from '@docusaurus/logger';
import {TransformOptions} from '@babel/core';
import {
ConfigureWebpackFn,
@ -161,11 +161,7 @@ export const getCustomizableJSLoader =
// TODO remove this before end of 2021?
const warnBabelLoaderOnce = memoize(() => {
console.warn(
chalk.yellow(
'Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): "getBabelLoader(isServer)" is now deprecated in favor of "getJSLoader({isServer})".',
),
);
logger.warn`Docusaurus plans to support multiple JS loader strategies (Babel, esbuild...): code=${'getBabelLoader(isServer)'} is now deprecated in favor of code=${'getJSLoader(isServer)'}.`;
});
const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
isServer: boolean,
@ -177,11 +173,7 @@ const getBabelLoaderDeprecated = function getBabelLoaderDeprecated(
// TODO remove this before end of 2021 ?
const warnCacheLoaderOnce = memoize(() => {
console.warn(
chalk.yellow(
'Docusaurus uses Webpack 5 and getCacheLoader() usage is now deprecated.',
),
);
logger.warn`Docusaurus uses Webpack 5 and code=${'getCacheLoader()'} usage is now deprecated.`;
});
function getCacheLoaderDeprecated() {
warnCacheLoaderOnce();
@ -269,11 +261,11 @@ export function compile(config: Configuration[]): Promise<void> {
const compiler = webpack(config);
compiler.run((err, stats) => {
if (err) {
console.error(err.stack || err);
logger.error(err.stack || err);
// @ts-expect-error: see https://webpack.js.org/api/node/#error-handling
if (err.details) {
// @ts-expect-error: see https://webpack.js.org/api/node/#error-handling
console.error(err.details);
logger.error(err.details);
}
reject(err);
}
@ -284,16 +276,14 @@ export function compile(config: Configuration[]): Promise<void> {
}
if (errorsWarnings && stats?.hasWarnings()) {
errorsWarnings.warnings?.forEach((warning) => {
console.warn(warning);
logger.warn(`${warning}`);
});
}
// Webpack 5 requires calling close() so that persistent caching works
// See https://github.com/webpack/webpack.js.org/pull/4775
compiler.close((errClose) => {
if (errClose) {
console.error(
chalk.red('Error while closing Webpack compiler:', errClose),
);
logger.error(`Error while closing Webpack compiler: ${errClose}`);
reject(errClose);
} else {
resolve();
@ -322,9 +312,8 @@ function validateKeyAndCerts({
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
throw new Error(
`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${
(err as Error).message
}`,
`The certificate ${crtFile} is invalid.
${err}`,
);
}
@ -333,9 +322,8 @@ function validateKeyAndCerts({
crypto.privateDecrypt(key, encrypted);
} catch (err) {
throw new Error(
`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
(err as Error).message
}`,
`The certificate key ${keyFile} is invalid.
${err}`,
);
}
}
@ -344,9 +332,7 @@ function validateKeyAndCerts({
function readEnvFile(file: string, type: string) {
if (!fs.existsSync(file)) {
throw new Error(
`You specified ${chalk.cyan(
type,
)} in your env, but the file "${chalk.yellow(file)}" can't be found.`,
`You specified ${type} in your env, but the file "${file}" can't be found.`,
);
}
return fs.readFileSync(file);

View file

@ -2,7 +2,6 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"incremental": true,
"lib": ["DOM", "ES2019"],
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"rootDir": "src",
"outDir": "lib",