|
2 | 2 |
|
3 | 3 | import type {Reporter} from '../../reporters/index.js';
|
4 | 4 | import type Config from '../../config.js';
|
| 5 | +import {version} from '../../util/yarn-version.js'; |
| 6 | +import * as child from '../../util/child.js'; |
5 | 7 | import buildSubCommands from './_build-sub-commands.js';
|
6 | 8 | import {getRcConfigForFolder} from '../../rc.js';
|
7 | 9 | import * as fs from '../../util/fs.js';
|
8 | 10 | import {stringify} from '../../lockfile';
|
| 11 | +import {satisfiesWithPrereleases} from '../../util/semver.js'; |
| 12 | +import {NODE_BIN_PATH} from '../../constants'; |
| 13 | + |
| 14 | +const V2_NAMES = ['stable', 'berry', 'stable', 'canary', 'v2', '2']; |
| 15 | + |
| 16 | +const isLocalFile = (version: string) => version.match(/^\.{0,2}[\\/]/) || path.isAbsolute(version); |
| 17 | +const isV2Version = (version: string) => satisfiesWithPrereleases(version, '>=2.0.0'); |
9 | 18 |
|
10 | 19 | const chalk = require('chalk');
|
11 | 20 | const invariant = require('invariant');
|
@@ -49,6 +58,7 @@ async function fetchReleases(
|
49 | 58 | ): Promise<Array<Release>> {
|
50 | 59 | const token = process.env.GITHUB_TOKEN;
|
51 | 60 | const tokenUrlParameter = token ? `?access_token=${token}` : '';
|
| 61 | + |
52 | 62 | const request: Array<Release> = await config.requestManager.request({
|
53 | 63 | url: `https://api.github.com/repos/yarnpkg/yarn/releases${tokenUrlParameter}`,
|
54 | 64 | json: true,
|
@@ -98,32 +108,103 @@ export function hasWrapper(flags: Object, args: Array<string>): boolean {
|
98 | 108 |
|
99 | 109 | const {run, setFlags, examples} = buildSubCommands('policies', {
|
100 | 110 | async setVersion(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
|
101 |
| - let range = args[0] || 'latest'; |
102 |
| - let allowRc = flags.rc; |
| 111 | + const initialRange = args[0] || 'latest'; |
| 112 | + let range = initialRange; |
103 | 113 |
|
104 |
| - reporter.log(`Resolving ${chalk.yellow(range)} to a url...`); |
| 114 | + let allowRc = flags.rc; |
105 | 115 |
|
106 | 116 | if (range === 'rc') {
|
107 |
| - range = 'latest'; |
| 117 | + reporter.log( |
| 118 | + `${chalk.yellow( |
| 119 | + `Warning:`, |
| 120 | + )} Your current Yarn binary is currently Yarn ${version}; to avoid potential breaking changes, 'set version rc' won't receive upgrades past the 1.22.x branch.\n To upgrade to the latest versions, run ${chalk.cyan( |
| 121 | + `yarn set version`, |
| 122 | + )} ${chalk.yellow.underline(`canary`)} instead. Sorry for the inconvenience.\n`, |
| 123 | + ); |
| 124 | + |
| 125 | + range = '*'; |
108 | 126 | allowRc = true;
|
109 | 127 | }
|
110 | 128 |
|
111 | 129 | if (range === 'latest') {
|
| 130 | + reporter.log( |
| 131 | + `${chalk.yellow( |
| 132 | + `Warning:`, |
| 133 | + )} Your current Yarn binary is currently Yarn ${version}; to avoid potential breaking changes, 'set version latest' won't receive upgrades past the 1.22.x branch.\n To upgrade to the latest versions, run ${chalk.cyan( |
| 134 | + `yarn set version`, |
| 135 | + )} ${chalk.yellow.underline(`stable`)} instead. Sorry for the inconvenience.\n`, |
| 136 | + ); |
| 137 | + |
| 138 | + range = '*'; |
| 139 | + } |
| 140 | + |
| 141 | + if (range === 'classic') { |
112 | 142 | range = '*';
|
113 | 143 | }
|
114 | 144 |
|
115 | 145 | let bundleUrl;
|
116 | 146 | let bundleVersion;
|
117 |
| - let isV2 = false; |
| 147 | + const isV2 = false; |
118 | 148 |
|
119 | 149 | if (range === 'nightly' || range === 'nightlies') {
|
| 150 | + reporter.log( |
| 151 | + `${chalk.yellow( |
| 152 | + `Warning:`, |
| 153 | + )} Nightlies only exist for Yarn 1.x; starting from 2.x onwards, you should use 'canary' instead`, |
| 154 | + ); |
| 155 | + |
120 | 156 | bundleUrl = 'https://nightly.yarnpkg.com/latest.js';
|
121 | 157 | bundleVersion = 'nightly';
|
122 |
| - } else if (range === 'berry' || range === 'v2' || range === '2') { |
123 |
| - bundleUrl = 'https://github.com/yarnpkg/berry/raw/master/packages/berry-cli/bin/berry.js'; |
124 |
| - bundleVersion = 'berry'; |
125 |
| - isV2 = true; |
| 158 | + } else if (V2_NAMES.includes(range) || isLocalFile(range) || isV2Version(range)) { |
| 159 | + const normalizedRange = range === `canary` ? `canary` : `stable`; |
| 160 | + |
| 161 | + if (process.env.COREPACK_ROOT) { |
| 162 | + await child.spawn( |
| 163 | + NODE_BIN_PATH, |
| 164 | + [ |
| 165 | + path.join(process.env.COREPACK_ROOT, 'dist/corepack.js'), |
| 166 | + `yarn@${normalizedRange}`, |
| 167 | + `set`, |
| 168 | + `version`, |
| 169 | + normalizedRange, |
| 170 | + ], |
| 171 | + { |
| 172 | + stdio: 'inherit', |
| 173 | + cwd: config.cwd, |
| 174 | + }, |
| 175 | + ); |
| 176 | + |
| 177 | + return; |
| 178 | + } else { |
| 179 | + const bundle = await fetchBundle( |
| 180 | + config, |
| 181 | + 'https://github.com/yarnpkg/berry/raw/master/packages/yarnpkg-cli/bin/yarn.js', |
| 182 | + ); |
| 183 | + |
| 184 | + const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-stable-temp.cjs`); |
| 185 | + await fs.mkdirp(path.dirname(yarnPath)); |
| 186 | + await fs.writeFile(yarnPath, bundle); |
| 187 | + await fs.chmod(yarnPath, 0o755); |
| 188 | + |
| 189 | + try { |
| 190 | + await child.spawn(NODE_BIN_PATH, [yarnPath, 'set', 'version', range], { |
| 191 | + stdio: 'inherit', |
| 192 | + cwd: config.lockfileFolder, |
| 193 | + env: { |
| 194 | + ...process.env, |
| 195 | + YARN_IGNORE_PATH: `1`, |
| 196 | + }, |
| 197 | + }); |
| 198 | + } catch (err) { |
| 199 | + // eslint-disable-next-line no-process-exit |
| 200 | + process.exit(1); |
| 201 | + } |
| 202 | + |
| 203 | + return; |
| 204 | + } |
126 | 205 | } else {
|
| 206 | + reporter.log(`Resolving ${chalk.yellow(initialRange)} to a url...`); |
| 207 | + |
127 | 208 | let releases = [];
|
128 | 209 |
|
129 | 210 | try {
|
|
0 commit comments