Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add automatic check for updates that nags the user when there's a new version available #1429

Merged
merged 8 commits into from
Nov 14, 2016
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ deployment:
commands:
- ./ghr --username yarnpkg --repository yarn --token $KPM_CIRCLE_RELEASE_TOKEN v$(dist/bin/yarn --version) artifacts/
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
- ./scripts/set-installation-method.js "`pwd`/package.json" npm
- npm publish

notify:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"ini": "^1.3.4",
"invariant": "^2.2.0",
"is-builtin-module": "^1.0.0",
"is-ci": "^1.0.9",
"is-ci": "^1.0.10",
"leven": "^2.0.0",
"loud-rejection": "^1.2.0",
"minimatch": "^3.0.3",
Expand Down
17 changes: 14 additions & 3 deletions scripts/install-latest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,20 @@ yarn_install() {
printf "${white}Installing Yarn!$reset\n"

if [ -d "$HOME/.yarn" ]; then
printf "$red> ~/.yarn already exists, possibly from a past Yarn install.$reset\n"
printf "$red> Remove it (rm -rf ~/.yarn) and run this script again.$reset\n"
exit 0
if [ -n `which yarn` ]; then
LATEST_VERSION=`curl https://yarnpkg.com/latest-version`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may need to handle the --nightly flag. We have this in yarn_get_tarball:

  if [ "$1" = '--nightly' ]; then
    url=https://nightly.yarnpkg.com/latest.tar.gz
  else
    url=https://yarnpkg.com/latest.tar.gz
  fi

You can use https://nightly.yarnpkg.com/latest-tar-version to get the latest nightly version.

YARN_VERSION=`yarn -V`

if [ "$LATEST_VERSION" -eq "$YARN_VERSION" ]; then
printf "$green> Yarn is already at the latest version.$reset\n"
else
rm -rf "$HOME/.yarn"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2scary4me, maybe warn the user before doing this.

"A newer version of Yarn is available, do you want to delete the existing version and upgrade? (Y/N)"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also won't this blow away their config? Or is that stored elsewhere?

fi
else
printf "$red> ~/.yarn already exists, possibly from a past Yarn install.$reset\n"
printf "$red> Remove it (rm -rf ~/.yarn) and run this script again.$reset\n"
exit 0
fi
fi

yarn_get_tarball $1
Expand Down
1 change: 0 additions & 1 deletion src/cli/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import * as pack from './pack.js'; export {pack};
import * as publish from './publish.js'; export {publish};
import * as remove from './remove.js'; export {remove};
import * as run from './run.js'; export {run};
import * as selfUpdate from './self-update.js'; export {selfUpdate};
import * as tag from './tag.js'; export {tag};
import * as team from './team.js'; export {team};
import * as unlink from './unlink.js'; export {unlink};
Expand Down
113 changes: 113 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 {verison: YARN_VERSION, installationMethod: YARN_INSTALL_METHOD} = require('../../../package.json');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possibly typo verison

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 {
if (YARN_INSTALL_METHOD === 'tar') {
return 'curl -o- -L https://yarnpkg.com/install.sh | bash';
}

if (YARN_INSTALL_METHOD === 'homebrwe') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "homebrwe" -> "homebrew"

return 'brew upgrade yarn';
}

if (YARN_INSTALL_METHOD === 'deb') {
return 'sudo apt-get updat e&& sudo apt-get install yarn';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "updat e" -> "update"

}

if (YARN_INSTALL_METHOD === 'rpm') {
return 'sudo yum install yarn';
}

if (YARN_INSTALL_METHOD === 'npm') {
return 'npm upgrade --global yarn';
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add Chocolatey: choco upgrade yarn

return null;
}

function getUpdateInstaller(): ?string {
// Windows
if (YARN_INSTALL_METHOD === 'msi') {
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,72 @@ 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still valuable for non-TTY environments. Why should we avoid showing a notice about Yarn being outdated just because the user is piping the output to a file, for example?

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I wonder if we should bug on nightly builds?

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',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to better automate this getting updated

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm going to have a webhook that runs when releases are updated, or just a cronjob. The tricky thing is that we can't bump the version number until we verify that all files are attached to the release, and the Windows installer is attached separately from everything else (as it's built on AppVeyor).

});
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'));
this.reporter.command(command);
} else {
const installer = getUpdateInstaller();
if (installer) {
this.reporter.info(this.reporter.lang('yarnOutdatedInstaller', installer));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional, but can we use something like boxen (or just render the ANSI codes ourself) to render a fancy box around it, like update-notifier does?

}
}
};
}
}

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

maybeOutputUpdate() {}
maybeOutputUpdate: any;
}

export function setFlags(commander: Object) {
Expand Down
83 changes: 0 additions & 83 deletions src/cli/commands/self-update.js

This file was deleted.

1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ 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 @@ -77,6 +77,10 @@ const messages = {
jsonError: 'Error parsing JSON at $0, $1.',
noFilePermission: "We don't have permissions to touch the file $0.",

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.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is totally optional, but we could download the installer and run it for the user. Maybe we'll hold off on that for now and do it as an enhancement!

yarnOutdatedCommand: 'To upgrade, run the following command:',

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
15 changes: 13 additions & 2 deletions 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,7 +2677,13 @@ is-builtin-module@^1.0.0:
dependencies:
builtin-modules "^1.0.0"

is-ci, is-ci@^1.0.9:
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"