@ovh-ux/manager-static-analysis-kit 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +59 -69
- package/bin/cli-path-config.js +31 -0
- package/bin/code-duplication-cli.js +96 -0
- package/bin/code-duplication-tests-cli.js +68 -0
- package/bin/lint-cli.js +18 -16
- package/bin/perf-budgets-cli.js +120 -0
- package/bin/perf-budgets-tests-cli.js +72 -0
- package/bin/static-dynamic-quality-checks.js +138 -0
- package/bin/tests-coverage-cli-tests.js +67 -0
- package/bin/tests-coverage-cli.js +135 -0
- package/bin/types-coverage-cli.js +127 -0
- package/bin/types-coverage-tests-cli.js +68 -0
- package/bin/utils/apps-utils.js +64 -0
- package/bin/utils/args-parse-utils.js +222 -0
- package/bin/utils/file-utils.js +52 -0
- package/bin/utils/log-utils.js +29 -0
- package/bin/utils/runner-utils.js +85 -0
- package/bin/utils/turbo-utils.js +139 -0
- package/dist/adapters/code-duplication/helpers/code-duplication-analysis-helper.d.ts +6 -0
- package/dist/adapters/code-duplication/helpers/code-duplication-analysis-helper.d.ts.map +1 -0
- package/dist/adapters/code-duplication/helpers/code-duplication-analysis-helper.js +240 -0
- package/dist/adapters/code-duplication/types/CodeDuplication.d.ts +60 -0
- package/dist/adapters/code-duplication/types/CodeDuplication.d.ts.map +1 -0
- package/dist/adapters/code-duplication/types/CodeDuplication.js +1 -0
- package/dist/adapters/eslint/rules/eslint-naming-conventions.d.ts.map +1 -1
- package/dist/adapters/eslint/rules/eslint-naming-conventions.js +1 -0
- package/dist/adapters/eslint/rules/eslint-prettier.js +1 -1
- package/dist/adapters/html-a11y-validation/helpers/html-a11y-tests-setup.d.ts +62 -0
- package/dist/adapters/html-a11y-validation/helpers/html-a11y-tests-setup.d.ts.map +1 -0
- package/dist/adapters/html-a11y-validation/helpers/html-a11y-tests-setup.js +73 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-tests-setup.d.ts +19 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-tests-setup.d.ts.map +1 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-tests-setup.js +32 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-validator.d.ts +4 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-validator.d.ts.map +1 -0
- package/dist/adapters/html-w3c-validation/helpers/html-w3c-validator.js +89 -0
- package/dist/adapters/html-w3c-validation/types/HtmlW3CValidator.d.ts +6 -0
- package/dist/adapters/html-w3c-validation/types/HtmlW3CValidator.d.ts.map +1 -0
- package/dist/adapters/html-w3c-validation/types/HtmlW3CValidator.js +1 -0
- package/dist/adapters/html-w3c-validation/types/globals/vnu-jar.d.ts +5 -0
- package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.d.ts +7 -0
- package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.js +191 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.d.ts +10 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.js +20 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.d.ts +5 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.js +35 -0
- package/dist/adapters/perf-budgets/types/PerfBudget.d.ts +22 -0
- package/dist/adapters/perf-budgets/types/PerfBudget.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/types/PerfBudget.js +1 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetAssets.d.ts +13 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetAssets.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetAssets.js +1 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetScore.d.ts +13 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetScore.d.ts.map +1 -0
- package/dist/adapters/perf-budgets/types/PerfBudgetScore.js +1 -0
- package/dist/adapters/tests-coverage/helpers/tests-coverage-analysis-helper.d.ts +4 -0
- package/dist/adapters/tests-coverage/helpers/tests-coverage-analysis-helper.d.ts.map +1 -0
- package/dist/adapters/tests-coverage/helpers/tests-coverage-analysis-helper.js +192 -0
- package/dist/adapters/tests-coverage/types/TestsCoverage.d.ts +36 -0
- package/dist/adapters/tests-coverage/types/TestsCoverage.d.ts.map +1 -0
- package/dist/adapters/tests-coverage/types/TestsCoverage.js +6 -0
- package/dist/adapters/types-coverage/helpers/types-coverage-analysis-helper.d.ts +4 -0
- package/dist/adapters/types-coverage/helpers/types-coverage-analysis-helper.d.ts.map +1 -0
- package/dist/adapters/types-coverage/helpers/types-coverage-analysis-helper.js +158 -0
- package/dist/adapters/types-coverage/types/TypesCoverage.d.ts +30 -0
- package/dist/adapters/types-coverage/types/TypesCoverage.d.ts.map +1 -0
- package/dist/adapters/types-coverage/types/TypesCoverage.js +1 -0
- package/dist/configs/architecture-analysis-config.d.ts +5 -0
- package/dist/configs/architecture-analysis-config.d.ts.map +1 -0
- package/dist/configs/{madge-config.js → architecture-analysis-config.js} +1 -1
- package/dist/configs/assets-budgets-config.d.ts +28 -0
- package/dist/configs/assets-budgets-config.d.ts.map +1 -0
- package/dist/configs/assets-budgets-config.js +45 -0
- package/dist/configs/bundle-analysis-config.d.ts +8 -0
- package/dist/configs/bundle-analysis-config.d.ts.map +1 -0
- package/dist/configs/bundle-analysis-config.js +7 -0
- package/dist/configs/code-duplication-config.d.ts +21 -0
- package/dist/configs/code-duplication-config.d.ts.map +1 -0
- package/dist/configs/code-duplication-config.js +21 -0
- package/dist/configs/{prettier-config.d.ts → code-formatter-config.d.ts} +1 -1
- package/dist/configs/code-formatter-config.d.ts.map +1 -0
- package/dist/configs/file-globs-config.d.ts +1 -4
- package/dist/configs/file-globs-config.d.ts.map +1 -1
- package/dist/configs/file-globs-config.js +1 -4
- package/dist/configs/naming-conventions-config.d.ts.map +1 -1
- package/dist/configs/naming-conventions-config.js +2 -0
- package/dist/configs/shared-exclusion-patterns.d.ts.map +1 -1
- package/dist/configs/shared-exclusion-patterns.js +3 -1
- package/dist/configs/tests-coverage-config.d.ts +12 -0
- package/dist/configs/tests-coverage-config.d.ts.map +1 -0
- package/dist/configs/tests-coverage-config.js +11 -0
- package/dist/configs/types-coverage-config.d.ts +19 -0
- package/dist/configs/types-coverage-config.d.ts.map +1 -0
- package/dist/configs/types-coverage-config.js +27 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -7
- package/dist/configs/jscpd-config.d.ts +0 -7
- package/dist/configs/jscpd-config.d.ts.map +0 -1
- package/dist/configs/jscpd-config.js +0 -7
- package/dist/configs/madge-config.d.ts +0 -5
- package/dist/configs/madge-config.d.ts.map +0 -1
- package/dist/configs/prettier-config.d.ts.map +0 -1
- /package/dist/configs/{prettier-config.js → code-formatter-config.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,54 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.9.0](https://github.com/ovh/manager/compare/@ovh-ux/manager-static-analysis-kit@0.8.0...@ovh-ux/manager-static-analysis-kit@0.9.0) (2025-09-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* md lint issues ([0d2fe8e](https://github.com/ovh/manager/commit/0d2fe8e49f3594f5abc9d8e6b306b0b71a065c6c)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* a11y and w3c unit tests expectations ([5a2d75d](https://github.com/ovh/manager/commit/5a2d75dba8a8877253871aa0a7c12dc2c79d1423)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
17
|
+
* code duplication analysis ([d431254](https://github.com/ovh/manager/commit/d4312543737541257185be6e54358dfb49285d51)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
18
|
+
* extend tests cases ([69ad98b](https://github.com/ovh/manager/commit/69ad98b3d02c615996f5c4ad9067a93a10b58ec4)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
19
|
+
* global unit tests coverage reports ([e11191a](https://github.com/ovh/manager/commit/e11191a24609d56e76fd3eacaeac79d4c3b1ab4a)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
20
|
+
* single html entry for all static and dynamic checks ([0556811](https://github.com/ovh/manager/commit/0556811b4f15ad3288f34b3ba8e468a1c9fee061)), closes [#MANAGER-18576](https://github.com/ovh/manager/issues/MANAGER-18576)
|
|
21
|
+
* typeScript types coverage analysis ([65f7d2f](https://github.com/ovh/manager/commit/65f7d2f22e4c68aa897d135e11642cd26073846b)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
22
|
+
* update documentation ([316add2](https://github.com/ovh/manager/commit/316add2055f4a27a3446d5361ee26e0baadbf2b8)), closes [#MANAGER-17958](https://github.com/ovh/manager/issues/MANAGER-17958)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# [0.8.0](https://github.com/ovh/manager/compare/@ovh-ux/manager-static-analysis-kit@0.7.1...@ovh-ux/manager-static-analysis-kit@0.8.0) (2025-09-11)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* adjust folder naming conventions rules ([fc7f608](https://github.com/ovh/manager/commit/fc7f6083038831902657e58f24792c7847f42d9c)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
34
|
+
* adjust thresholds ([bd950f1](https://github.com/ovh/manager/commit/bd950f1fb8e972475e9c0a26915470f4f2e29fd4)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
35
|
+
* ci lint issues ([c7b389e](https://github.com/ovh/manager/commit/c7b389e552cc1478998ad6dd24eb5c59328751da)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
36
|
+
* indentation issues ([f106dcf](https://github.com/ovh/manager/commit/f106dcf283eb453d97a5f575327f4bd7e8eb9ccb)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
37
|
+
* perf budgets readme doc indentation ([00660ba](https://github.com/ovh/manager/commit/00660ba9c418757dfc25dbb92be2af0a6e3dfea6)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
38
|
+
* readme doc indentation ([e54e5eb](https://github.com/ovh/manager/commit/e54e5eb4c0bda11f7dc1c9e41bde804664420939)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
39
|
+
* static kit integration status ([9a49e4f](https://github.com/ovh/manager/commit/9a49e4f992311de0ec2ac2876720dc46202ed118)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Features
|
|
43
|
+
|
|
44
|
+
* add new cli commands ([cfe81c2](https://github.com/ovh/manager/commit/cfe81c255885165fdfd12bb9ba6e0a81fc8f4d18)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
45
|
+
* add safety check and testing scenarios cases ([04d9b74](https://github.com/ovh/manager/commit/04d9b747f84e7475eee267f5311bebcdb1a6749a)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
46
|
+
* include shared in turbo build by default ([d006428](https://github.com/ovh/manager/commit/d0064281ef1a4c844fa574169fac17d2301e976b)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
47
|
+
* integrate and configure bundle analysis ([514d424](https://github.com/ovh/manager/commit/514d4247b6b6e4b37379e64e5260636b5d1c7c4d)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
48
|
+
* remove debug features ([7d1ac89](https://github.com/ovh/manager/commit/7d1ac892639831ace9a539d156775dbeeae19579)), closes [#MANAGER-19352](https://github.com/ovh/manager/issues/MANAGER-19352)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
6
54
|
## [0.7.1](https://github.com/ovh/manager/compare/@ovh-ux/manager-static-analysis-kit@0.7.0...@ovh-ux/manager-static-analysis-kit@0.7.1) (2025-08-14)
|
|
7
55
|
|
|
8
56
|
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 🧪static-analysis-kit
|
|
1
|
+
# 🧪 static-analysis-kit
|
|
2
2
|
|
|
3
3
|
A modular, extensible, and future-ready toolkit for defining, adapting, and sharing static analysis rules across projects in the `manager` monorepo.
|
|
4
4
|
|
|
@@ -6,103 +6,93 @@ A modular, extensible, and future-ready toolkit for defining, adapting, and shar
|
|
|
6
6
|
|
|
7
7
|
## 🚀 What Is It?
|
|
8
8
|
|
|
9
|
-
`static-analysis-kit` provides a unified platform for
|
|
9
|
+
`static-analysis-kit` provides a unified platform for **static & dynamic quality checks**: linting, duplication, type coverage, tests coverage, and performance budgets.
|
|
10
10
|
|
|
11
|
-
It
|
|
12
|
-
- ESLint (flat config)
|
|
13
|
-
- Madge (dependency graph & circular analysis)
|
|
14
|
-
- JSCPD (code duplication detection)
|
|
15
|
-
- Code Health Meter (complexity, Halstead, maintainability, SLOC, architecture)
|
|
11
|
+
It separates semantic rule definitions from tool-specific integrations using a clean adapter-based architecture.
|
|
16
12
|
|
|
17
13
|
---
|
|
18
14
|
|
|
19
|
-
##
|
|
15
|
+
## 📦 Tools Exposed by the Kit
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
- Avoid duplication of `.eslintrc`, `.prettierrc`, `.madgerc`, etc.
|
|
23
|
-
- Standardize how we measure code health and enforce architectural boundaries
|
|
24
|
-
- Enable safe and gradual migration to new tooling
|
|
17
|
+
The kit currently provides:
|
|
25
18
|
|
|
26
|
-
|
|
19
|
+
- **ESLint** (flat config, adapters for React, TS, a11y, imports, naming, Storybook, Tailwind, TanStack, Vitest)
|
|
20
|
+
- **Code Duplication Reports** (`manager-code-duplication`)
|
|
21
|
+
- **Performance Budgets** (`manager-perf-budgets`)
|
|
22
|
+
- **Tests Coverage Reports** (`manager-tests-coverage`)
|
|
23
|
+
- **Types Coverage Reports** (`manager-types-coverage`)
|
|
24
|
+
- **W3C & A11Y Unit Tests Matchers** (`expect(container).toBeAccessible()`, `await expect(html).toBeValidHtml()`)
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
Coming soon:
|
|
27
|
+
- **Madge** (dependency graph & circular analysis)
|
|
28
|
+
- **Code Health Meter** (complexity, Halstead, maintainability, SLOC)
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
│ └── adapters/
|
|
39
|
-
│ ├── eslint/ # ESLint flat config + rules
|
|
40
|
-
│ │ ├── config/
|
|
41
|
-
│ │ │ └── eslint.config.ts
|
|
42
|
-
│ │ └── rules/
|
|
43
|
-
│ ├── madge/ # Madge analysis adapter
|
|
44
|
-
│ ├── jscpd/ # JSCPD (duplication) adapter
|
|
45
|
-
│ ├── prettier/ # Optional: shared formatting config
|
|
46
|
-
│ └── code-health-meter/ # Halstead, MI, Cyclomatic, SLOC
|
|
47
|
-
```
|
|
30
|
+
> Each tool has its own README inside the kit with full usage & configuration details.
|
|
31
|
+
> See:
|
|
32
|
+
> - [Code Duplication](src/adapters/code-duplication/README.md)
|
|
33
|
+
> - [Performance Budgets](src/adapters/perf-budgets/README.md)
|
|
34
|
+
> - [Tests Coverage](src/adapters/tests-coverage/README.md)
|
|
35
|
+
> - [Types Coverage](src/adapters/types-coverage/README.md)
|
|
36
|
+
> - [HTML W3C Validation](src/adapters/html-w3c-validation/README.md)
|
|
37
|
+
> - [HTML Accessibility Matcher](src/adapters/html-a11y-validation/README.md)
|
|
48
38
|
|
|
49
39
|
---
|
|
50
40
|
|
|
51
|
-
##
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
// apps/zimbra/eslint.config.ts
|
|
55
|
-
import { eslintConfig } from '@ovh-ux/manager-static-analysis-kit';
|
|
56
|
-
|
|
57
|
-
export default [...eslintConfig];
|
|
58
|
-
```
|
|
41
|
+
## 🧑💻 Combined Quality Checks
|
|
59
42
|
|
|
60
|
-
|
|
43
|
+
The kit also provides a **single entrypoint** for running all static & dynamic quality checks in parallel:
|
|
61
44
|
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
```bash
|
|
46
|
+
# Run all quality checks
|
|
47
|
+
yarn manager-static-dynamic-quality-checks
|
|
65
48
|
|
|
66
|
-
|
|
49
|
+
# Run only tests-related checks
|
|
50
|
+
yarn manager-static-dynamic-quality-checks --tests
|
|
67
51
|
```
|
|
68
52
|
|
|
69
|
-
|
|
53
|
+
### Run by Type
|
|
70
54
|
|
|
71
|
-
|
|
55
|
+
You can also target subsets of checks:
|
|
72
56
|
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
57
|
+
```bash
|
|
58
|
+
yarn manager-code-duplication
|
|
59
|
+
yarn manager-perf-budgets
|
|
60
|
+
yarn manager-tests-coverage
|
|
61
|
+
yarn manager-types-coverage
|
|
62
|
+
```
|
|
77
63
|
|
|
78
64
|
---
|
|
79
65
|
|
|
80
|
-
##
|
|
81
|
-
|
|
82
|
-
This architecture is designed to easily accommodate:
|
|
83
|
-
|
|
84
|
-
- `biome/` adapter (Rust-based formatter/linter)
|
|
85
|
-
- `oxlint/` adapter (high-performance Rust linter)
|
|
86
|
-
- `depcruise/`, `pmd/`, `stylelint/` or internal tools
|
|
66
|
+
## 🧱 Structure Overview
|
|
87
67
|
|
|
88
|
-
|
|
68
|
+
```
|
|
69
|
+
static-analysis-kit/
|
|
70
|
+
├── src/
|
|
71
|
+
│ ├── code-analysis.ts # Central entry point (exports adapters)
|
|
72
|
+
│ ├── configs/ # Tool-agnostic semantic rule definitions
|
|
73
|
+
│ └── adapters/ # Tool integrations
|
|
74
|
+
│ ├── eslint/
|
|
75
|
+
│ ├── code-duplication/ # Duplication reports
|
|
76
|
+
│ ├── perf-budgets/ # Performance analyzer
|
|
77
|
+
│ ├── tests-coverage/ # Test coverage reports
|
|
78
|
+
│ ├── types-coverage/ # TS coverage reports
|
|
79
|
+
│ ├── madge/ # Coming soon
|
|
80
|
+
│ └── code-health-meter/ # Coming soon
|
|
81
|
+
```
|
|
89
82
|
|
|
90
83
|
---
|
|
91
84
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
If you’re adding a new rule or adapter:
|
|
85
|
+
## 🧠 Design Principles
|
|
95
86
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
5. Document your addition.
|
|
87
|
+
- **Composable**: Adapters are modular, rules are grouped by category.
|
|
88
|
+
- **Decoupled**: Semantic configs live separately from tool logic.
|
|
89
|
+
- **Pluggable**: Easy to add new tools (e.g., Biome, Oxlint).
|
|
90
|
+
- **CI/CD Ready**: All tools produce JSON + HTML reports for pipelines.
|
|
101
91
|
|
|
102
92
|
---
|
|
103
93
|
|
|
104
94
|
## 📬 Feedback Welcome
|
|
105
95
|
|
|
106
|
-
The goal is to create a robust, composable, and organization-wide standard for static analysis.
|
|
96
|
+
The goal is to create a **robust, composable, and organization-wide standard** for static analysis and dynamic quality checks.
|
|
107
97
|
|
|
108
|
-
|
|
98
|
+
Suggestions & contributions are welcome.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
|
|
4
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
|
|
6
|
+
export const rootDir = path.resolve(__dirname, '../../..');
|
|
7
|
+
export const outputRootDir = path.resolve(__dirname, '../../../../static-dynamic-quality-reports');
|
|
8
|
+
|
|
9
|
+
export const appsDir = path.join(rootDir, 'manager/apps');
|
|
10
|
+
|
|
11
|
+
export const bundleAnalyzerBinPath = path.resolve(__dirname, '../node_modules/.bin/analyze');
|
|
12
|
+
export const perfBudgetsReportDirName = 'perf-budgets-reports';
|
|
13
|
+
export const perfBudgetCombinedJsonReportName = 'perf-budgets-combined-report.json';
|
|
14
|
+
export const perfBudgetCombinedHtmlReportName = 'perf-budgets-combined-report.html';
|
|
15
|
+
|
|
16
|
+
export const jscpdBinPath = path.resolve(__dirname, '../node_modules/.bin/jscpd');
|
|
17
|
+
export const codeDupReportsRootDirName = 'code-duplication-reports';
|
|
18
|
+
export const codeDupCombinedJsonReportName = 'code-duplication-combined-report.json';
|
|
19
|
+
export const codeDupCombinedHtmlReportName = 'code-duplication-combined-report.html';
|
|
20
|
+
|
|
21
|
+
export const testsCoverageReportsRootDirName = 'tests-coverage-reports';
|
|
22
|
+
export const testsCoverageCombinedJsonReportName = 'tests-coverage-combined-report.json';
|
|
23
|
+
export const testsCoverageCombinedHtmlReportName = 'tests-coverage-combined-report.html';
|
|
24
|
+
|
|
25
|
+
export const tsTypesCoverageBin = path.resolve(
|
|
26
|
+
__dirname,
|
|
27
|
+
'../node_modules/.bin/typescript-coverage-report',
|
|
28
|
+
);
|
|
29
|
+
export const typesCoverageReportsRootDirName = 'types-coverage-reports';
|
|
30
|
+
export const typesCoverageCombinedJsonReportName = 'types-coverage-combined-report.json';
|
|
31
|
+
export const typesCoverageCombinedHtmlReportName = 'types-coverage-combined-report.html';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
collectCodeDuplication,
|
|
8
|
+
generateCodeDuplicationHtml,
|
|
9
|
+
} from '../dist/adapters/code-duplication/helpers/code-duplication-analysis-helper.js';
|
|
10
|
+
import {
|
|
11
|
+
appsDir,
|
|
12
|
+
codeDupCombinedHtmlReportName,
|
|
13
|
+
codeDupCombinedJsonReportName,
|
|
14
|
+
codeDupReportsRootDirName,
|
|
15
|
+
jscpdBinPath,
|
|
16
|
+
outputRootDir,
|
|
17
|
+
} from './cli-path-config.js';
|
|
18
|
+
import { buildCodeDuplicationArgs, parseCliTargets } from './utils/args-parse-utils.js';
|
|
19
|
+
import { logError, logInfo, logWarn } from './utils/log-utils.js';
|
|
20
|
+
import { ensureBinExists, runAppsAnalysis, runCommand } from './utils/runner-utils.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run `jscpd` code duplication analysis for a single app.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} appDir - Absolute path to the app’s root directory.
|
|
26
|
+
* @param {string} appShortName - Shortened app name (from package.json or folder).
|
|
27
|
+
* @returns {boolean} True if analysis completed successfully, false otherwise.
|
|
28
|
+
*/
|
|
29
|
+
function runAppCodeDuplication(appDir, appShortName) {
|
|
30
|
+
try {
|
|
31
|
+
const absoluteOutputDir = path.join(outputRootDir, codeDupReportsRootDirName, appShortName);
|
|
32
|
+
fs.mkdirSync(absoluteOutputDir, { recursive: true });
|
|
33
|
+
|
|
34
|
+
// Relative output path from the app dir (keeps paths clean inside HTML reports)
|
|
35
|
+
const relativeOutputDir = path.relative(appDir, absoluteOutputDir);
|
|
36
|
+
|
|
37
|
+
logInfo(`Running jscpd for ${appShortName} → ${absoluteOutputDir}`);
|
|
38
|
+
|
|
39
|
+
const args = [...buildCodeDuplicationArgs(relativeOutputDir), appDir];
|
|
40
|
+
const ok = runCommand(jscpdBinPath, args, appDir);
|
|
41
|
+
|
|
42
|
+
// Validate expected reports
|
|
43
|
+
const jsonReport = path.join(absoluteOutputDir, 'jscpd-report.json');
|
|
44
|
+
const htmlReport = path.join(absoluteOutputDir, 'html', 'index.html');
|
|
45
|
+
|
|
46
|
+
if (!fs.existsSync(jsonReport)) {
|
|
47
|
+
logWarn(`⚠️ Missing jscpd-report.json at ${jsonReport}`);
|
|
48
|
+
}
|
|
49
|
+
if (!fs.existsSync(htmlReport)) {
|
|
50
|
+
logWarn(`⚠️ Missing html/index.html at ${htmlReport}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return ok;
|
|
54
|
+
} catch (err) {
|
|
55
|
+
logError(`Fatal error: ${err.stack || err.message}`);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Main CLI entrypoint for code duplication analysis.
|
|
62
|
+
*
|
|
63
|
+
* - Ensures the `jscpd` binary is available
|
|
64
|
+
* - Resolves target app folders from CLI args
|
|
65
|
+
* - Runs per-app analysis via {@link runAppCodeDuplication}
|
|
66
|
+
* - Generates combined JSON + HTML reports across all apps
|
|
67
|
+
*
|
|
68
|
+
* Exits process with code `1` if no apps were analyzed successfully
|
|
69
|
+
* or if a fatal error occurred.
|
|
70
|
+
*/
|
|
71
|
+
function main() {
|
|
72
|
+
try {
|
|
73
|
+
ensureBinExists(jscpdBinPath, 'jscpd');
|
|
74
|
+
|
|
75
|
+
const { appFolders } = parseCliTargets(appsDir);
|
|
76
|
+
|
|
77
|
+
runAppsAnalysis({
|
|
78
|
+
appsDir,
|
|
79
|
+
appFolders,
|
|
80
|
+
requireReact: true,
|
|
81
|
+
binaryLabel: 'Code duplication',
|
|
82
|
+
appRunner: runAppCodeDuplication,
|
|
83
|
+
reportsRootDirName: codeDupReportsRootDirName,
|
|
84
|
+
combinedJson: codeDupCombinedJsonReportName,
|
|
85
|
+
combinedHtml: codeDupCombinedHtmlReportName,
|
|
86
|
+
collectFn: collectCodeDuplication,
|
|
87
|
+
generateHtmlFn: generateCodeDuplicationHtml,
|
|
88
|
+
outputRootDir,
|
|
89
|
+
});
|
|
90
|
+
} catch (err) {
|
|
91
|
+
logError(`Fatal error: ${err.stack || err.message}`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
import { logError, logInfo } from './utils/log-utils.js';
|
|
5
|
+
|
|
6
|
+
// Define the set of validation test cases for code-duplication CLI
|
|
7
|
+
const cases = [
|
|
8
|
+
// Debug only — very slow, runs across all apps
|
|
9
|
+
// { name: 'Auto-discovery (all apps)', cmd: 'yarn manager-code-duplication', expect: 0 },
|
|
10
|
+
|
|
11
|
+
{ name: 'Single app (zimbra)', cmd: 'yarn manager-code-duplication --app zimbra', expect: 0 },
|
|
12
|
+
{
|
|
13
|
+
name: 'Multiple apps (container,zimbra,web-ongoing-operations,key-management-service)',
|
|
14
|
+
cmd: 'yarn manager-code-duplication --apps container,zimbra,web-ongoing-operations,key-management-service',
|
|
15
|
+
expect: 0,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Single package (container)',
|
|
19
|
+
cmd: 'yarn manager-code-duplication --package @ovh-ux/manager-container-app',
|
|
20
|
+
expect: 0,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Multiple packages (zimbra,pci-workflow)',
|
|
24
|
+
cmd: 'yarn manager-code-duplication --packages @ovh-ux/manager-zimbra-app,@ovh-ux/manager-pci-workflow-app',
|
|
25
|
+
expect: 0,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Mixed valid+invalid apps',
|
|
29
|
+
cmd: 'yarn manager-code-duplication --apps zimbra,unknown-app,container',
|
|
30
|
+
expect: 0,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Mixed valid+invalid packages',
|
|
34
|
+
cmd: 'yarn manager-code-duplication --packages @ovh-ux/manager-zimbra-app,@ovh-ux/manager-ghost-app',
|
|
35
|
+
expect: 0,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'All invalid apps',
|
|
39
|
+
cmd: 'yarn manager-code-duplication --apps doesnotexist1,doesnotexist2',
|
|
40
|
+
expect: 1,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'All invalid packages',
|
|
44
|
+
cmd: 'yarn manager-code-duplication --packages @ovh-ux/manager-ghost-app,@ovh-ux/manager-missing-app',
|
|
45
|
+
expect: 1,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
let failed = 0;
|
|
50
|
+
|
|
51
|
+
for (const test of cases) {
|
|
52
|
+
logInfo(`\n🔎 Running: ${test.name}`);
|
|
53
|
+
const [bin, ...args] = test.cmd.split(' ');
|
|
54
|
+
const result = spawnSync(bin, args, { stdio: 'inherit', shell: true });
|
|
55
|
+
|
|
56
|
+
if (result.status !== test.expect) {
|
|
57
|
+
logError(`❌ ${test.name} failed (expected exit ${test.expect}, got ${result.status})`);
|
|
58
|
+
failed++;
|
|
59
|
+
} else {
|
|
60
|
+
logInfo(`✅ ${test.name} passed`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (failed > 0) {
|
|
65
|
+
logError(`\n❌ ${failed} test(s) failed.`);
|
|
66
|
+
} else {
|
|
67
|
+
logInfo('\n🎉 All code-duplication-tests CLI validation tests passed!');
|
|
68
|
+
}
|
package/bin/lint-cli.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { spawn } from 'child_process';
|
|
3
|
-
import {
|
|
4
|
-
import { dirname,
|
|
5
|
-
import { cwd } from 'process';
|
|
6
|
-
import {
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import process, { cwd } from 'node:process';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
|
|
8
|
+
import { logError, logInfo } from './utils/log-utils.js';
|
|
7
9
|
|
|
8
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const userCwd = cwd();
|
|
11
12
|
const eslintBin = resolve(__dirname, '../node_modules/.bin/eslint');
|
|
@@ -13,11 +14,13 @@ const eslintBin = resolve(__dirname, '../node_modules/.bin/eslint');
|
|
|
13
14
|
const args = process.argv.slice(2);
|
|
14
15
|
const hasExplicitConfigArg = args.includes('--config');
|
|
15
16
|
const localConfigPath = join(userCwd, 'eslint.config.ts');
|
|
16
|
-
const sharedDefaultPath = resolve(
|
|
17
|
+
const sharedDefaultPath = resolve(
|
|
18
|
+
__dirname,
|
|
19
|
+
'../dist/adapters/eslint/config/eslint-shared-config.js',
|
|
20
|
+
);
|
|
17
21
|
const hasLocalConfig = existsSync(localConfigPath);
|
|
18
22
|
|
|
19
23
|
// Determine effective config path
|
|
20
|
-
// eslint-disable-next-line no-nested-ternary
|
|
21
24
|
const configPath = hasExplicitConfigArg
|
|
22
25
|
? args[args.indexOf('--config') + 1]
|
|
23
26
|
: hasLocalConfig
|
|
@@ -34,8 +37,8 @@ function runLint(command, args, cwd) {
|
|
|
34
37
|
});
|
|
35
38
|
|
|
36
39
|
child.on('error', (err) => {
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
logError('[manager-lint] Failed to run ESLint');
|
|
41
|
+
logError(err);
|
|
39
42
|
reject(1);
|
|
40
43
|
});
|
|
41
44
|
|
|
@@ -52,20 +55,19 @@ function runLint(command, args, cwd) {
|
|
|
52
55
|
try {
|
|
53
56
|
const mod = await import(url);
|
|
54
57
|
const configContent = mod.default ?? mod;
|
|
55
|
-
|
|
58
|
+
logInfo('[manager-lint] Loaded ESLint config from:', configPath);
|
|
56
59
|
console.dir(configContent, { depth: null });
|
|
57
60
|
} catch (err) {
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
logError(`[manager-lint] Failed to load config at ${configPath}`);
|
|
62
|
+
logError(err);
|
|
60
63
|
process.exit(1);
|
|
61
64
|
}
|
|
62
65
|
process.exit(0);
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
// Construct full args
|
|
66
|
-
const fullArgs =
|
|
67
|
-
? args
|
|
68
|
-
: ['--config', sharedDefaultPath, ...args];
|
|
69
|
+
const fullArgs =
|
|
70
|
+
hasExplicitConfigArg || hasLocalConfig ? args : ['--config', sharedDefaultPath, ...args];
|
|
69
71
|
|
|
70
72
|
// Run ESLint using tsx and wait for completion
|
|
71
73
|
const exitCode = await runLint('tsx', [eslintBin, ...fullArgs], userCwd);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
collectPerfBudgets,
|
|
8
|
+
generatePerfBudgetsHtml,
|
|
9
|
+
} from '../dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.js';
|
|
10
|
+
import { bundleAnalysisConfig } from '../dist/configs/bundle-analysis-config.js';
|
|
11
|
+
import {
|
|
12
|
+
appsDir,
|
|
13
|
+
bundleAnalyzerBinPath,
|
|
14
|
+
outputRootDir,
|
|
15
|
+
perfBudgetCombinedHtmlReportName,
|
|
16
|
+
perfBudgetCombinedJsonReportName,
|
|
17
|
+
perfBudgetsReportDirName,
|
|
18
|
+
rootDir,
|
|
19
|
+
} from './cli-path-config.js';
|
|
20
|
+
import { parseCliTargets } from './utils/args-parse-utils.js';
|
|
21
|
+
import { logError, logInfo, logWarn } from './utils/log-utils.js';
|
|
22
|
+
import { ensureBinExists, runAppsAnalysis, runCommand } from './utils/runner-utils.js';
|
|
23
|
+
import { resolveTurboFilters, runTurboBuild } from './utils/turbo-utils.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Run vite-bundle-analyzer for a given mode (html or json).
|
|
27
|
+
*
|
|
28
|
+
* @param {string} appDir - Absolute app directory
|
|
29
|
+
* @param {string} appShortName - Shortened app name
|
|
30
|
+
* @param {"static"|"json"} mode - Analyzer mode
|
|
31
|
+
* @returns {boolean} True if analyzer produced output, false otherwise
|
|
32
|
+
*/
|
|
33
|
+
function runAppBundleAnalyzer(appDir, appShortName, mode) {
|
|
34
|
+
const reportFile = `${bundleAnalysisConfig?.reportFile || 'bundle-report'}${
|
|
35
|
+
mode === 'json' ? '.json' : '.html'
|
|
36
|
+
}`;
|
|
37
|
+
const outputDir = path.join(outputRootDir, perfBudgetsReportDirName, appShortName);
|
|
38
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
39
|
+
|
|
40
|
+
logInfo(`Running bundle analyzer (${mode}) for ${appShortName} → ${outputDir}`);
|
|
41
|
+
|
|
42
|
+
const analyzerArgs = [
|
|
43
|
+
'--mode',
|
|
44
|
+
mode,
|
|
45
|
+
'--no-open',
|
|
46
|
+
'--filename',
|
|
47
|
+
bundleAnalysisConfig?.reportFile || 'bundle-report',
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const ok = runCommand(bundleAnalyzerBinPath, analyzerArgs, appDir);
|
|
51
|
+
if (!ok) {
|
|
52
|
+
logError(`❌ Analyzer (${mode}) failed for ${appShortName}`);
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const distReport = path.join(appDir, 'dist', reportFile);
|
|
57
|
+
const targetReport = path.join(outputDir, reportFile);
|
|
58
|
+
|
|
59
|
+
if (fs.existsSync(distReport)) {
|
|
60
|
+
fs.copyFileSync(distReport, targetReport);
|
|
61
|
+
logInfo(`✅ ${mode.toUpperCase()} report copied to ${targetReport}`);
|
|
62
|
+
return true;
|
|
63
|
+
} else {
|
|
64
|
+
logWarn(`⚠️ Expected ${mode} report not found at ${distReport}`);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Run perf budgets analysis for one app (both static + json).
|
|
71
|
+
*
|
|
72
|
+
* @param {string} appDir
|
|
73
|
+
* @param {string} appShortName
|
|
74
|
+
* @returns {boolean} True if at least one report succeeded
|
|
75
|
+
*/
|
|
76
|
+
function runAppPerfBudgets(appDir, appShortName) {
|
|
77
|
+
const okStatic = runAppBundleAnalyzer(appDir, appShortName, 'static');
|
|
78
|
+
const okJson = runAppBundleAnalyzer(appDir, appShortName, 'json');
|
|
79
|
+
return okStatic || okJson;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Main CLI entrypoint for perf budgets analysis.
|
|
84
|
+
*
|
|
85
|
+
* - Ensures analyzer binary is available
|
|
86
|
+
* - Runs a turbo build for the selected apps
|
|
87
|
+
* - Executes analyzer per app via {@link runAppPerfBudgets}
|
|
88
|
+
* - Generates combined JSON + HTML reports
|
|
89
|
+
*/
|
|
90
|
+
function main() {
|
|
91
|
+
try {
|
|
92
|
+
ensureBinExists(bundleAnalyzerBinPath, 'vite-bundle-analyzer');
|
|
93
|
+
|
|
94
|
+
const { appFolders, packageNames } = parseCliTargets(appsDir);
|
|
95
|
+
const turboFilters = resolveTurboFilters({ appsDir, appFolders, packageNames });
|
|
96
|
+
|
|
97
|
+
// Step 1: build
|
|
98
|
+
runTurboBuild(rootDir, turboFilters);
|
|
99
|
+
|
|
100
|
+
// Step 2: analyze apps + combined
|
|
101
|
+
runAppsAnalysis({
|
|
102
|
+
appsDir,
|
|
103
|
+
appFolders,
|
|
104
|
+
requireReact: false,
|
|
105
|
+
binaryLabel: 'Perf budgets',
|
|
106
|
+
appRunner: runAppPerfBudgets,
|
|
107
|
+
reportsRootDirName: perfBudgetsReportDirName,
|
|
108
|
+
combinedJson: perfBudgetCombinedJsonReportName,
|
|
109
|
+
combinedHtml: perfBudgetCombinedHtmlReportName,
|
|
110
|
+
collectFn: collectPerfBudgets,
|
|
111
|
+
generateHtmlFn: generatePerfBudgetsHtml,
|
|
112
|
+
outputRootDir,
|
|
113
|
+
});
|
|
114
|
+
} catch (err) {
|
|
115
|
+
logError(`Fatal error: ${err.stack || err.message}`);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
main();
|