Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Including the presets and plugins module path into config.metadata #43

Merged
merged 15 commits into from
Aug 13, 2019

Conversation

DanielSanudo
Copy link
Contributor

Summary

Including the presets and plugins module path into config.metadata.presets and config.metadata.plugins.

This will allow us to access to the module path from the plugin lifecycles. Immediate use cases will be for metadata and docs lifecycles.

Changelog

Test Plan

Unit tests included for the different cases.

SivanMehta
SivanMehta previously approved these changes Aug 5, 2019
Copy link
Contributor

@SivanMehta SivanMehta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hit the wrong radio 🤦‍♂

@SivanMehta SivanMehta dismissed their stale review August 5, 2019 17:41

should have been a comment, not an approval

fullName => `Plugin ${fullName} could not be resolved. Make sure it is installed.`);
}

pluginFullName(name) {
return `@gasket/${name}-plugin`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works for short-named gasket plugins. This is not going to work for user plugins (i.e. @my/fancy-gasket-plugin) or if the user specified the full name in the config (i.e. @gasket/express-plugin).

Instead, let's centralize these by using the pluginIdentifier helper from:
https://github.com/godaddy/gasket/blob/master/packages/gasket-cli/src/scaffold/package-identifier.js

It would probably be best to move package-identifier.js and tests from the cli to the resolve package, with the identifiers exposed for the cli to also utilize:

const { pluginIdentifier } = require(`@gasket/resolve`);

@@ -32,7 +36,7 @@ module.exports = class Resolver {

return this.resolveShorthandModule(
name,
shortName => `@gasket/${shortName}-preset`,
this.presetFullName,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment, and use presetIdentifier here instead.

if (pluginName.indexOf('/') !== -1) {
const relativePath = path.relative(rootPath, pluginName);
const pluginKey = path.basename(pluginName).replace('-plugin', '');
this.config.metadata.plugins[pluginKey] = { modulePath: `./${relativePath}` };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to avoid using / directly in your paths. This will likely cause issues on Windows machines.

Copy link
Member

@Swaagie Swaagie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, no additional comments, on green ✅ from all reviewers

* Saves into the gasket config the module path of the presets
*
* @private
* @param {Array} presets Array of presets
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: this order is usually inverted, e.g. params first and then scope.

@DanielSanudo
Copy link
Contributor Author

DanielSanudo commented Aug 7, 2019

@SivanMehta @kinetifex @Swaagie Related to building the paths, this is the format that was defined in the docs, https://github.secureserver.net/UX/uxp-pdrs/blob/master/gasket/docs-command.md#gathering-data.

I ended up getting

modulePath: '/node_modules/@gasket/plugin-fastify'

instead of ( see the dot at the start of the path )

modulePath: './node_modules/@gasket/plugin-fastify'

by using the following code. Is there another way of getting what was defined in the docs?

relativePath = path.join('//', relativePath);

@kinetifex
Copy link
Contributor

Oh, I see why you were trying to do that now. It's actually sufficient to just have relative path be:

modulePath: 'node_modules/@gasket/plugin-fastify'

and not bother trying to add the extra ./

Copy link
Contributor

@kinetifex kinetifex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't know the resolve or plugin-engine code base too well.
I'd definitely recommend a review from @indexzero here, though I left some comments regarding some code organization that make help keeps things cleaner.

@@ -13,10 +14,14 @@ module.exports = class Resolver {

return this.resolveShorthandModule(
name,
shortName => `@gasket/${shortName}-plugin`,
this.pluginFullName,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this pluginFullName static method, instead just use pluginIdentifier directly here.

Suggested change
this.pluginFullName,
shortName => pluginIdentifier(shortName).fullName,

@@ -32,7 +37,7 @@ module.exports = class Resolver {

return this.resolveShorthandModule(
name,
shortName => `@gasket/${shortName}-preset`,
this.presetFullName,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this presetFullName static method, instead just use presetIdentifier directly here.

Suggested change
this.presetFullName,
shortName => presetIdentifier(shortName).fullName,


it('pluginFullName returns expected full name', () => {
const resolver = new Resolver();
const result = resolver.pluginFullName('pluginName');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop these fullName static methods and tests from Resolver, since they are effectively redundant to the identifier functions.

* @private
* @param {Array} plugins Array of plugins
*/
_registerPluginsModulePath(plugins) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like a lot of this code should be owned by the Resolver, and is related to:
https://github.com/godaddy/gasket/blob/master/packages/gasket-resolve/resolver.js#L52-L55

Maybe add a related resolver.tryResolve like:

tryResolve(moduleName) {
  const options = this.resolveFrom ? { paths: [this.resolveFrom] } : {};
  // may want to wrap this in a try/catch
  return require.resolve(moduleName, options);
}

That way, you can utilize the resolveFrom option, instead of deriving your own rootPath.

See the require.resolve docs.

* @returns {Path} root path of the app
*/
_rootPath() {
return path.resolve(__dirname).split('/node_modules')[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root path is already provided by the cli when instantiating the PluginEngine. See: https://github.com/godaddy/gasket/blob/master/packages/gasket-cli/src/config/loader.js#L11

It would be good to clear this up in the PluginEngine API, and add a safety check with:

class PluginEngine {
  constructor(config, { resolveFrom } = {}) {
    this.config = config || {};
+    this.config.root = this.config.root || process.cwd()

* @param {String} module module
* @returns {Path} path of the module
*/
_resolveModulePath(module) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many consoles.logs!

But either way, probably would be better owned by the Resolver (see other comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this ended up here xd, I will remove the logs.

var pluginNameKey;
// Plugins that are defined locally to the app
if (pluginName.indexOf(this.config.root) !== -1) {
pluginNameKey = path.basename(pluginName).replace('-plugin', '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need really this fixup to remove -plugin? Seems like that could give confusing results, being a short name, which is reserved for @gasket/<name>-plugin formatted plugins.

In fact, it would probably be best to include plugins/ in this key name, to delineate an app plugin, from a node_module plugin.

So, for example, if a user has these plugins:

  • example — resolved short name for @gasket/example-plugin
  • example-plugin
  • plugins/example-plugin — avoids collision with example-plugin

Copy link
Contributor Author

@DanielSanudo DanielSanudo Aug 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is only applied to the local plugins that are defined under plugin/something-plugin, it will not affect to any @gasket/<name>-plugin. What I am doing is getting something-pluginand removing -plugin from it to use it as the key.
Metadata will appear as this:

metadata: {
  plugins: {
    pluginA: 'plugins/pluginA-plugin'
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you prefer to have something else as key I can work on that.

* @returns {Path} relative path of the preset
* @public
*/
tryResolvePresetRelativePath(presetName, appRootPath) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tryResolvePresetRelativePath and tryResolvePluginRelativePath are effectively the same code. Why not just have a single tryResolveRelative(pkgName) then the consumer passes in the package name they want. That way, this could resolve for non-preset/plugin packages, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are not exactly the same, I need to use presetIdentifier or pluginIdentifier depending on which one and also I need to handle the case of a local plugin before calling pluginIdentifier.

* Returns the relative path of the preset
*
* @param {String} presetName name of the preset
* @param {String} appRootPath root path of the app
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just make root an option when instantiating the Resolver? Then the consumer doesn't have to keep track and pass it to this method.

constructor({ resolveFrom, resolve, root = process.cwd() } = {}) {

@kinetifex kinetifex requested a review from indexzero August 12, 2019 17:01
@DanielSanudo DanielSanudo force-pushed the register_module_paths branch from 07cec4d to c002a8a Compare August 13, 2019 13:21
@DanielSanudo DanielSanudo merged commit cbe42ca into master Aug 13, 2019
@DanielSanudo DanielSanudo deleted the register_module_paths branch August 13, 2019 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants