diff --git a/bin/index.js b/bin/index.js index 5aab888a..79933f7e 100755 --- a/bin/index.js +++ b/bin/index.js @@ -133,6 +133,13 @@ program updateCheck(true).then(() => uploadAction()) }) +program + .command('update') + .description(['🔄', ' '.repeat(3), 'Update the Lightning-CLI to the latest version'].join('')) + .action(() => { + updateCheck(true).then(() => process.exit(1)) + }) + program.on('command:*', () => { const suggestion = didYouMean( program.args[0] || '', diff --git a/docs/_sidebar.md b/docs/_sidebar.md index e04d9388..93a84e3a 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -8,4 +8,5 @@ - [Docs](commands/docs.md) - [Dist](commands/dist.md) - [Upload](commands/upload.md) + - [Update](commands/update.md) - [Environment variables](environmentvariables.md) diff --git a/docs/commands/update.md b/docs/commands/update.md new file mode 100644 index 00000000..05236de5 --- /dev/null +++ b/docs/commands/update.md @@ -0,0 +1,13 @@ +# Update command + +_Update the Lightning-CLI to the latest version_ + +```bash +lng update +``` + +The Lightning-CLI has an auto-update mechanism. It check periodically if you are still on the latest version, +and updates automatically if you are not. This way you can be sure that you are always compatible with the latest +changes (either on the Lightning-SDK side, or the Metro App store side). + +When you don't want to wait, but force an update to the latest version manually you can use the `lng update` command. diff --git a/package-lock.json b/package-lock.json index 1d45cb6a..04f6dc5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1939,6 +1939,11 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2759,6 +2764,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, "inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", @@ -3042,6 +3052,14 @@ "json-buffer": "3.0.0" } }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "requires": { + "package-json": "^6.3.0" + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -3538,6 +3556,24 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "package-name-regex": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/package-name-regex/-/package-name-regex-1.0.8.tgz", @@ -3717,6 +3753,24 @@ "safe-buffer": "^5.1.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + } + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -3784,6 +3838,22 @@ "unicode-match-property-value-ecmascript": "^1.2.0" } }, + "registry-auth-token": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "requires": { + "rc": "^1.2.8" + } + }, "regjsgen": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", diff --git a/package.json b/package.json index 97f0d62b..de161d97 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "http-server": "^0.12.3", "inquirer": "^7.3.3", "is-online": "^8.4.0", + "latest-version": "^5.1.0", "ora": "^5.1.0", "replace-in-file": "^6.1.0", "rollup": "^2.28.2", diff --git a/src/helpers/uptodate.js b/src/helpers/uptodate.js index 9257b9b6..a8031ad8 100644 --- a/src/helpers/uptodate.js +++ b/src/helpers/uptodate.js @@ -19,10 +19,10 @@ const fs = require('fs') const path = require('path') -const https = require('https') const semver = require('semver') const execa = require('execa') const isOnline = require('is-online') +const latestVersion = require('latest-version') const spinner = require('./spinner.js') const exit = require('./exit.js') @@ -30,33 +30,17 @@ const packageJson = require('../../package.json') const ask = require('../helpers/ask') const fetchLatestVersion = () => { - const gitBranch = getGitBranch() - const url = gitBranch - ? 'https://raw.githubusercontent.com/rdkcentral/Lightning-CLI/' + gitBranch + '/package.json' - : false - return new Promise((resolve, reject) => { - if (!url) reject('Skipping auto update.') - https - .get(url, res => { - let body = '' - - res.on('data', chunk => { - body += chunk - }) - - res.on('end', () => { - try { - let json = JSON.parse(body) - resolve(json.version) - } catch (error) { - reject('Unable to get CLI version from ' + url) - } - }) - }) - .on('error', error => { - reject(error) - }) + // if a git folder exists, we are probably working of a clone, + // so likely we don't want to do any auto updates + const gitFolder = path.join(__dirname, '../../.git') + if (fs.existsSync(gitFolder)) { + resolve(false) + } else { + return latestVersion(packageJson.name) + .then(resolve) + .catch(reject) + } }) } @@ -93,15 +77,17 @@ const testConnection = async () => { const checkForUpdate = () => { spinner.start('Verifying if your installation of Lightning-CLI is up to date.') return fetchLatestVersion() - .then(latestVersion => { + .then(version => { + if (version === false) { + spinner.succeed() + return Promise.resolve() + } if ( - semver.lt(packageJson.version, latestVersion) || + semver.lt(packageJson.version, version) || packageJson.name === 'wpe-lightning-cli' // always update when old package name ) { spinner.fail() - spinner.start( - 'Attempting to update Lightning-CLI to the latest version (' + latestVersion + ')' - ) + spinner.start('Attempting to update Lightning-CLI to the latest version (' + version + ')') const options = ['install', '-g', '@lightningjs/cli'] @@ -138,22 +124,4 @@ const checkForUpdate = () => { }) } -const getGitBranch = () => { - // if a git folder exists, we are probably working of a clone, - // so likely we don't want to do any auto updates - const gitFolder = path.join(__dirname, '../../.git') - if (fs.existsSync(gitFolder)) { - return false - } - // otherwise base on the package.json - else { - const packageJson = require(path.join(__dirname, '../../package.json')) - if (packageJson._requested && 'gitCommittish' in packageJson._requested) { - return packageJson._requested.gitCommittish || 'master' // gitCommittish is null for master - } else { - return false - } - } -} - module.exports = upToDate