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" } }