diff --git a/src/cli/aliases.js b/src/cli/aliases.js index 64a26a072d..64edab02b6 100644 --- a/src/cli/aliases.js +++ b/src/cli/aliases.js @@ -3,4 +3,5 @@ export default ({ 'upgrade-interactive': 'upgradeInteractive', 'generate-lock-entry': 'generateLockEntry', + 'self-upgrade': 'selfUpgrade', }: {[key: string]: string}); diff --git a/src/cli/commands/index.js b/src/cli/commands/index.js index 2a8f6a852f..1d3b8ee4e7 100644 --- a/src/cli/commands/index.js +++ b/src/cli/commands/index.js @@ -36,6 +36,7 @@ import * as policies from './policies.js'; import * as publish from './publish.js'; import * as remove from './remove.js'; import * as run from './run.js'; +import * as selfUpgrade from './self-upgrade.js'; import * as tag from './tag.js'; import * as team from './team.js'; import * as unplug from './unplug.js'; @@ -84,6 +85,7 @@ const commands = { publish, remove, run, + selfUpgrade, tag, team, unplug, diff --git a/src/cli/commands/install.js b/src/cli/commands/install.js index 85c8648fb7..c6d2dba144 100644 --- a/src/cli/commands/install.js +++ b/src/cli/commands/install.js @@ -87,7 +87,7 @@ type Flags = { * Try and detect the installation method for Yarn and provide a command to update it with. */ -function getUpdateCommand(installationMethod: InstallationMethod): ?string { +export function getUpdateCommand(installationMethod: InstallationMethod): ?string { if (installationMethod === 'tar') { return `curl --compressed -o- -L ${constants.YARN_INSTALLER_SH} | bash`; } diff --git a/src/cli/commands/self-upgrade.js b/src/cli/commands/self-upgrade.js new file mode 100644 index 0000000000..2aac3e3700 --- /dev/null +++ b/src/cli/commands/self-upgrade.js @@ -0,0 +1,62 @@ +/* @flow */ + +import semver from 'semver'; +import type Config from '../../config.js'; +import {SELF_UPDATE_VERSION_URL} from '../../constants.js'; +import type {Reporter} from '../../reporters/index.js'; +import {getInstallationMethod} from '../../util/yarn-version.js'; +import {getUpdateCommand} from './install'; +import {execCommand} from '../../util/execute-lifecycle-script.js'; + +export const noArguments = true; +export const requireLockfile = false; + +export function setFlags(commander: Object) { + commander.description('Upgrades yarn according to the installation method'); +} + +export function hasWrapper(commander: Object, args: Array): boolean { + return true; +} + +export async function run(config: Config, reporter: Reporter, flags: Object, args: Array): Promise { + const currentVersion = flags.version(); + const latestVersion = await config.requestManager.request({ + url: SELF_UPDATE_VERSION_URL, + headers: { + Accept: 'text/plain', + }, + }); + + // Check if we already use the latest or a newer version + if (semver.compare(currentVersion, latestVersion) >= 0) { + reporter.info('already on latest version or higher'); + return; + } + + const installationMethod = await getInstallationMethod(); + + reporter.info(installationMethod); + + if (installationMethod === 'unknown') { + reporter.info('installation method could not be identified'); + return; + } + + const command = getUpdateCommand(installationMethod); + if (command) { + reporter.info(`installation method: , ${installationMethod}`); + + reporter.info('running'); + + await execCommand({ + stage: 'self-upgrade', + config, + cmd: command, + cwd: config.cwd, + isInteractive: true, + }); + } else { + reporter.info('could not find command for instalation method'); + } +} diff --git a/src/lockfile/parse.js b/src/lockfile/parse.js index 2348746063..5712a522bb 100644 --- a/src/lockfile/parse.js +++ b/src/lockfile/parse.js @@ -186,7 +186,7 @@ class Parser { if (version > LOCKFILE_VERSION) { throw new MessageError( `Can't install from a lockfile of version ${version} as you're on an old yarn version that only supports ` + - `versions up to ${LOCKFILE_VERSION}. Run \`$ yarn self-update\` to upgrade to the latest version.`, + `versions up to ${LOCKFILE_VERSION}. Run \`$ yarn self-upgrade\` to upgrade to the latest version.`, ); } }