From c5fcc5d72f19ba0808f5b3a69ca9fc69bb748198 Mon Sep 17 00:00:00 2001 From: Reto Brunner Date: Wed, 2 Jun 2021 00:43:53 +0200 Subject: [PATCH] install: allow installation of local packages It may not be desirable to host all plugins on npm, allow for local packages to be installed given a package name with a `file:` prefix. This is still more restrictive than what yarn would support but allows us to still verify the thelounge compatibility by reading the package.json file. `yarn add` messes up with local filepaths and generates a lockfile that is "outdated" as far as any other yarn commands go, which makes them error out. For some reason `yarn install` fixes that and hence we run that after an install. Here's the diff of yarn.lock between the broken state after `yarn add file:$path` and `yarn install` --- yarn.lock.2.afterAdd 2021-06-02 00:10:52.365134018 +0200 +++ yarn.lock.3.afterinstall 2021-06-02 00:13:27.122760442 +0200 @@ -2194,7 +2194,7 @@ safe-buffer "^5.1.2" yallist "^3.0.3" -thelounge-plugin-shortcuts@/home/reto/sourcecode/thelounge-plugin-shortcuts: +"thelounge-plugin-shortcuts@file:../../sourcecode/thelounge-plugin-shortcuts": version "1.0.12" dependencies: thelounge "4.2.0" The only thing it does is switch an absolute path to a relative one for whatever reason. --- src/command-line/install.js | 62 +++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/src/command-line/install.js b/src/command-line/install.js index 53108f57..bc30a851 100644 --- a/src/command-line/install.js +++ b/src/command-line/install.js @@ -13,6 +13,8 @@ program .on("--help", Utils.extraHelp) .action(function (packageName) { const fs = require("fs"); + const fspromises = fs.promises; + const path = require("path"); const packageJson = require("package-json"); if (!fs.existsSync(Helper.getConfigPath())) { @@ -21,22 +23,31 @@ program } log.info("Retrieving information about the package..."); + let readFile = null; + let isLocalFile = false; - const split = packageName.split("@"); - packageName = split[0]; - const packageVersion = split[1] || "latest"; + if (packageName.startsWith("file:")) { + isLocalFile = true; + readFile = fspromises + .readFile(path.join(packageName.substr("file:".length), "package.json"), "utf-8") + .then((data) => JSON.parse(data)); + } else { + const split = packageName.split("@"); + packageName = split[0]; + const packageVersion = split[1] || "latest"; - packageJson(packageName, { - fullMetadata: true, - version: packageVersion, - }) + readFile = packageJson(packageName, { + fullMetadata: true, + version: packageVersion, + }); + } + + readFile .then((json) => { + const humanVersion = isLocalFile ? packageName : `${json.name} v${json.version}`; + if (!("thelounge" in json)) { - log.error( - `${colors.red( - json.name + " v" + json.version - )} does not have The Lounge metadata.` - ); + log.error(`${colors.red(humanVersion)} does not have The Lounge metadata.`); process.exit(1); } @@ -47,7 +58,7 @@ program ) { log.error( `${colors.red( - json.name + " v" + json.version + humanVersion )} does not support The Lounge v${Helper.getVersionNumber()}. Supported version(s): ${ json.thelounge.supports }` @@ -56,20 +67,23 @@ program process.exit(2); } - log.info(`Installing ${colors.green(json.name + " v" + json.version)}...`); - - return Utils.executeYarnCommand("add", "--exact", `${json.name}@${json.version}`) + log.info(`Installing ${colors.green(humanVersion)}...`); + const yarnVersion = isLocalFile ? packageName : `${json.name}@${json.version}`; + return Utils.executeYarnCommand("add", "--exact", yarnVersion) .then(() => { - log.info( - `${colors.green( - json.name + " v" + json.version - )} has been successfully installed.` - ); + log.info(`${colors.green(humanVersion)} has been successfully installed.`); + + if (isLocalFile) { + // yarn v1 is buggy if a local filepath is used and doesn't update + // the lockfile properly. We need to run an install in that case + // even though that's supposed to be done by the add subcommand + return Utils.executeYarnCommand("install").catch((err) => { + throw `Failed to update lockfile after package install ${err}`; + }); + } }) .catch((code) => { - throw `Failed to install ${colors.green( - json.name + " v" + json.version - )}. Exit code: ${code}`; + throw `Failed to install ${colors.red(humanVersion)}. Exit code: ${code}`; }); }) .catch((e) => {