From 0685459edbd8fef352810f8ebd75513f5a43373b Mon Sep 17 00:00:00 2001 From: Dragon Fire Date: Tue, 15 Dec 2020 20:45:56 -0500 Subject: [PATCH] Dependency Update Command --- README.md | 4 +- commands/util/dependency-update.js | 68 ++++++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 commands/util/dependency-update.js diff --git a/README.md b/README.md index bf1c6568..b3db54b7 100644 --- a/README.md +++ b/README.md @@ -259,7 +259,7 @@ in the appropriate channel's topic to use it. ## Commands -Total: 570 +Total: 571 ### Utility: @@ -284,6 +284,7 @@ Total: 570 * **eval:** Executes JavaScript code. (Owner-Only) * **command-leaderboard-export:** Exports a command leaderboard JSON file. (Owner-Only) * **command-leaderboard-import:** Imports a command leaderboard JSON file. (Owner-Only) +* **dependency-update:** Checks for dependency updates. (Owner-Only) * **exec:** Executes a command-line application. (Owner-Only) * **generate-commands:** Generates the commands list for Xiao's README. (Owner-Only) * **generate-credit:** Generates the credit list for Xiao's README. (Owner-Only) @@ -1468,6 +1469,7 @@ here. - [NotAWeebDev](https://github.com/NotAWeebDev/) * triggered ([Image](https://github.com/NotAWeebDev/Misaki/blob/2e44f9efb467028dcbae5a2c9f836d2e99860b85/assets/images/plate_triggered.png)) - [npm](https://www.npmjs.com/) + * dependency-update (API) * npm (API) - [Numbers API](http://numbersapi.com/) * number-fact (Trivia API) diff --git a/commands/util/dependency-update.js b/commands/util/dependency-update.js new file mode 100644 index 00000000..907e1c05 --- /dev/null +++ b/commands/util/dependency-update.js @@ -0,0 +1,68 @@ +const Command = require('../../structures/Command'); +const request = require('node-superfetch'); +const semver = require('semver'); +const { stripIndents } = require('common-tags'); +const { dependencies, devDependencies } = require('../../package'); + +module.exports = class DependencyUpdateCommand extends Command { + constructor(client) { + super(client, { + name: 'dependency-update', + aliases: ['dep-update', 'dependencies-update', 'npm-update'], + group: 'util', + memberName: 'dependency-update', + description: 'Checks for dependency updates.', + details: 'Only the bot owner(s) may use this command.', + ownerOnly: true, + guarded: true, + credit: [ + { + name: 'npm', + url: 'https://www.npmjs.com/', + reason: 'API' + } + ] + }); + } + + async run(msg) { + const needUpdate = []; + for (const [dep, ver] of Object.entries(dependencies)) { + const latest = this.fetchVersion(dep); + const clean = semver.clean(ver); + if (latest === clean) continue; + needUpdate.push({ + name: dep, + oldVer: clean, + newVer: latest, + breaking: !semver.satisfies(clean, latest) + }); + } + for (const [dep, ver] of Object.entries(devDependencies)) { + const latest = this.fetchVersion(dep); + const clean = semver.clean(ver); + if (latest === clean) continue; + needUpdate.push({ + name: dep, + oldVer: clean, + newVer: latest, + breaking: !semver.satisfies(clean, latest) + }); + } + if (!needUpdate.length) return msg.say('All packages are up to date.'); + const updatesList = needUpdate.map(pkg => { + const breaking = pkg.breaking ? ' ⚠️' : ''; + return `${pkg.name} (${pkg.oldVer} -> ${pkg.newVer})${breaking}`; + }); + return msg.say(stripIndents` + __**Package Updates Available:**__ + ${updatesList.join('\n')} + `); + } + + async fetchVersion(dependency) { + const { body } = await request.get(`https://registry.npmjs.com/${dependency}`); + if (body.time.unpublished) return null; + return body.versions[body['dist-tags'].latest]; + } +}; diff --git a/package.json b/package.json index bc0e7dce..f7e61958 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "124.0.0", + "version": "124.1.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { @@ -59,6 +59,7 @@ "pokersolver": "^2.1.4", "random-js": "^2.1.0", "rss-parser": "^3.10.0", + "semver": "^7.3.4", "sherlockjs": "^1.4.0", "stackblur-canvas": "^2.4.0", "tesseract.js": "^2.1.4",