Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

plugins.js 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /**
  2. * @fileoverview Plugins manager
  3. * @author Nicholas C. Zakas
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const debug = require("debug")("eslint:plugins");
  10. const naming = require("../util/naming");
  11. const path = require("path");
  12. //------------------------------------------------------------------------------
  13. // Public Interface
  14. //------------------------------------------------------------------------------
  15. /**
  16. * Plugin class
  17. */
  18. class Plugins {
  19. /**
  20. * Creates the plugins context
  21. * @param {Environments} envContext - env context
  22. * @param {Rules} rulesContext - rules context
  23. */
  24. constructor(envContext, rulesContext) {
  25. this._plugins = Object.create(null);
  26. this._environments = envContext;
  27. this._rules = rulesContext;
  28. }
  29. /**
  30. * Defines a plugin with a given name rather than loading from disk.
  31. * @param {string} pluginName The name of the plugin to load.
  32. * @param {Object} plugin The plugin object.
  33. * @returns {void}
  34. */
  35. define(pluginName, plugin) {
  36. const longName = naming.normalizePackageName(pluginName, "eslint-plugin");
  37. const shortName = naming.getShorthandName(longName, "eslint-plugin");
  38. // load up environments and rules
  39. this._plugins[shortName] = plugin;
  40. this._environments.importPlugin(plugin, shortName);
  41. this._rules.importPlugin(plugin, shortName);
  42. }
  43. /**
  44. * Gets a plugin with the given name.
  45. * @param {string} pluginName The name of the plugin to retrieve.
  46. * @returns {Object} The plugin or null if not loaded.
  47. */
  48. get(pluginName) {
  49. return this._plugins[pluginName] || null;
  50. }
  51. /**
  52. * Returns all plugins that are loaded.
  53. * @returns {Object} The plugins cache.
  54. */
  55. getAll() {
  56. return this._plugins;
  57. }
  58. /**
  59. * Loads a plugin with the given name.
  60. * @param {string} pluginName The name of the plugin to load.
  61. * @returns {void}
  62. * @throws {Error} If the plugin cannot be loaded.
  63. */
  64. load(pluginName) {
  65. const longName = naming.normalizePackageName(pluginName, "eslint-plugin");
  66. const shortName = naming.getShorthandName(longName, "eslint-plugin");
  67. let plugin = null;
  68. if (pluginName.match(/\s+/)) {
  69. const whitespaceError = new Error(`Whitespace found in plugin name '${pluginName}'`);
  70. whitespaceError.messageTemplate = "whitespace-found";
  71. whitespaceError.messageData = {
  72. pluginName: longName
  73. };
  74. throw whitespaceError;
  75. }
  76. if (!this._plugins[shortName]) {
  77. try {
  78. plugin = require(longName);
  79. } catch (pluginLoadErr) {
  80. try {
  81. // Check whether the plugin exists
  82. require.resolve(longName);
  83. } catch (missingPluginErr) {
  84. // If the plugin can't be resolved, display the missing plugin error (usually a config or install error)
  85. debug(`Failed to load plugin ${longName}.`);
  86. missingPluginErr.message = `Failed to load plugin ${pluginName}: ${missingPluginErr.message}`;
  87. missingPluginErr.messageTemplate = "plugin-missing";
  88. missingPluginErr.messageData = {
  89. pluginName: longName,
  90. eslintPath: path.resolve(__dirname, "../..")
  91. };
  92. throw missingPluginErr;
  93. }
  94. // Otherwise, the plugin exists and is throwing on module load for some reason, so print the stack trace.
  95. throw pluginLoadErr;
  96. }
  97. // This step is costly, so skip if debug is disabled
  98. if (debug.enabled) {
  99. const resolvedPath = require.resolve(longName);
  100. let version = null;
  101. try {
  102. version = require(`${longName}/package.json`).version;
  103. } catch (e) {
  104. // Do nothing
  105. }
  106. const loadedPluginAndVersion = version
  107. ? `${longName}@${version}`
  108. : `${longName}, version unknown`;
  109. debug(`Loaded plugin ${pluginName} (${loadedPluginAndVersion}) (from ${resolvedPath})`);
  110. }
  111. this.define(pluginName, plugin);
  112. }
  113. }
  114. /**
  115. * Loads all plugins from an array.
  116. * @param {string[]} pluginNames An array of plugins names.
  117. * @returns {void}
  118. * @throws {Error} If a plugin cannot be loaded.
  119. * @throws {Error} If "plugins" in config is not an array
  120. */
  121. loadAll(pluginNames) {
  122. // if "plugins" in config is not an array, throw an error so user can fix their config.
  123. if (!Array.isArray(pluginNames)) {
  124. const pluginNotArrayMessage = "ESLint configuration error: \"plugins\" value must be an array";
  125. debug(`${pluginNotArrayMessage}: ${JSON.stringify(pluginNames)}`);
  126. throw new Error(pluginNotArrayMessage);
  127. }
  128. // load each plugin by name
  129. pluginNames.forEach(this.load, this);
  130. }
  131. }
  132. module.exports = Plugins;