UNPKG

@zowe/imperative

Version:
185 lines 7.67 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.WebHelpManager = void 0; const fs = require("fs"); const path = require("path"); const Constants_1 = require("../../../constants/src/Constants"); const utilities_1 = require("../../../utilities"); const WebHelpGenerator_1 = require("./WebHelpGenerator"); const error_1 = require("../../../error"); /** * Imperative web help manager. Single instance class used to launch web help * in browser which handles (re)building web help files first if necessary. * @export * @class WebHelpManager */ class WebHelpManager { /** * Return a singleton instance of this class * @static * @readonly */ static get instance() { if (this.mInstance == null) { this.mInstance = new WebHelpManager(); } return this.mInstance; } /** * Launch root help page in browser. * @param {IHandlerResponseApi} cmdResponse - Command response object to use for output * @memberof WebHelpManager */ openRootHelp(cmdResponse) { this.openHelp(null, cmdResponse); } /** * Launch help page for specific group/command in browser. * @param {string} inContext - Name of page for group/command to jump to * @param {IHandlerResponseApi} cmdResponse - Command response object to use for output * @memberof WebHelpManager */ openHelp(inContext, cmdResponse) { const doWeHaveGui = utilities_1.ProcessUtils.isGuiAvailable(); if (doWeHaveGui !== utilities_1.GuiResult.GUI_AVAILABLE) { let errMsg = "You are running in an environment with no graphical interface." + "\nAlternatively, you can run '" + utilities_1.ImperativeConfig.instance.findPackageBinName() + " --help' for text-based help."; if (doWeHaveGui === utilities_1.GuiResult.NO_GUI_NO_DISPLAY) { errMsg += "\n\nIf you are running in an X Window environment," + "\nensure that your DISPLAY environment variable is set." + "\nFor example, type the following:" + "\n echo $DISPLAY" + "\nIf it is not set, assign a valid value. For example:" + "\n export DISPLAY=:0.0" + "\nThen try the --help-web option again."; } cmdResponse.console.log(errMsg); return; } const newMetadata = this.checkIfMetadataChanged(); if (newMetadata !== null) { new WebHelpGenerator_1.WebHelpGenerator(this.mFullCommandTree, utilities_1.ImperativeConfig.instance, this.webHelpDir). buildHelp(cmdResponse); this.writePackageMetadata(newMetadata); } cmdResponse.console.log("Launching web help in browser..."); /* Create launcher file in web help folder to jump to desired command. * This is kind of a hack, necessitated by the fact that unfortunately * Windows does not natively support passing URL search params to * file:/// links. Therefore the `p` parameter supported by the docs * site to load a page in-context cannot be used here. */ if (inContext != null) { const launcherPath = path.join(this.webHelpDir, "launcher.html"); fs.writeFileSync(launcherPath, `<html><head><meta http-equiv="refresh" content="0; url=index.html?p=${inContext}" /></head></html>`); } try { const htmlFile = inContext != null ? "launcher.html" : "index.html"; utilities_1.ProcessUtils.openInDefaultApp(`file:///${this.webHelpDir}/${htmlFile}`); } catch (e) { throw new error_1.ImperativeError({ msg: "Failed to launch web help, try running -h for console help instead", causeErrors: [e] }); } } /** * Record a reference to our CLI's full command tree. * @param fullCommandTree - The command tree. */ set fullCommandTree(fullCommandTree) { this.mFullCommandTree = fullCommandTree; } /** * Get a reference to our CLI's full command tree. * @returns The command tree. */ get fullCommandTree() { return this.mFullCommandTree; } /** * Gets the directory where built copy of web help is stored * @readonly * @private * @returns {string} Absolute path of directory */ get webHelpDir() { return path.join(utilities_1.ImperativeConfig.instance.cliHome, Constants_1.Constants.WEB_HELP_DIR); } /** * Computes current package metadata based on version of core and installed plug-ins * @private * @param packageJson - CLI package JSON * @param pluginsJson - Imperative plug-ins JSON * @returns {IWebHelpPackageMetadata[]} Names and versions of all components */ calcPackageMetadata(packageJson, pluginsJson) { return [ { name: packageJson.name, version: packageJson.version }, ...Object.keys(pluginsJson).map((name) => { return { name, version: pluginsJson[name].version }; }) ]; } /** * Compares two package metadata objects to see if they are equal * @private * @param {IWebHelpPackageMetadata[]} cached - Old cached package metadata * @param {IWebHelpPackageMetadata[]} current - Freshly computed package metadata * @returns {boolean} True if the package metadata objects are equal */ eqPackageMetadata(cached, current) { return JSON.stringify(cached.sort((a, b) => a.name.localeCompare(b.name))) === JSON.stringify(current.sort((a, b) => a.name.localeCompare(b.name))); } /** * Checks if cached package metadata is non-existent or out of date * @private * @returns {MaybePackageMetadata} Updated metadata, or `null` if cached metadata is already up to date */ checkIfMetadataChanged() { // Load cached metadata from file if it exists const metadataFile = path.join(this.webHelpDir, "metadata.json"); let cachedMetadata = []; if (fs.existsSync(metadataFile)) { cachedMetadata = require(metadataFile); } // Compute current metadata and compare it to cached const myConfig = utilities_1.ImperativeConfig.instance; const currentMetadata = this.calcPackageMetadata(myConfig.callerPackageJson, require(path.join(myConfig.cliHome, "plugins", "plugins.json"))); const metadataChanged = process.env.NODE_ENV === "development" || !this.eqPackageMetadata(cachedMetadata, currentMetadata); return metadataChanged ? currentMetadata : null; } /** * Updates cached package metadata * @private * @param {IWebHelpPackageMetadata[]} metadata - New metadata to save to disk */ writePackageMetadata(metadata) { const metadataFile = path.join(this.webHelpDir, "metadata.json"); fs.writeFileSync(metadataFile, JSON.stringify(metadata, null, 2)); } } exports.WebHelpManager = WebHelpManager; /** * Singleton instance of this class * @private * @static * @type {WebHelpManager} * @memberof WebHelpManager */ WebHelpManager.mInstance = null; //# sourceMappingURL=WebHelpManager.js.map