[eslint] fix and skip violations for cross-boundary imports#136911
[eslint] fix and skip violations for cross-boundary imports#136911spalger merged 16 commits intoelastic:mainfrom
Conversation
dd3a065 to
1792bb0
Compare
5e20d2b to
fd6a2a2
Compare
1fbdfe4 to
4884add
Compare
There was a problem hiding this comment.
"scripts" directories are used to store tooling files, which are only necessary for local development and not a part of package source code. I hope this rename is acceptable
f3a1521 to
ea8348e
Compare
There was a problem hiding this comment.
helpers is a pretty ambiguous name, so I renamed the directory to test_helpers to be more clear about the purpose of the code and allow the classifier to assert that this is test code which shouldn't be imported by non-test code.
ea8348e to
89cdd13
Compare
marshallmain
left a comment
There was a problem hiding this comment.
Detection alerts changes LGTM
efegurkan
left a comment
There was a problem hiding this comment.
Enterprise Search look good
rshen91
left a comment
There was a problem hiding this comment.
Shared UX services changes LGTM thanks!
tsullivan
left a comment
There was a problem hiding this comment.
app services / reporting services changes are LGTM
ThomThomson
left a comment
There was a problem hiding this comment.
Presentation team import changes LGTM!
mistic
left a comment
There was a problem hiding this comment.
Changes on files under operations team code owners LGTM
dominiqueclarke
left a comment
There was a problem hiding this comment.
Uptime changes lgtm. Thanks!
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Unknown metric groupsESLint disabled in files
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
drewdaemon
left a comment
There was a problem hiding this comment.
Vis editors changes LGTM!
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
|
|
||
| export { coreDeprecationProvider } from './deprecation'; | ||
| export { ensureValidConfiguration } from './ensure_valid_configuration'; | ||
| // eslint-disable-next-line @kbn/imports/no_boundary_crossing |
There was a problem hiding this comment.
The problem here is that test_utils are assumed to be code only intended for use by tests, but it's imported from the index.ts file of the package, meaning that it's included in the distributable and these test helpers are exposed to everyone who imports this package. If these helpers are actually used in other packages then we will need to move them to a new test-helpers package (though we can't define the type of the package yet, that would be it's purpose and it's name should reflect that somehow). Then we can import the @kbn/core-config-server-test-helpers package in the local tests and in the other packages which use them.
If these test helpers are not actually needed outside this package then this export ... from statement can just be removed.
Sorry this isn't short, but there's lots of context here.
You're probably familiar with the
@kbn/eslint/no-restricted-pathsrule. This rule attempted to prevent the problems caused by importing server code in public code (and vice-versa) but it was implemented in a very generic way which made it difficult to understand and harder to make work for everything. Now it's very common for people to use// eslint-disablecomments to disable this rule, but the new packaging project relies on these assertions so we need to make them actually work and then break our habits of disabling the rule. This PR is a step in that direction by implementing a new rule,@kbn/imports/no_boundary_crossing, that's described below and removing the@kbn/eslint/no-restricted-pathsrule.In short, the purpose of this rule is similar to
@kbn/eslint/no-restricted-pathsexcept that:import typestatements can reach into any package, including from the server to the browser and back (though circular deps are still not supported)For now, any instance of
// eslint-disablecomments for the@kbn/imports/no_boundary_crossingrule is an example of an import that won't be supported in the new package system and is likely unintentional and either should be removed or moved out to a different location.We're starting by disabling the rule in these locations and once this is merged I'll be working with teams and creating issues, providing details about the steps necessary to get rid of these disables and pave the way for the relevant code to be migrated to packages.
A recently opened RFC will reduce some of the complexity of this rule. It's currently easy to know when you're looking at a Jest unit test file, we want similar clarity for other types of files.
What's going on here?
An early component of the internal dependency management project (package all the things) is getting a handle on the purpose of each file in the repository. This will ease the process of migrating the code to packages, and help identify likely problem areas for migration.
To accomplish this I've added a new ESLint rule
@kbn/imports/no_boundary_crossingwhich classifies the linted source file with@kbn/repo-source-classifier, traverses the AST to find all imports, resolves those imports, and then classifies the imported file. It then makes sure that the source file is allowed to import each thing it does import and report errors when we're breaking the rules.The types of code that can exist are:
server package: plugin code in the rootserver/directory, eventually this will include packages of typeserver-pluginorserver-sharedbrowser package: plugin code in the rootpublic/directory (and a few others in specific plugins), eventually this will include packages of typebrowser-pluginorbrowser-sharedcommon packages: includes any existing package, plugin code in rootcommon/directories, (and a few others in specific plugins), Eventually this will includecommon-sharedpackagestests or mocks: code that is loaded by jest/storybook and mocks/helpers intended for use by that code. These files usually live along side package code but will have a separate dependency tree and are pieces of code which should never end up in the product.static: static files, currently any .json file or things loaded viaraw-loaderin browser codetooling: scripts, config files for tools like eslint, webpack, etc.non-package: code that lives outside of packages/plugins or doesn't fit into other more specific categories. Once the package project is complete this category should be limited to just@kbn/pmThis is a map of types to the types they are allowed to import:
import type'dnon-package:non-package,server package,browser package,common packageorstaticserver package:common package,server package, orstaticbrowser package:common package,browser package, orstaticcommon package:common packageorstaticstatic: static files are not allowed to have dependenciestests or mocks: anythingtooling: anythingTo inspect how files are being classified, you can use the
node scripts/classify_source --helpCLI.Here is a detailed description of how files are classified by this PR. These rules are applied in order and the first rule to match the path in question defines the type of the file:
.jsonextension it is of typestatictest or mocks:mock_*_and includes any well known "test tag" (see TEST_TAG list)tooling:scriptsdirectory (excludingsrc/plugins/data/server/scripts)webpack.configand is not in the@kbn/optimizerpackagenon-packagemocks,storybookortestthen the type istest or mockscommon package@kbn/corepackage and within the roottypesdirectory then the type iscommon package@kbn/canvas-pluginpackage then a set of custom rules is applied for canvas, as agreed upon with that teampublicorstaticdirectory of a package/plugin then it is of typebrowser packageserverdirectory of a package/plugin then it is of typeserver packagecommon packageThese rules are complicated, but they are only necessary during the transition to packages. Once all of the code is migrated to package (and packages have types) the code will describe it's own type. The only exception to this rule is test code, which lives along-side implementation code in packages and needs to be properly removed from package before they are used for Kibana, or included in the distributable. Because of this we recently opened an RFC to choose standard naming we can use across the repository for test-specific code, tooling, and other specific types of code.
In the cases where the classifier was identified to be making the right decision, but the code was still violating the rules, an
// eslint-disable-next-line @kbn/imports/no_boundary_crossingcomment was used to disable the ESLint violation in that spot. I will be opening issues for each team which has these comments, as they need to be resolved ASAP so that we can protect this ESLint rule and prevent additional violations from being committed to the repository (which will simply make the migration to packages more challenging for teams).