feat(bazel): validate that checked-in bundles are ignored in prettierignore#3707
feat(bazel): validate that checked-in bundles are ignored in prettierignore#3707josephperrott wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a validation mechanism to ensure that checked-in bundles generated by the esbuild_checked_in macro are correctly ignored in .prettierignore. It adds a new Bazel validation rule validate_prettierignore and a supporting Node.js script verify-prettierignore.mjs. The review feedback identifies several critical improvements: handling Windows path separators (\\) in the verification script to prevent regex failures, normalizing .prettierignore patterns by stripping leading ./ or / to avoid false negatives, and forwarding common test attributes (such as tags and testonly) from the macros to the underlying js_test to ensure correct test execution behavior.
| // We need to clean it up to match the relative workspace path. | ||
| // Aspect JS rules prefix the path with the workspace name segment (e.g. "_main" or "devinfra"). | ||
| // Removing the first segment gets the workspace-relative path. | ||
| const relativePath = bundlePath.replace(/^[^/]+\//, ''); |
There was a problem hiding this comment.
On Windows, bundlePath may contain backslashes (\\) instead of forward slashes (/). This will cause the regex replacement to fail to strip the workspace prefix, and the resulting path will not match the forward-slash format used in .prettierignore.
To ensure Windows compatibility (as required by the general rules), we should normalize the path separators to forward slashes before processing.
| const relativePath = bundlePath.replace(/^[^/]+\//, ''); | |
| const normalizedBundlePath = bundlePath.replace(/\\/g, '/'); | |
| const relativePath = normalizedBundlePath.replace(/^[^/]+\//, ''); |
| const ignoredFiles = new Set( | ||
| prettierIgnoreContent | ||
| .split(/\r?\n/) | ||
| .map((line) => line.trim()) | ||
| .filter((line) => line && !line.startsWith('#')), | ||
| ); |
There was a problem hiding this comment.
.prettierignore entries often start with / or ./ to specify paths relative to the workspace root (e.g., /foo/bar.js or ./foo/bar.js). Since relativePath does not have a leading slash, a direct Set.has check will fail to match these entries.
We can normalize the ignore patterns by stripping leading / and ./ prefixes to prevent false negatives.
| const ignoredFiles = new Set( | |
| prettierIgnoreContent | |
| .split(/\r?\n/) | |
| .map((line) => line.trim()) | |
| .filter((line) => line && !line.startsWith('#')), | |
| ); | |
| const ignoredFiles = new Set( | |
| prettierIgnoreContent | |
| .split(/\r?\n/) | |
| .map((line) => line.trim()) | |
| .filter((line) => line && !line.startsWith('#')) | |
| .map((line) => line.replace(/^\.?\//, '')), | |
| ); |
| def validate_prettierignore(name, prettierignore, bundle): | ||
| js_test( | ||
| name = name, | ||
| data = [ | ||
| prettierignore, | ||
| bundle, | ||
| ], | ||
| entry_point = "@devinfra//bazel/validation:verify-prettierignore", | ||
| fixed_args = [ | ||
| "$(rlocationpath %s)" % prettierignore, | ||
| "$(rlocationpath %s)" % bundle, | ||
| ], | ||
| ) |
There was a problem hiding this comment.
The validate_prettierignore macro does not accept or forward common test attributes (such as tags, testonly, timeout, etc.) to the underlying js_test.
If esbuild_checked_in is called with specific tags (e.g., tags = ["manual"]) or other attributes, they won't be applied to the validation test, which can lead to unexpected test execution behavior.
We should accept **kwargs in validate_prettierignore and forward them to js_test.
| def validate_prettierignore(name, prettierignore, bundle): | |
| js_test( | |
| name = name, | |
| data = [ | |
| prettierignore, | |
| bundle, | |
| ], | |
| entry_point = "@devinfra//bazel/validation:verify-prettierignore", | |
| fixed_args = [ | |
| "$(rlocationpath %s)" % prettierignore, | |
| "$(rlocationpath %s)" % bundle, | |
| ], | |
| ) | |
| def validate_prettierignore(name, prettierignore, bundle, **kwargs): | |
| js_test( | |
| name = name, | |
| data = [ | |
| prettierignore, | |
| bundle, | |
| ], | |
| entry_point = "@devinfra//bazel/validation:verify-prettierignore", | |
| fixed_args = [ | |
| "$(rlocationpath %s)" % prettierignore, | |
| "$(rlocationpath %s)" % bundle, | |
| ], | |
| **kwargs | |
| ) |
| validate_prettierignore( | ||
| name = "%s_prettierignore_test" % name, | ||
| prettierignore = "//:prettierignore", | ||
| bundle = "%s.js" % name, | ||
| ) |
There was a problem hiding this comment.
To ensure that the validation test inherits the correct tags and testonly attributes from the parent esbuild_checked_in macro, we should retrieve and pass them to validate_prettierignore.
| validate_prettierignore( | |
| name = "%s_prettierignore_test" % name, | |
| prettierignore = "//:prettierignore", | |
| bundle = "%s.js" % name, | |
| ) | |
| validate_prettierignore( | |
| name = "%s_prettierignore_test" % name, | |
| prettierignore = "//:prettierignore", | |
| bundle = "%s.js" % name, | |
| tags = kwargs.get("tags", []), | |
| testonly = kwargs.get("testonly", False), | |
| ) |
48a6e62 to
b496c1b
Compare
Adds a Bazel js_test validation check to the esbuild_checked_in macro that asserts that the checked-in bundle is ignored in .prettierignore, preventing format check-in mismatches.