kibana/packages/kbn-repo-source-classifier
Gerard Soldevila 7b820130ab
[8.x] Add ESLINT constraints to detect inter-group dependencies (#194810) (#197670)
# Backport

This will backport the following commits from `main` to `8.x`:
- [Add ESLINT constraints to detect inter-group dependencies
(#194810)](https://github.com/elastic/kibana/pull/194810)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Gerard
Soldevila","email":"gerard.soldevila@elastic.co"},"sourceCommit":{"committedDate":"2024-10-22T11:34:19Z","message":"Add
ESLINT constraints to detect inter-group dependencies (#194810)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/kibana-team/issues/1175\r\n\r\nAs part of the
**Sustainable Kibana Architecture** initiative, this PR\r\nsets the
foundation to start classifying plugins in isolated groups,\r\nmatching
our current solutions / project types:\r\n\r\n* It adds support for the
following fields in the packages' manifests\r\n(kibana.jsonc):\r\n*
`group?: 'search' | 'security' | 'observability' | 'platform'
|\r\n'common'`\r\n * `visibility?: 'private' | 'shared'`\r\n\r\n* It
proposes a folder structure to automatically infer
groups:\r\n```javascript\r\n 'src/platform/plugins/shared': {\r\n group:
'platform',\r\n visibility: 'shared',\r\n },\r\n
'src/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/platform/plugins/shared':
{\r\n group: 'platform',\r\n visibility: 'shared',\r\n },\r\n
'x-pack/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n
'x-pack/solutions/observability/plugins': {\r\n group:
'observability',\r\n visibility: 'private',\r\n },\r\n
'x-pack/solutions/security/plugins': {\r\n group: 'security',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/solutions/search/plugins':
{\r\n group: 'search',\r\n visibility: 'private',\r\n },\r\n```\r\n\r\n*
If a plugin is moved to one of the specific locations above, the
group\r\nand visibility in the manifest (if specified) must match those
inferred\r\nfrom the path.\r\n* Plugins that are not relocated are
considered: `group: 'common',\r\nvisibility: 'shared'` by default. As
soon as we specify a custom\r\n`group`, the ESLINT rules will check
violations against dependencies /\r\ndependants.\r\n\r\nThe ESLINT rules
are pretty simple:\r\n* Plugins can only depend on:\r\n * Plugins in the
same group\r\n * OR plugins with `'shared'` visibility\r\n* Plugins in
`'observability', 'security', 'search'` groups are\r\nmandatorily
`'private'`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2a085e103afe8c7bdfb626d0dc683fc8be0e6c05","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","backport
missing","v9.0.0","release_note:feature","backport:prev-minor"],"number":194810,"url":"https://github.com/elastic/kibana/pull/194810","mergeCommit":{"message":"Add
ESLINT constraints to detect inter-group dependencies (#194810)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/kibana-team/issues/1175\r\n\r\nAs part of the
**Sustainable Kibana Architecture** initiative, this PR\r\nsets the
foundation to start classifying plugins in isolated groups,\r\nmatching
our current solutions / project types:\r\n\r\n* It adds support for the
following fields in the packages' manifests\r\n(kibana.jsonc):\r\n*
`group?: 'search' | 'security' | 'observability' | 'platform'
|\r\n'common'`\r\n * `visibility?: 'private' | 'shared'`\r\n\r\n* It
proposes a folder structure to automatically infer
groups:\r\n```javascript\r\n 'src/platform/plugins/shared': {\r\n group:
'platform',\r\n visibility: 'shared',\r\n },\r\n
'src/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/platform/plugins/shared':
{\r\n group: 'platform',\r\n visibility: 'shared',\r\n },\r\n
'x-pack/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n
'x-pack/solutions/observability/plugins': {\r\n group:
'observability',\r\n visibility: 'private',\r\n },\r\n
'x-pack/solutions/security/plugins': {\r\n group: 'security',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/solutions/search/plugins':
{\r\n group: 'search',\r\n visibility: 'private',\r\n },\r\n```\r\n\r\n*
If a plugin is moved to one of the specific locations above, the
group\r\nand visibility in the manifest (if specified) must match those
inferred\r\nfrom the path.\r\n* Plugins that are not relocated are
considered: `group: 'common',\r\nvisibility: 'shared'` by default. As
soon as we specify a custom\r\n`group`, the ESLINT rules will check
violations against dependencies /\r\ndependants.\r\n\r\nThe ESLINT rules
are pretty simple:\r\n* Plugins can only depend on:\r\n * Plugins in the
same group\r\n * OR plugins with `'shared'` visibility\r\n* Plugins in
`'observability', 'security', 'search'` groups are\r\nmandatorily
`'private'`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2a085e103afe8c7bdfb626d0dc683fc8be0e6c05"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194810","number":194810,"mergeCommit":{"message":"Add
ESLINT constraints to detect inter-group dependencies (#194810)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/kibana-team/issues/1175\r\n\r\nAs part of the
**Sustainable Kibana Architecture** initiative, this PR\r\nsets the
foundation to start classifying plugins in isolated groups,\r\nmatching
our current solutions / project types:\r\n\r\n* It adds support for the
following fields in the packages' manifests\r\n(kibana.jsonc):\r\n*
`group?: 'search' | 'security' | 'observability' | 'platform'
|\r\n'common'`\r\n * `visibility?: 'private' | 'shared'`\r\n\r\n* It
proposes a folder structure to automatically infer
groups:\r\n```javascript\r\n 'src/platform/plugins/shared': {\r\n group:
'platform',\r\n visibility: 'shared',\r\n },\r\n
'src/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/platform/plugins/shared':
{\r\n group: 'platform',\r\n visibility: 'shared',\r\n },\r\n
'x-pack/platform/plugins/internal': {\r\n group: 'platform',\r\n
visibility: 'private',\r\n },\r\n
'x-pack/solutions/observability/plugins': {\r\n group:
'observability',\r\n visibility: 'private',\r\n },\r\n
'x-pack/solutions/security/plugins': {\r\n group: 'security',\r\n
visibility: 'private',\r\n },\r\n 'x-pack/solutions/search/plugins':
{\r\n group: 'search',\r\n visibility: 'private',\r\n },\r\n```\r\n\r\n*
If a plugin is moved to one of the specific locations above, the
group\r\nand visibility in the manifest (if specified) must match those
inferred\r\nfrom the path.\r\n* Plugins that are not relocated are
considered: `group: 'common',\r\nvisibility: 'shared'` by default. As
soon as we specify a custom\r\n`group`, the ESLINT rules will check
violations against dependencies /\r\ndependants.\r\n\r\nThe ESLINT rules
are pretty simple:\r\n* Plugins can only depend on:\r\n * Plugins in the
same group\r\n * OR plugins with `'shared'` visibility\r\n* Plugins in
`'observability', 'security', 'search'` groups are\r\nmandatorily
`'private'`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"2a085e103afe8c7bdfb626d0dc683fc8be0e6c05"}}]}]
BACKPORT-->
2024-10-24 13:20:30 -07:00
..
src [8.x] Add ESLINT constraints to detect inter-group dependencies (#194810) (#197670) 2024-10-24 13:20:30 -07:00
index.ts Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
jest.config.js Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
kibana.jsonc Transpile packages on demand, validate all TS projects (#146212) 2022-12-22 19:00:29 -06:00
package.json Adds AGPL 3.0 license (#192025) 2024-09-06 19:02:41 -06:00
README.mdx
tsconfig.json [8.x] Add ESLINT constraints to detect inter-group dependencies (#194810) (#197670) 2024-10-24 13:20:30 -07:00

---
id: kibDevDocsOpsRepoSourceClassifier
slug: /kibana-dev-docs/ops/repo-source-classifier
title: "@kbn/repo-source-classifier"
description: 'The tool which classifies source files into categories'
date: 2022-07-25
tags: ['kibana', 'dev', 'contributor', 'operations', 'packages', 'scripts']
---

This package exposes a class which can be used to efficiently classify all of the files in the repository into one of the following groups:

- `server package`: plugin code in the root `server/` directory, eventually this will include packages of type `server-plugin` or `server-shared`
 - `browser package`: plugin code in the root `public/` directory (and a few others in specific plugins), eventually this will include packages of type `browser-plugin` or `browser-shared`
 - `common packages`: includes any existing package, plugin code in root `common/` directories, (and a few others in specific plugins), Eventually this will include `common-shared` packages
 - `tests 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 via `raw-loader` in browser code
 - `tooling`: 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/pm`

This is a map of types to the types they are allowed to import:
 - `non-package`: `non-package`, `server package`, `browser package`, `common package` or `static`
 - `server package`: `common package`, `server package`, or `static`
 - `browser package`: `common package`, `browser package`, or `static`
 - `common package`: `common package` or`static`
 - `static`: static files are not allowed to have dependencies
 - `tests or mocks`: anything
 - `tooling`: anything

The `RepoSourceClassifier` class implements several caches to make these lookups as efficient as possible in ESLint when all imports across the entire repository are validated. This cache lasts for the lifetime of the class and to invalidate the cache the object should just be discarded and a new instance created.

A CLI is provided for inspecting the results of the classifier, check out `node scripts/classify_source --help` for more information about usage.