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

replace update-notifier #61

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
71 changes: 15 additions & 56 deletions bin/npm-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
var npm = require('../lib/npm.js')
var npmconf = require('../lib/config/core.js')
var errorHandler = require('../lib/utils/error-handler.js')

var versionChecker = require('../lib/utils/version-checker.js')
var configDefs = npmconf.defs
var shorthands = configDefs.shorthands
var types = configDefs.types
Expand Down Expand Up @@ -69,67 +69,13 @@
npm.command = 'help'
}

var isGlobalNpmUpdate = conf.global && ['install', 'update'].includes(npm.command) && npm.argv.includes('npm')

// now actually fire up npm and run the command.
// this is how to use npm programmatically:
conf._exit = true
npm.load(conf, function (er) {
if (er) return errorHandler(er)
if (
!isGlobalNpmUpdate &&
npm.config.get('update-notifier') &&
!unsupported.checkVersion(process.version).unsupported
) {
const pkg = require('../package.json')
let notifier = require('update-notifier')({pkg})
const isCI = require('ci-info').isCI
if (
notifier.update &&
notifier.update.latest !== pkg.version &&
!isCI
) {
const color = require('ansicolors')
const useColor = npm.config.get('color')
const useUnicode = npm.config.get('unicode')
const old = notifier.update.current
const latest = notifier.update.latest
let type = notifier.update.type
if (useColor) {
switch (type) {
case 'major':
type = color.red(type)
break
case 'minor':
type = color.yellow(type)
break
case 'patch':
type = color.green(type)
break
}
}
const changelog = `https://github.com/npm/cli/releases/tag/v${latest}`
notifier.notify({
message: `New ${type} version of ${pkg.name} available! ${
useColor ? color.red(old) : old
} ${useUnicode ? '→' : '->'} ${
useColor ? color.green(latest) : latest
}\n` +
`${
useColor ? color.yellow('Changelog:') : 'Changelog:'
} ${
useColor ? color.cyan(changelog) : changelog
}\n` +
`Run ${
useColor
? color.green(`npm install -g ${pkg.name}`)
: `npm i -g ${pkg.name}`
} to update!`
})
}
}
npm.commands[npm.command](npm.argv, function (err) {
// https://genius.com/Lin-manuel-miranda-your-obedient-servant-lyrics
// https://genius.com/Lin-manuel-miranda-your-obedient-servant-lyrics
if (
!err &&
npm.config.get('ham-it-up') &&
Expand All @@ -150,4 +96,17 @@
errorHandler.apply(this, arguments)
})
})

if (process.stdout.isTTY) {
var versionCheckerMessages = []
versionChecker.check()
.stdout.on('data', function (data) {
versionCheckerMessages.push(data.toString())
})
process.on('exit', () => {
if (versionCheckerMessages.length > 0) {
console.error(versionCheckerMessages.join('\n'))
}
})
}
})()
30 changes: 30 additions & 0 deletions lib/utils/version-checker-launch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'
/* eslint-disable camelcase */
const child_process = require('child_process')

module.exports = launchCheck

if (require.main === module) main()

function launchCheck () {
try {
return runInBackground(__filename, [])
} catch (ex) {
// ignore failures
}
}

function runInBackground (js, args, opts) {
if (!args) args = []
args.unshift(js)
if (!opts) opts = {}
opts.detached = true
var child = child_process.spawn(process.execPath, args, opts)
child.unref()
return child
}

function main () {
var check = require('./version-checker').doCheck
check()
}
113 changes: 113 additions & 0 deletions lib/utils/version-checker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const boxen = require('boxen')
const cacache = require('cacache')
const log = require('npmlog')
const nopt = require('nopt')
const path = require('path')
const pacote = require('pacote')
const semver = require('semver')

const npm = require('../npm.js')
const npmconf = require('../config/core.js')
const configDefs = npmconf.defs
const shorthands = configDefs.shorthands
const types = configDefs.types
const pacoteOpts = require('../config/pacote')
const unsupported = require('./unsupported.js')

