From 42fd55e99cc73b38e4958e62735d63725c2b5a30 Mon Sep 17 00:00:00 2001 From: Thomas Fournier Date: Fri, 29 Jul 2022 12:44:46 -0400 Subject: [PATCH] Improve checking for updates --- core/commands/checkupdates.js | 110 +++++++++++++++++++++++++++++----- core/index.js | 2 + index.js | 29 ++++++++- locales.json | 8 +++ package-lock.json | 4 +- package.json | 4 +- testing.js | 4 +- 7 files changed, 140 insertions(+), 21 deletions(-) diff --git a/core/commands/checkupdates.js b/core/commands/checkupdates.js index 49547df..e2d78bc 100644 --- a/core/commands/checkupdates.js +++ b/core/commands/checkupdates.js @@ -7,14 +7,73 @@ import Artibot from "../../index.js"; * @param {string[]} args * @param {Artibot} artibot */ -export default async function execute(message, args, { config, localizer, version, checkForUpdates, modules }) { +export default async function execute(message, args, { config, localizer, version, checkForUpdates, checkForPackageUpdates, modules }) { // Check if config is valid if (!config.checkForUpdates) { message.reply(localizer._("Checking for updates is disabled in config!")); return; }; - const latest = await checkForUpdates(); + // Check if an argument is passed + if (args.length) { + const moduleId = args[0].toLowerCase(); + + if (moduleId == "artibot") { + const latest = await checkForPackageUpdates(); + + let content; + + if (!latest) { + content = "**Artibot:** " + localizer._("Impossible to get latest version!"); + } else if (version == latest) { + content = "**Artibot:** " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }); + } else { + content = "**Artibot:** " + localizer.__("An update is available: v[[0]] --> v[[1]].", { placeholders: [version, latest] }); + } + + return await message.reply({ content }); + } + + const module = modules.get(moduleId); + + if (!module) return await message.reply(localizer.__("Module with ID `[[0]]` not found.", { placeholders: [moduleId] })); + + const { name, repo, packageName } = module; + version = module.version; + let content = name + ": " + localizer._("Impossible to get latest version!") + "\n"; + + if (packageName) { + const latest = await checkForPackageUpdates(packageName); + + if (latest) { + if (version == latest) { + content = name + ": " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }); + } else { + content = name + ": " + localizer.__("An update is available: v[[0]] --> v[[1]].", { placeholders: [version, latest] }); + } + + return await message.reply({ content }); + } + } + + if (repo) { + const latest = await checkForUpdates(repo); + + if (latest) { + if (version == latest) { + content = name + ": " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }); + } else { + content = name + ": " + localizer.__("An update is available: v[[0]] --> v[[1]].", { placeholders: [version, latest] }); + } + + return await message.reply({ content }); + } + } + + return await message.reply({ content }); + } + + const latest = await checkForPackageUpdates(); let reply; @@ -29,19 +88,42 @@ export default async function execute(message, args, { config, localizer, versio } for (const [, module] of modules) { - if (!module.repo) continue; - const { name, version, repo } = module; - const latest = await checkForUpdates(repo); - - if (!latest) { - reply += name + ": " + localizer._("Impossible to get latest version!") + "\n"; - } else if (version == latest) { - reply += name + ": " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }) + "\n"; - } else { - reply += name + ": " + localizer.__("An update is available: v[[0]] --> v[[1]].", { - placeholders: [version, latest] - }) + "\n"; + const { name, version, repo, packageName } = module; + + if (packageName) { + const latest = await checkForPackageUpdates(packageName); + + if (latest) { + if (version == latest) { + reply += name + ": " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }) + "\n"; + } else { + reply += name + ": " + localizer.__("An update is available: v[[0]] --> v[[1]].", { + placeholders: [version, latest] + }) + "\n"; + } + + continue; + } + } + + if (repo) { + const latest = await checkForUpdates(repo); + + if (latest) { + if (version == latest) { + reply += name + ": " + localizer.__("Already up to date (v[[0]]).", { placeholders: [version] }) + "\n"; + } else { + reply += name + ": " + localizer.__("An update is available: v[[0]] --> v[[1]].", { + placeholders: [version, latest] + }) + "\n"; + } + + continue; + } } + + // If no way to find the latest version + reply += name + ": " + localizer._("Impossible to get latest version!") + "\n"; } message.reply(reply.trim()); diff --git a/core/index.js b/core/index.js index f70ba2b..3ce15e7 100644 --- a/core/index.js +++ b/core/index.js @@ -28,6 +28,7 @@ export default function coreModule(artibot) { name: "Artibot Core", id: "core", repo: "Artivain/artibot", + packageName: "artibot", version, langs: ["en", "fr"], parts: [ @@ -61,6 +62,7 @@ export default function coreModule(artibot) { id: "checkupdates", name: "checkupdates", description: localizer._("Check updates for the bot"), + usage: localizer._("[module id]"), ownerOnly: true, mainFunction: checkupdatesCommand }), diff --git a/index.js b/index.js index 57fdd69..d3e2163 100644 --- a/index.js +++ b/index.js @@ -232,7 +232,7 @@ export class Artibot { headers: { "User-Agent": "Artibot/" + this.version }, - validateStatus: () => { return true } + validateStatus: () => true }); if (request.status != 200) return false; @@ -240,6 +240,29 @@ export class Artibot { const { data } = request; return data.name.replace("v", ""); } + + /** + * Get latest release version of a NPM package + * @param {String} [packageName="artibot"] - Package name on NPM + * @returns {Promise} Version number, or false if package not found or an error happens + * @method + */ + checkForPackageUpdates = async (packageName = "artibot") => { + const request = await axios({ + method: "GET", + url: `https://api.npms.io/v2/package/${packageName}`, + responseType: "json", + headers: { + "User-Agent": "Artibot/" + this.version + }, + validateStatus: () => true + }); + + if (request.status != 200) return false; + + const { data } = request; + return data.collected.metadata.version; + } } /** @ignore */ @@ -263,8 +286,9 @@ export class Module { * @param {ModulePartResolvable[]} config.parts - List of parts of the module * @param {IntentsResolvable[]} [config.intents] - List of required intents * @param {string} [config.repo] - GitHub repository of the module (ex.: "Artivain/artibot") + * @param {String} [config.packageName] - Package name of the module on NPM (ex.: "artibot") */ - constructor({ name, id, version, langs = "any", parts, intents = [], repo }) { + constructor({ name, id, version, langs = "any", parts, intents = [], repo, packageName }) { if (!name || !id || !version || !langs || !parts) throw new Error("Missing module informations!"); this.name = name; this.id = id; @@ -273,6 +297,7 @@ export class Module { this.parts = parts; this.additionalIntents = intents; this.repo = repo; + this.packageName = packageName; } } diff --git a/locales.json b/locales.json index c9d112f..7368e24 100644 --- a/locales.json +++ b/locales.json @@ -629,6 +629,14 @@ "Error when registering module: ": { "fr": "Une erreur est survenue en chargeant un module: " + }, + + "[module id]": { + "fr": "[id du module]" + }, + + "Module with ID `[[0]]` not found.": { + "fr": "Il n'y a pas de module avec le ID `[[0]]` installé." } } diff --git a/package-lock.json b/package-lock.json index e1c56e7..6a0a203 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "artibot", - "version": "4.0.0", + "version": "4.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "artibot", - "version": "4.0.0", + "version": "4.1.0", "license": "GPL-3.0-or-later", "dependencies": { "@discordjs/rest": "^1.0.1", diff --git a/package.json b/package.json index 469028c..aefb537 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "artibot", - "version": "4.0.0", + "version": "4.1.0", "description": "Modern, fast and modular open-source Discord bot", "main": "index.js", "scripts": { "start": "node index.js", - "test": "nodemon testing.js", + "test": "nodemon testing.js --ignore data/", "upgrade": "ncu -u && npm install && npm update", "build-docs": "jsdoc -c ./jsdoc.json" }, diff --git a/testing.js b/testing.js index ab3a512..4261ca6 100644 --- a/testing.js +++ b/testing.js @@ -74,4 +74,6 @@ artibot.registerModule( }) ); -artibot.login({ token }); \ No newline at end of file +artibot.login({ token }); + +console.log(await artibot.checkForPackageUpdates()); \ No newline at end of file