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

Suggest yarn when installed with yarn #132

Merged
merged 12 commits into from
May 10, 2019
35 changes: 33 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const spawn = require('child_process').spawn;
const fs = require('fs');
const path = require('path');
const format = require('util').format;
const importLazy = require('import-lazy')(require);
Expand All @@ -13,6 +14,7 @@ const isInstalledGlobally = importLazy('is-installed-globally');
const boxen = importLazy('boxen');
const xdgBasedir = importLazy('xdg-basedir');
const isCi = importLazy('is-ci');
const which = importLazy('which');
const ONE_DAY = 1000 * 60 * 60 * 24;

class UpdateNotifier {
Expand All @@ -25,7 +27,8 @@ class UpdateNotifier {
// TODO: Remove deprecated options at some point far into the future
options.pkg = {
name: options.pkg.name || options.packageName,
version: options.pkg.version || options.packageVersion
version: options.pkg.version || options.packageVersion,
bin: options.pkg.bin
};

if (!options.pkg.name || !options.pkg.version) {
Expand All @@ -34,6 +37,7 @@ class UpdateNotifier {

this.packageName = options.pkg.name;
this.packageVersion = options.pkg.version;
this.packageBin = options.pkg.bin;
this.updateCheckInterval = typeof options.updateCheckInterval === 'number' ? options.updateCheckInterval : ONE_DAY;
this.hasCallback = typeof options.callback === 'function';
this.callback = options.callback || (() => {});
Expand Down Expand Up @@ -107,15 +111,42 @@ class UpdateNotifier {
};
});
}
isYarn() {
const bin = this.packageBin;
let cliName = null;

switch (typeof bin) {
case 'string':
cliName = this.packageName;
break;
case 'object':
cliName = Object.keys(bin)[0];
break;
case 'undefined':
default:
return false;
}

try {
const realpath = fs.realpathSync(which().sync(cliName, {nothrow: true}));
if (realpath.match(/yarn\/global/)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I could be wrong, but this literal RegExp doesn't look to be Windows-friendly (hardcoded forward slash).

Perhaps we could simplify this to:

return realpath.includes(path.join('yarn', 'global'));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I will try it in Windows.

return true;
}
return false;
} catch (err) {
return false;
}
}
notify(opts) {
if (!process.stdout.isTTY || isNpm() || !this.update) {
return this;
}

opts = Object.assign({isGlobal: isInstalledGlobally()}, opts);
Copy link
Member

Choose a reason for hiding this comment

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

isInstalledGlobally already supports Yarn, but it doesn't return which one it is. For that, you could use https://github.com/sindresorhus/global-dirs#packages

Copy link
Contributor Author

@LitoMore LitoMore Jan 23, 2018

Choose a reason for hiding this comment

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

@sindresorhus I created a package is-yarn-global, it without any fs calls and dependencies. What about this?

const installCommand = this.isYarn() ? 'yarn global upgrade ' + this.packageName : 'npm i ' + (opts.isGlobal ? '-g ' : '') + this.packageName;
Copy link
Member

Choose a reason for hiding this comment

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

We should probably do the global check on yarn too no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have to.


opts.message = opts.message || 'Update available ' + chalk().dim(this.update.current) + chalk().reset(' → ') +
chalk().green(this.update.latest) + ' \nRun ' + chalk().cyan('npm i ' + (opts.isGlobal ? '-g ' : '') + this.packageName) + ' to update';
chalk().green(this.update.latest) + ' \nRun ' + chalk().cyan(installCommand) + ' to update';

opts.boxenOpts = opts.boxenOpts || {
padding: 1,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"is-npm": "^1.0.0",
"latest-version": "^3.0.0",
"semver-diff": "^2.0.0",
"which": "^1.3.0",
"xdg-basedir": "^3.0.0"
},
"devDependencies": {
Expand Down