exports.check = function () {
var checkerLaunch = require('./version-checker-launch')
return checkerLaunch()
}

exports.doCheck = function () {
const conf = nopt(types, shorthands)
npm.argv = conf.argv.remain
const isGlobalNpmUpdate = conf.global && ['install', 'update'].includes(npm.command) && npm.argv.includes('npm')
const isCI = require('ci-info').isCI

npm.load(conf, function (err) {
if (err) return

isBeyondCheckInterval().then((shouldCheck) => {
if (shouldCheck) {
if (
npm.config.get('update-notifier') &&
!isGlobalNpmUpdate &&
!unsupported.checkVersion(process.version).unsupported &&
!isCI
) {
pacote.manifest('npm@latest', pacoteOpts())
.then((latest) => {
const oldVersion = require('../../package.json').version
let diffType = semver.diff(oldVersion, latest.version)
if (diffType) {
console.log(generateMessage(oldVersion, latest.version, diffType, npm))
} else {
log.silly('version-checker', 'we are running the latest version of npm')
}
})
}
}
})
})
}

function isBeyondCheckInterval () {
const cache = path.join(npm.config.get('cache'), '_cacache')
const ONE_DAY = 24 * 60 * 60 * 1000

return cacache.get(cache, 'update-notifier:last-check').then(cacheObj => {
const time = Number(cacheObj.data.toString('utf8'))
return (time + ONE_DAY) < Date.now()
}).catch((notFound) => {
const time = Number(Date.now()).toString()
return cacache.put(cache, 'update-notifier:last-check', time).then(() => {
return true
})
})
}

function generateMessage (oldVersion, latestVersion, diffType, npm) {
const color = require('ansicolors')
const useColor = npm.config.get('color')
const useUnicode = npm.config.get('unicode')
if (useColor) {
switch (diffType) {
case 'major':
diffType = color.red(diffType)
break
case 'minor':
diffType = color.yellow(diffType)
break
case 'patch':
diffType = color.green(diffType)
break
}
}
const changelog = `https://github.com/npm/cli/releases/tag/v${latestVersion}`

let message = `New ${diffType} version of npm available! ${
useColor ? color.red(oldVersion) : oldVersion
} ${useUnicode ? '→' : '->'} ${
useColor ? color.green(latestVersion) : latestVersion
}\n` +
`${
useColor ? color.yellow('Changelog:') : 'Changelog:'
} ${
useColor ? color.cyan(changelog) : changelog
}\n` +
`Run ${
useColor
? color.green(`npm install -g npm`)
: `npm i -g npm`
} to update!`

const boxenOptions = {
padding: 1,
margin: 1,
align: 'center',
borderColor: 'yellow',
borderStyle: 'round'
}
return boxen(message, boxenOptions)
}
16 changes: 9 additions & 7 deletions node_modules/boxen/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"archy": "~1.0.0",
"bin-links": "^1.1.2",
"bluebird": "^3.5.3",
"boxen": "^1.3.0",
"byte-size": "^4.0.3",
"cacache": "^11.2.0",
"call-limit": "~1.1.0",
Expand Down Expand Up @@ -135,7 +136,6 @@
"umask": "~1.1.0",
"unique-filename": "~1.1.0",
"unpipe": "~1.0.0",
"update-notifier": "^2.5.0",
"uuid": "^3.3.2",
"validate-npm-package-license": "^3.0.4",
"validate-npm-package-name": "~3.0.0",
Expand All @@ -153,6 +153,7 @@
"cacache",
"call-limit",
"bluebird",
"boxen",
"bin-links",
"chownr",
"ci-info",
Expand Down Expand Up @@ -248,7 +249,6 @@
"umask",
"unique-filename",
"unpipe",
"update-notifier",
"uuid",
"validate-npm-package-license",
"validate-npm-package-name",
Expand Down