Skip to content

Commit

Permalink
Add automatic check for updates that nags the user when there's a new…
Browse files Browse the repository at this point in the history
… version available - fixes #1138
  • Loading branch information
Sebastian McKenzie committed Oct 25, 2016
1 parent 798d190 commit e864da9
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"ini": "^1.3.4",
"invariant": "^2.2.0",
"is-builtin-module": "^1.0.0",
"is-ci": "^1.0.10",
"leven": "^2.0.0",
"loud-rejection": "^1.2.0",
"minimatch": "^3.0.3",
Expand Down
112 changes: 112 additions & 0 deletions src/cli/commands/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ import * as crypto from '../../util/crypto.js';
import map from '../../util/map.js';

const invariant = require('invariant');
const userHome = require('user-home');
const semver = require('semver');
const emoji = require('node-emoji');
const isCI = require('is-ci');
const path = require('path');
const fs2 = require('fs');

const YARN_VERSION = require('../../../package.json').version;
const ONE_DAY = 1000 * 60 * 60 * 24;

export type InstallPrepared = {
skip: boolean,
Expand Down Expand Up @@ -69,6 +76,43 @@ type Flags = {
tilde: boolean,
};

/**
* Try and detect the installation method for Yarn and provide a command to update it with.
*/

function getUpdateCommand(): ?string {
// Tarball install
if (fs2.existsSync(path.join(userHome, '.yarn'))) {
return 'yarn self-update';
}

// OSX
if (fs2.existsSync('/usr/local/Cellar')) {
return 'brew upgrade yarn';
}

// Debian
if (fs2.existsSync('/usr/share/lintian/overrides/yarn')) {
return 'sudo apt-get install yarn';
}

// npm
if (__dirname.indexOf('node_modules') >= 0) {
return 'npm upgrade --global yarn';
}

return null;
}

function getUpdateInstaller(): ?string {
// Windows
if (fs2.existsSync('C:/Program Files/Yarn') || fs2.existsSync('C:/Program Files (x86)/Yarn')) {
return 'https://yarnpkg.com/latest.msi';
}

return null;
}

function normalizeFlags(config: Config, rawFlags: Object): Flags {
const flags = {
// install
Expand Down Expand Up @@ -273,6 +317,8 @@ export class Install {
*/

async init(): Promise<Array<string>> {
this.checkUpdate();

let [depRequests, rawPatterns] = await this.fetchRequestFromCwd();
const match = await this.matchesIntegrityHash(rawPatterns);

Expand Down Expand Up @@ -355,6 +401,7 @@ export class Install {

// fin!
await this.saveLockfileAndIntegrity(rawPatterns);
this.maybeOutputUpdate();
this.config.requestManager.clearCache();
return patterns;
}
Expand Down Expand Up @@ -640,6 +687,71 @@ export class Install {

return request;
}

/**
* Check for updates every day and output a nag message if there's a newer version.
*/

checkUpdate() {
if (!process.stdout.isTTY || isCI) {
// don't show upgrade dialog on CI or non-TTY terminals
return;
}

// only check for updates once a day
const lastUpdateCheck = Number(this.config.getOption('lastUpdateCheck')) || 0;
if (lastUpdateCheck && Date.now() - lastUpdateCheck < ONE_DAY) {
return;
}

// don't bug for updates on tagged releases
if (YARN_VERSION.indexOf('-') >= 0) {
return;
}

this._checkUpdate().catch(() => {
// swallow errors
});
}

async _checkUpdate(): Promise<void> {
let latestVersion = await this.config.requestManager.request({
url: 'https://yarnpkg.com/latest-version',
});
invariant(typeof latestVersion === 'string', 'expected string');
latestVersion = latestVersion.trim();
if (!semver.valid(latestVersion)) {
return;
}

// ensure we only check for updates periodically
this.config.registries.yarn.saveHomeConfig({
lastUpdateCheck: Date.now(),
});

if (semver.gt(latestVersion, YARN_VERSION)) {
this.maybeOutputUpdate = () => {
this.reporter.warn(this.reporter.lang('yarnOutdated', latestVersion, YARN_VERSION));

const command = getUpdateCommand();
if (command) {
this.reporter.info(this.reporter.lang('yarnOutdatedCommand', command));
} else {
const installer = getUpdateInstaller();
if (installer) {
this.reporter.info(this.reporter.lang('yarnOutdatedInstaller', installer));
}
}
};
}
}

/**
* Method to override with a possible upgrade message.
*/

maybeOutputUpdate() {}
maybeOutputUpdate: any;
}

export function _setFlags(commander: Object) {
Expand Down
2 changes: 2 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ export default class Config {
return file;
}
}

return null;
});
}

Expand Down
4 changes: 4 additions & 0 deletions src/reporters/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ const messages = {
unexpectedError: 'An unexpected error occurred, please open a bug report with the information provided in $0.',
jsonError: 'Error parsing JSON at $0, $1.',

yarnOutdated: "Your current version of Yarn is out of date. The latest version is $0 while you're on $1.",
yarnOutdatedInstaller: 'To upgrade, download the latest installer at $0.',
yarnOutdatedCommand: 'To upgrade, run $0.',

tooManyArguments: 'Too many arguments, maximum of $0.',
tooFewArguments: 'Not enough arguments, expected at least $0.',
noArguments: "This command doesn't require any arguments.",
Expand Down
13 changes: 12 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


abab@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
Expand Down Expand Up @@ -1329,6 +1331,10 @@ chokidar@^1.4.3, chokidar@^1.5.2:
optionalDependencies:
fsevents "^1.0.0"

ci-info@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534"

cipher-base@^1.0.0, cipher-base@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07"
Expand Down Expand Up @@ -2671,6 +2677,12 @@ is-builtin-module@^1.0.0:
dependencies:
builtin-modules "^1.0.0"

is-ci:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
dependencies:
ci-info "^1.0.0"

is-ci@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.9.tgz#de2c5ffe49ab3237fda38c47c8a3bbfd55bbcca7"
Expand Down Expand Up @@ -5192,4 +5204,3 @@ yargs@~3.27.0:
os-locale "^1.4.0"
window-size "^0.1.2"
y18n "^3.2.0"

0 comments on commit e864da9

Please sign in to comment.