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

fix: update usages of ExternalNpmPackageInfo.path to be safe and default to empty string #2881

Merged
merged 1 commit into from
Aug 22, 2021

Conversation

dgp1130
Copy link
Contributor

@dgp1130 dgp1130 commented Aug 22, 2021

ExternalNpmPackageInfo had a path attribute introduced and used in
2c2cc6e, but the provider was publicly exported beforehand. Even
though all internal usages were updated to include a path, this change was shipped in 3.2.0 and
introduced an unintentional breaking change for consumers. Most notably, rules_postcss manually
implements this provider and does not give a path failing in versions 3.2.0 and up.

https://github.com/bazelbuild/rules_postcss/blob/2bd16fda40cd4bf4fbf0b477b968366ec1602103/internal/plugin.bzl#L30-L41

Solution here is to safely retrieve the path attribute and default to empty string at all places
it is used. A test is also introduced to ensure that a nodejs_binary() can depend on a custom
ExternalNpmPackageInfo provider without a path attribute, which should hopefully prevent against
regressions.

PR Checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • [N/A] Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix

What is the current behavior?

Usage of custom rules which provide ExternalNpmPackageInfo without a path attribute, break in versions 3.2.0 and up.

ERROR: /home/dparker/Source/rules_prerender/examples/styles/BUILD.bazel:5:16: in nodejs_binary rule //examples/styles:page_styles.postcss_runner: 
Traceback (most recent call last):
        File "/home/dparker/.cache/bazel/_bazel_dparker/3b4ba8c4eec5951318c36cb07368e75b/external/build_bazel_rules_nodejs/internal/node/node.bzl", line 155, column 56, in _nodejs_binary_impl
                node_modules_manifest = write_node_modules_manifest(ctx, link_workspace_root = ctx.attr.link_workspace_root)
        File "/home/dparker/.cache/bazel/_bazel_dparker/3b4ba8c4eec5951318c36cb07368e75b/external/build_bazel_rules_nodejs/internal/linker/link_node_modules.bzl", line 72, column 47, in write_node_modules_manifest
                path = dep[ExternalNpmPackageInfo].path
Error: 'ExternalNpmPackageInfo' value has no field or method 'path'
Available attributes: direct_sources, sources, workspace

What is the new behavior?

All usages of an ExternalNpmPackageInfo provider with no path attribute, default to the empty string, meaning they will be linked at the root.

Does this PR introduce a breaking change?

  • No

Other information

This bug appears to have been a regression in 3.2.0 which broke rules_postcss, as its plugins return a custom ExternalNpmPackageInfo provider that does not contain a path, leading to the above error when using postcss_binary() with rules_nodejs@>=3.2.0.

Considering that this shipped without note in 3.2.0 and in a minor version, I'm assuming this was a regression rather than a deliberate breaking change, so this PR simply provides a default value for a missing path field. Since then, 4.0.0 was released, so we technically could argue this is just an undocumented breaking change in 4.0.0. I'm not sure if 3.x.x is still supported, but if not we could just call this a breaking change and the path field is now required. I'm inclined not to do that if possible and actually fix the bug in rules_nodejs, which is the strategy this PR attempts to do.

I'm not very familiar with the test infrastructure of rules_nodejs. I think I put this test in the right package, but most of the other packages use a linker() rule that I don't fully understand. I found that nodejs_binary() was sufficient to reproduce the bug, so I just tested with that. Let me know if using linker() would be more appropriate here.

More context about how I came across this regression: dgp1130/rules_prerender#39.

…fault to empty string

`ExternalNpmPackageInfo` had a `path` attribute introduced and used in
2c2cc6e, but the provider was publicly exported beforehand. Even
though all internal usages were updated to include a path, this change was shipped in `3.2.0` and
introduced an unintentional breaking change for consumers. Most notably, `rules_postcss` manually
implements this provider and does not give a `path` failing in versions `3.2.0` and up.

https://github.com/bazelbuild/rules_postcss/blob/2bd16fda40cd4bf4fbf0b477b968366ec1602103/internal/plugin.bzl#L30-L41

Solution here is to safely retrieve the `path` attribute and default to empty string at all places
it is used. A test is also introduced to ensure that a `nodejs_binary()` can depend on a custom
`ExternalNpmPackageInfo` provider without a `path` attribute, which should hopefully prevent against
regressions.
Copy link
Collaborator

@alexeagle alexeagle left a comment

Choose a reason for hiding this comment

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

thanks for catching that subtle breaking change!

I'll cherry-pick this to 4.x. Do you think it's also necessary for postcss that we publish one more 3.x release with this bugfix?

@alexeagle alexeagle merged commit b836b11 into bazel-contrib:stable Aug 22, 2021
@dgp1130 dgp1130 deleted the external-npm-package-info branch August 22, 2021 22:25
@dgp1130
Copy link
Contributor Author

dgp1130 commented Aug 22, 2021

AFAICT rules_postcss is effectively unusable in 3.2.0+, since you kinda have to use plugins to do anything useful. I recommend releasing this to 3.x.x just to have at least one fixed version before having to deal with 4.0.0's breaking changes.

@alexeagle
Copy link
Collaborator

okay that's fair, I can do a patch of 3.8 this week

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants