diff --git a/client/gulpfile.js b/client/gulpfile.js
index 873bae0c0bd8..feb386952329 100644
--- a/client/gulpfile.js
+++ b/client/gulpfile.js
@@ -1,10 +1,11 @@
const path = require("path");
-const fs = require("fs");
+const fs = require("fs-extra");
const del = require("del");
const { src, dest, series, parallel, watch } = require("gulp");
const child_process = require("child_process");
const { globSync } = require("glob");
const buildIcons = require("./icons/build_icons");
+const xml2js = require("xml2js");
/*
* We'll want a flexible glob down the road, but for now there are no
@@ -24,7 +25,6 @@ const STATIC_PLUGIN_BUILD_IDS = [
"hyphyvision",
"jqplot/jqplot_bar",
"media_player",
- "msa",
"mvpapp",
"ngl",
"nora",
@@ -39,9 +39,15 @@ const STATIC_PLUGIN_BUILD_IDS = [
"ts_visjs",
"venn",
];
+const INSTALL_PLUGIN_BUILD_IDS = ["msa"]; // todo: derive from XML
const DIST_PLUGIN_BUILD_IDS = ["new_user"];
const PLUGIN_BUILD_IDS = Array.prototype.concat(DIST_PLUGIN_BUILD_IDS, STATIC_PLUGIN_BUILD_IDS);
+const failOnError =
+ process.env.GALAXY_PLUGIN_BUILD_FAIL_ON_ERROR && process.env.GALAXY_PLUGIN_BUILD_FAIL_ON_ERROR !== "0"
+ ? true
+ : false;
+
const PATHS = {
nodeModules: "./node_modules",
stagedLibraries: {
@@ -57,11 +63,6 @@ const PATHS = {
},
};
-const failOnError =
- process.env.GALAXY_PLUGIN_BUILD_FAIL_ON_ERROR && process.env.GALAXY_PLUGIN_BUILD_FAIL_ON_ERROR !== "0"
- ? true
- : false;
-
PATHS.pluginBaseDir =
(process.env.GALAXY_PLUGIN_PATH && process.env.GALAXY_PLUGIN_PATH !== "None"
? process.env.GALAXY_PLUGIN_PATH
@@ -162,6 +163,8 @@ function buildPlugins(callback, forceRebuild) {
console.log(`No changes detected for ${pluginName}`);
} else {
console.log(`Installing Dependencies for ${pluginName}`);
+
+ // Else we call yarn install and yarn build
child_process.spawnSync(
"yarn",
["install", "--production=false", "--network-timeout=300000", "--check-files"],
@@ -205,6 +208,64 @@ function buildPlugins(callback, forceRebuild) {
return callback();
}
+async function installPlugins(callback) {
+ // iterate through install_plugin_build_ids, identify xml files and install dependencies
+ for (const plugin_name of INSTALL_PLUGIN_BUILD_IDS) {
+ const pluginDir = path.join(PATHS.pluginBaseDir, `visualizations/${plugin_name}`);
+ const xmlPath = path.join(pluginDir, `config/${plugin_name}.xml`);
+ // Check if the file exists
+ if (fs.existsSync(xmlPath)) {
+ await installDependenciesFromXML(xmlPath, pluginDir);
+ } else {
+ console.error(`XML file not found: ${xmlPath}`);
+ }
+ }
+ return callback();
+}
+
+// Function to parse the XML and install dependencies
+async function installDependenciesFromXML(xmlPath, pluginDir) {
+ try {
+ const pluginXML = fs.readFileSync(xmlPath);
+ const parsedXML = await xml2js.parseStringPromise(pluginXML);
+ const requirements = parsedXML.visualization.requirements[0].requirement;
+
+ const installPromises = requirements.map(async (dep) => {
+ const { type: reqType, package: pkgName, version } = dep.$;
+
+ if (reqType === "npm" && pkgName && version) {
+ try {
+ const installResult = child_process.spawnSync(
+ "npm",
+ ["install", "--silent", "--no-save", `${pkgName}@${version}`],
+ {
+ cwd: pluginDir,
+ stdio: "inherit",
+ shell: true,
+ }
+ );
+
+ if (installResult.status === 0) {
+ await fs.copy(
+ path.join(pluginDir, "node_modules", pkgName, "static"),
+ path.join(pluginDir, "static")
+ );
+ console.log(`Installed package ${pkgName}@${version} in ${pluginDir}`);
+ } else {
+ console.error(`Error installing package ${pkgName}@${version} in ${pluginDir}`);
+ }
+ } catch (err) {
+ console.error(`Error handling package ${pkgName}@${version} in ${pluginDir}:`, err);
+ }
+ }
+ });
+
+ await Promise.all(installPromises);
+ } catch (err) {
+ console.error(`Error processing XML file ${xmlPath}:`, err);
+ }
+}
+
function forceBuildPlugins(callback) {
return buildPlugins(callback, true);
}
@@ -214,8 +275,8 @@ function cleanPlugins() {
}
const client = parallel(fonts, stageLibs, icons);
-const plugins = series(buildPlugins, cleanPlugins, stagePlugins);
-const pluginsRebuild = series(forceBuildPlugins, cleanPlugins, stagePlugins);
+const plugins = series(buildPlugins, installPlugins, cleanPlugins, stagePlugins);
+const pluginsRebuild = series(forceBuildPlugins, installPlugins, cleanPlugins, stagePlugins);
function watchPlugins() {
const BUILD_PLUGIN_WATCH_GLOB = [
@@ -229,3 +290,4 @@ module.exports.plugins = plugins;
module.exports.pluginsRebuild = pluginsRebuild;
module.exports.watchPlugins = watchPlugins;
module.exports.default = parallel(client, plugins);
+module.exports.installPlugins = installPlugins;
diff --git a/client/package.json b/client/package.json
index 28104a656ff5..a4f2c4b695d2 100644
--- a/client/package.json
+++ b/client/package.json
@@ -172,6 +172,7 @@
"eslint-plugin-vuejs-accessibility": "^2.2.0",
"expose-loader": "^4.1.0",
"fake-indexeddb": "^6.0.0",
+ "fs-extra": "^11.2.0",
"gulp": "^4.0.2",
"ignore-loader": "^0.1.2",
"imports-loader": "^4.0.1",
@@ -204,6 +205,7 @@
"webpack-dev-server": "^4.15.1",
"webpack-merge": "^5.10.0",
"xml-js": "^1.6.11",
+ "xml2js": "^0.6.2",
"yaml-jest": "^1.2.0",
"yaml-loader": "^0.8.0"
},
diff --git a/client/yarn.lock b/client/yarn.lock
index 83b454203c5f..1b464017f3bb 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -6295,6 +6295,15 @@ fresh@0.5.2:
resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+fs-extra@^11.2.0:
+ version "11.2.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
+ integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
+ dependencies:
+ graceful-fs "^4.2.0"
+ jsonfile "^6.0.1"
+ universalify "^2.0.0"
+
fs-mkdirp-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz"
@@ -6561,7 +6570,12 @@ gopd@^1.0.1:
dependencies:
get-intrinsic "^1.1.3"
-graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+ version "4.2.10"
+ resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz"
+ integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
+
+graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.11:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -8077,6 +8091,15 @@ json5@^2.2.2, json5@^2.2.3:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+jsonfile@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
+ integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
+ dependencies:
+ universalify "^2.0.0"
+ optionalDependencies:
+ graceful-fs "^4.1.6"
+
jspdf@^2.5.1:
version "2.5.1"
resolved "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz"
@@ -10364,6 +10387,11 @@ sass@^1.69.4:
immutable "^4.0.0"
source-map-js ">=0.6.2 <2.0.0"
+sax@>=0.6.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f"
+ integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==
+
sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
@@ -11597,6 +11625,11 @@ universalify@^0.2.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
+universalify@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
+ integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
+
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
@@ -12245,6 +12278,19 @@ xml-name-validator@^4.0.0:
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz"
integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
+xml2js@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499"
+ integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz"
diff --git a/config/plugins/visualizations/msa/config/msa.xml b/config/plugins/visualizations/msa/config/msa.xml
index 566a036ebe9b..2fd3761c4847 100644
--- a/config/plugins/visualizations/msa/config/msa.xml
+++ b/config/plugins/visualizations/msa/config/msa.xml
@@ -11,6 +11,9 @@
dataset_id
+
+
+
dataset_id
diff --git a/config/plugins/visualizations/msa/package.json b/config/plugins/visualizations/msa/package.json
index 1a011c6ef6b1..6d96f0a712b1 100644
--- a/config/plugins/visualizations/msa/package.json
+++ b/config/plugins/visualizations/msa/package.json
@@ -1,19 +1,20 @@
{
- "name": "visualization",
- "version": "0.1.0",
+ "name": "@galaxyproject/msa",
+ "version": "0.2.1",
"keywords": [
"galaxy",
"visualization"
],
"license": "AFL-3.0",
- "dependencies": {
- "babel-plugin-transform-export-extensions": "^6.22.0",
- "babel-preset-env": "^1.6.1"
- },
+ "files": [
+ "static"
+ ],
"scripts": {
- "build": "parcel build src/script.js --dist-dir static"
+ "build": "parcel build src/script.js --dist-dir static --no-source-maps"
},
"devDependencies": {
+ "babel-plugin-transform-export-extensions": "^6.22.0",
+ "babel-preset-env": "^1.6.1",
"parcel": "^2.12.0"
}
}