-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
/
beforeCli.mjs
140 lines (125 loc) · 4.59 KB
/
beforeCli.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* 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.
*/
// @ts-check
import fs from 'fs-extra';
import path from 'path';
import {createRequire} from 'module';
import logger from '@docusaurus/logger';
import semver from 'semver';
import updateNotifier from 'update-notifier';
import boxen from 'boxen';
import {DOCUSAURUS_VERSION} from '@docusaurus/utils';
const packageJson = /** @type {import("../package.json")} */ (
createRequire(import.meta.url)('../package.json')
);
/** @type {Record<string, any>} */
let sitePkg;
try {
sitePkg = createRequire(path.resolve('package.json'))('./package.json');
} catch {
logger.warn`path=${'package.json'} file not found at CWD: path=${process.cwd()}.`;
logger.info`This is non-critical, but could lead to undesired behavior downstream. Docusaurus assumes that path=${'package.json'} exists at CWD, because it's where the package manager looks up the script at. A common reason is because you have changed directory in the script. Instead of writing code=${'"start": "cd website && docusaurus start"'}, consider using the code=${'[siteDir]'} argument: code=${'"start": "docusaurus start website"'}.`;
sitePkg = {};
}
const {
name,
engines: {node: requiredVersion},
} = packageJson;
/**
* Notify user if `@docusaurus` packages are outdated
*
* Note: this is a 2-step process to avoid delaying cli usage by awaiting a
* response:
* - 1st run: trigger background job to check releases + store result
* - 2nd run: display potential update to users
*
* cache data is stored in `~/.config/configstore/update-notifier-@docusaurus`
*/
export default async function beforeCli() {
const notifier = updateNotifier({
pkg: {
name,
version: DOCUSAURUS_VERSION,
},
// Check is in background so it's fine to use a small value like 1h
// Use 0 for debugging
updateCheckInterval: 1000 * 60 * 60,
});
// Hacky way to ensure we check for updates on first run
// Note: the notification will only happen in the 2nd run
// See https://github.com/yeoman/update-notifier/issues/209
try {
if (
notifier.config &&
// @ts-expect-error: this is an internal API
!notifier.disabled &&
Date.now() - notifier.config.get('lastUpdateCheck') < 50
) {
notifier.config.set('lastUpdateCheck', 0);
notifier.check();
}
} catch (err) {
// Do not stop cli if this fails, see https://github.com/facebook/docusaurus/issues/5400
logger.error(err);
}
/**
* We don't want to display update message for canary releases.
* See https://github.com/facebook/docusaurus/issues/5378
* @param {import('update-notifier').UpdateInfo} update
*/
function ignoreUpdate(update) {
const isCanaryRelease = update?.current?.startsWith('0.0.0');
return isCanaryRelease;
}
if (
notifier.config &&
notifier.update &&
semver.lt(notifier.update.current, notifier.update.latest)
) {
// Because notifier clears cached data after reading it, leading to notifier
// not consistently displaying the update.
// See https://github.com/yeoman/update-notifier/issues/209
notifier.config.set('update', notifier.update);
if (ignoreUpdate(notifier.update)) {
return;
}
const siteDocusaurusPackagesForUpdate = Object.keys({
...sitePkg.dependencies,
...sitePkg.devDependencies,
})
.filter((p) => p.startsWith('@docusaurus'))
.map((p) => p.concat('@latest'))
.join(' ');
const isYarnUsed = await fs.pathExists(path.resolve('yarn.lock'));
const upgradeCommand = isYarnUsed
? `yarn upgrade ${siteDocusaurusPackagesForUpdate}`
: `npm i ${siteDocusaurusPackagesForUpdate}`;
/** @type {import('boxen').Options} */
const boxenOptions = {
padding: 1,
margin: 1,
align: 'center',
borderColor: 'yellow',
borderStyle: 'round',
};
const docusaurusUpdateMessage = boxen(
`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,
);
console.log(docusaurusUpdateMessage);
}
// Notify user if node version needs to be updated
if (!semver.satisfies(process.version, requiredVersion)) {
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);
}
}