@sun-asterisk/sunlint 1.3.34 → 1.3.35
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/core/architecture-integration.js +16 -7
- package/core/auto-performance-manager.js +1 -1
- package/core/cli-action-handler.js +92 -2
- package/core/cli-program.js +96 -138
- package/core/file-targeting-service.js +62 -4
- package/core/git-utils.js +19 -12
- package/core/github-annotate-service.js +326 -11
- package/core/html-report-generator.js +326 -731
- package/core/impact-integration.js +433 -0
- package/core/output-service.js +293 -21
- package/core/scoring-service.js +3 -2
- package/engines/arch-detect/core/analyzer.js +413 -0
- package/engines/arch-detect/core/index.js +22 -0
- package/engines/arch-detect/engine/hybrid-detector.js +176 -0
- package/engines/arch-detect/engine/index.js +24 -0
- package/engines/arch-detect/engine/rule-executor.js +228 -0
- package/engines/arch-detect/engine/score-calculator.js +214 -0
- package/engines/arch-detect/engine/violation-detector.js +616 -0
- package/engines/arch-detect/index.js +50 -0
- package/engines/arch-detect/rules/base-rule.js +187 -0
- package/engines/arch-detect/rules/index.js +35 -0
- package/engines/arch-detect/rules/layered/index.js +28 -0
- package/engines/arch-detect/rules/layered/l001-presentation-layer.js +237 -0
- package/engines/arch-detect/rules/layered/l002-business-layer.js +215 -0
- package/engines/arch-detect/rules/layered/l003-data-layer.js +229 -0
- package/engines/arch-detect/rules/layered/l004-model-layer.js +204 -0
- package/engines/arch-detect/rules/layered/l005-layer-separation.js +215 -0
- package/engines/arch-detect/rules/layered/l006-dependency-direction.js +221 -0
- package/engines/arch-detect/rules/layered/layered-rules-collection.js +445 -0
- package/engines/arch-detect/rules/modular/index.js +27 -0
- package/engines/arch-detect/rules/modular/m001-feature-modules.js +238 -0
- package/engines/arch-detect/rules/modular/m002-core-module.js +169 -0
- package/engines/arch-detect/rules/modular/m003-module-declaration.js +186 -0
- package/engines/arch-detect/rules/modular/m004-public-api.js +171 -0
- package/engines/arch-detect/rules/modular/m005-no-deep-imports.js +220 -0
- package/engines/arch-detect/rules/modular/modular-rules-collection.js +357 -0
- package/engines/arch-detect/rules/presentation/index.js +27 -0
- package/engines/arch-detect/rules/presentation/pr001-view-layer.js +221 -0
- package/engines/arch-detect/rules/presentation/pr002-presentation-logic.js +192 -0
- package/engines/arch-detect/rules/presentation/pr004-data-binding.js +187 -0
- package/engines/arch-detect/rules/presentation/pr006-router-layer.js +185 -0
- package/engines/arch-detect/rules/presentation/pr007-interactor-layer.js +181 -0
- package/engines/arch-detect/rules/presentation/presentation-rules-collection.js +507 -0
- package/engines/arch-detect/rules/project-scanner/index.js +31 -0
- package/engines/arch-detect/rules/project-scanner/ps001-project-root.js +213 -0
- package/engines/arch-detect/rules/project-scanner/ps002-language-detection.js +192 -0
- package/engines/arch-detect/rules/project-scanner/ps003-framework-detection.js +339 -0
- package/engines/arch-detect/rules/project-scanner/ps004-build-system.js +171 -0
- package/engines/arch-detect/rules/project-scanner/ps005-source-directory.js +163 -0
- package/engines/arch-detect/rules/project-scanner/ps006-test-directory.js +184 -0
- package/engines/arch-detect/rules/project-scanner/ps007-documentation.js +149 -0
- package/engines/arch-detect/rules/project-scanner/ps008-cicd-detection.js +163 -0
- package/engines/arch-detect/rules/project-scanner/ps009-code-quality.js +152 -0
- package/engines/arch-detect/rules/project-scanner/ps010-statistics.js +180 -0
- package/engines/arch-detect/rules/rule-registry.js +111 -0
- package/engines/arch-detect/types/context.types.js +60 -0
- package/engines/arch-detect/types/enums.js +161 -0
- package/engines/arch-detect/types/index.js +25 -0
- package/engines/arch-detect/types/result.types.js +7 -0
- package/engines/arch-detect/types/rule.types.js +7 -0
- package/engines/arch-detect/utils/file-scanner.js +411 -0
- package/engines/arch-detect/utils/index.js +23 -0
- package/engines/arch-detect/utils/pattern-matcher.js +328 -0
- package/engines/impact/cli.js +106 -0
- package/engines/impact/config/default-config.js +54 -0
- package/engines/impact/core/change-detector.js +258 -0
- package/engines/impact/core/detectors/database-detector.js +1317 -0
- package/engines/impact/core/detectors/endpoint-detector.js +55 -0
- package/engines/impact/core/impact-analyzer.js +124 -0
- package/engines/impact/core/report-generator.js +462 -0
- package/engines/impact/core/utils/ast-parser.js +241 -0
- package/engines/impact/core/utils/dependency-graph.js +159 -0
- package/engines/impact/core/utils/file-utils.js +116 -0
- package/engines/impact/core/utils/git-utils.js +203 -0
- package/engines/impact/core/utils/logger.js +13 -0
- package/engines/impact/core/utils/method-call-graph.js +1192 -0
- package/engines/impact/index.js +135 -0
- package/engines/impact/package.json +29 -0
- package/package.json +18 -43
- package/scripts/build-release.sh +0 -0
- package/scripts/copy-impact-analyzer.js +135 -0
- package/scripts/install.sh +0 -0
- package/scripts/manual-release.sh +0 -0
- package/scripts/pre-release-test.sh +0 -0
- package/scripts/prepare-release.sh +0 -0
- package/scripts/quick-performance-test.js +0 -0
- package/scripts/setup-github-registry.sh +0 -0
- package/scripts/trigger-release.sh +0 -0
- package/scripts/verify-install.sh +0 -0
- package/templates/combined-report.html +1418 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Impact Analyzer - Main Entry Point
|
|
5
|
+
* Orchestrates the entire impact analysis workflow
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { CLI } from './cli.js';
|
|
9
|
+
import { loadConfig } from './config/default-config.js';
|
|
10
|
+
import { ChangeDetector } from './core/change-detector.js';
|
|
11
|
+
import { ImpactAnalyzer } from './core/impact-analyzer.js';
|
|
12
|
+
import { ReportGenerator } from './core/report-generator.js';
|
|
13
|
+
import { GitUtils } from './core/utils/git-utils.js';
|
|
14
|
+
import fs from 'fs';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
|
|
17
|
+
async function main() {
|
|
18
|
+
const cli = new CLI(process.argv);
|
|
19
|
+
|
|
20
|
+
// Show help if requested
|
|
21
|
+
if (cli.hasArg('help') || cli.hasArg('h')) {
|
|
22
|
+
cli.showHelp();
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Load configuration
|
|
27
|
+
const config = loadConfig(cli);
|
|
28
|
+
const absoluteSourceDir = path.resolve(config.sourceDir);
|
|
29
|
+
|
|
30
|
+
console.log('🚀 Starting Impact Analysis...\n');
|
|
31
|
+
console.log('Configuration:');
|
|
32
|
+
console.log(` Source Dir: ${config.sourceDir}`);
|
|
33
|
+
console.log(` Absolute Path: ${absoluteSourceDir}`);
|
|
34
|
+
console.log(` Base Ref: ${config.baseRef}`);
|
|
35
|
+
console.log(` Head Ref: ${config.headRef}`);
|
|
36
|
+
console.log(` Exclude: ${config.excludePaths.join(', ')}`);
|
|
37
|
+
console.log('');
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// ============================================
|
|
41
|
+
// Validation
|
|
42
|
+
// ============================================
|
|
43
|
+
|
|
44
|
+
// Check if source directory exists
|
|
45
|
+
if (! fs.existsSync(absoluteSourceDir)) {
|
|
46
|
+
throw new Error(`Source directory does not exist: ${absoluteSourceDir}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Check if it's a git repository
|
|
50
|
+
if (!GitUtils.isGitRepo(absoluteSourceDir)) {
|
|
51
|
+
throw new Error(`Source directory is not a git repository: ${absoluteSourceDir}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if refs exist
|
|
55
|
+
if (!GitUtils.refExists(config.baseRef, absoluteSourceDir)) {
|
|
56
|
+
throw new Error(`Base ref does not exist: ${config.baseRef}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log('✓ Validation passed\n');
|
|
60
|
+
|
|
61
|
+
// ============================================
|
|
62
|
+
// Step 1: Detect Changes
|
|
63
|
+
// ============================================
|
|
64
|
+
console.log('📝 Step 1: Detecting changes...');
|
|
65
|
+
const detector = new ChangeDetector(config);
|
|
66
|
+
|
|
67
|
+
const changedFiles = detector.detectChangedFiles();
|
|
68
|
+
console.log(` ✓ Found ${changedFiles.length} changed files`);
|
|
69
|
+
|
|
70
|
+
const changedSymbols = detector.detectChangedSymbols(changedFiles);
|
|
71
|
+
console.log(` ✓ Found ${changedSymbols.length} changed symbols\n`);
|
|
72
|
+
|
|
73
|
+
const changes = {
|
|
74
|
+
changedFiles,
|
|
75
|
+
changedSymbols,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// ============================================
|
|
79
|
+
// Step 2: Analyze Impact
|
|
80
|
+
// ============================================
|
|
81
|
+
console.log('🔍 Step 2: Analyzing impact...');
|
|
82
|
+
const analyzer = new ImpactAnalyzer(config);
|
|
83
|
+
|
|
84
|
+
// Initialize method-level call graph for precise tracking
|
|
85
|
+
await analyzer.initializeMethodCallGraph();
|
|
86
|
+
|
|
87
|
+
const impact = await analyzer.analyzeImpact(changes);
|
|
88
|
+
console.log(` ✓ Impact score: ${impact.impactScore}`);
|
|
89
|
+
console.log(` ✓ Severity: ${impact.severity.toUpperCase()}\n`);
|
|
90
|
+
|
|
91
|
+
// ============================================
|
|
92
|
+
// Step 3: Generate Reports
|
|
93
|
+
// ============================================
|
|
94
|
+
console.log('📄 Step 3: Generating reports...\n');
|
|
95
|
+
const reporter = new ReportGenerator();
|
|
96
|
+
|
|
97
|
+
// Console report
|
|
98
|
+
reporter.generateConsoleReport(changes, impact);
|
|
99
|
+
|
|
100
|
+
// Markdown report
|
|
101
|
+
const markdownReport = reporter.generateMarkdownReport(changes, impact);
|
|
102
|
+
|
|
103
|
+
// Save to file
|
|
104
|
+
const outputFile = cli.getArg('output', 'impact-report.md');
|
|
105
|
+
fs.writeFileSync(outputFile, markdownReport);
|
|
106
|
+
console.log(`✅ Report saved to: ${outputFile}\n`);
|
|
107
|
+
|
|
108
|
+
// JSON output (optional)
|
|
109
|
+
if (cli.hasArg('json')) {
|
|
110
|
+
const jsonOutput = cli.getArg('json');
|
|
111
|
+
const jsonReport = reporter.generateJSONReport(changes, impact);
|
|
112
|
+
fs.writeFileSync(jsonOutput, JSON.stringify(jsonReport, null, 2));
|
|
113
|
+
console.log(`✅ JSON report saved to: ${jsonOutput}\n`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Exit with code based on severity
|
|
117
|
+
if (impact.severity === 'critical' && ! cli.hasArg('no-fail')) {
|
|
118
|
+
console.log('⚠️ Critical impact detected - exiting with error code');
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log('✨ Analysis completed successfully!\n');
|
|
123
|
+
process.exit(0);
|
|
124
|
+
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error('❌ Error during analysis:', error.message);
|
|
127
|
+
if (cli.hasArg('verbose')) {
|
|
128
|
+
console.error(error.stack);
|
|
129
|
+
}
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Run if executed directly
|
|
135
|
+
main();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sunlint/impact-analyzer",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "Automated impact analysis for TypeScript/JavaScript projects (internal - bundled into sunlint)",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"impact-analyzer": "./index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "echo 'No build required (pure Node.js)'",
|
|
13
|
+
"test": "echo 'No tests yet'",
|
|
14
|
+
"analyze": "node index.js"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"impact-analysis",
|
|
18
|
+
"code-analysis",
|
|
19
|
+
"ci-cd"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@babel/parser": "^7.23.0",
|
|
25
|
+
"@babel/traverse": "^7.23.0",
|
|
26
|
+
"glob": "^10.3.0",
|
|
27
|
+
"ts-morph": "^27.0.2"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sun-asterisk/sunlint",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.35",
|
|
4
4
|
"description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,46 +15,6 @@
|
|
|
15
15
|
"registry": "https://registry.npmjs.org",
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"test": "node examples/run-tests.js",
|
|
20
|
-
"test:examples": "node examples/integration-tests/examples-integration-test.js",
|
|
21
|
-
"test:architecture": "node examples/integration-tests/core-architecture-test.js",
|
|
22
|
-
"test:integration": "echo 'Temporarily disabled - config extension issue'",
|
|
23
|
-
"test:realworld": "node examples/integration-tests/realworld-integration-test.js",
|
|
24
|
-
"test:cli": "node examples/integration-tests/direct-cli-test.js",
|
|
25
|
-
"test:performance": "node test/performance-test.js",
|
|
26
|
-
"test:c019": "node cli.js --rule=C019 --input=examples/test-fixtures --format=eslint",
|
|
27
|
-
"test:c006": "node cli.js --rule=C006 --input=examples/test-fixtures --format=eslint",
|
|
28
|
-
"test:c029": "node cli.js --rule=C029 --input=examples/test-fixtures --format=eslint",
|
|
29
|
-
"test:multi": "node cli.js --rules=C019,C006,C029 --input=examples/test-fixtures --format=eslint",
|
|
30
|
-
"test:all": "node cli.js --all --input=examples/test-fixtures --format=eslint",
|
|
31
|
-
"test:quality": "node cli.js --category=quality --input=examples/test-fixtures --format=eslint",
|
|
32
|
-
"test:security": "node cli.js --category=security --input=examples/test-fixtures --format=eslint",
|
|
33
|
-
"demo": "./demo.sh",
|
|
34
|
-
"demo:single": "node cli.js --rule=C019 --input=examples/test-fixtures/typescript --format=eslint",
|
|
35
|
-
"demo:multi": "node cli.js --rules=C019,C006 --input=test/fixtures --format=summary",
|
|
36
|
-
"demo:quality": "node cli.js --quality --input=test/fixtures --format=summary",
|
|
37
|
-
"demo:security": "node cli.js --security --input=test/fixtures --format=summary",
|
|
38
|
-
"demo:all": "node cli.js --all --input=test/fixtures --format=summary",
|
|
39
|
-
"demo:config": "node cli.js --config=.sunlint.json --input=test/fixtures",
|
|
40
|
-
"demo:eslint-integration": "./demo-eslint-integration.sh",
|
|
41
|
-
"demo:file-targeting": "./demo-file-targeting.sh",
|
|
42
|
-
"lint": "node cli.js --config=.sunlint.json --input=.",
|
|
43
|
-
"lint:eslint-integration": "node cli.js --all --eslint-integration --input=.",
|
|
44
|
-
"build": "npm run copy-rules && npm run generate-registry && npm run copy-arch-detect && echo 'Build completed'",
|
|
45
|
-
"copy-rules": "node scripts/copy-rules.js",
|
|
46
|
-
"generate-registry": "node scripts/generate-rules-registry.js",
|
|
47
|
-
"copy-arch-detect": "node scripts/copy-arch-detect.js",
|
|
48
|
-
"clean": "rm -rf coverage/ *.log reports/ *.tgz engines/arch-detect",
|
|
49
|
-
"postpack": "echo '📦 Package created successfully! Size: ' && ls -lh *.tgz | awk '{print $5}'",
|
|
50
|
-
"start": "node cli.js --help",
|
|
51
|
-
"version": "node cli.js --version",
|
|
52
|
-
"pack": "npm run build && npm pack",
|
|
53
|
-
"publish:github": "npm publish --registry=https://npm.pkg.github.com",
|
|
54
|
-
"publish:npmjs": "npm publish --registry=https://registry.npmjs.org",
|
|
55
|
-
"publish:test": "npm publish --dry-run --registry=https://registry.npmjs.org",
|
|
56
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
57
|
-
},
|
|
58
18
|
"keywords": [
|
|
59
19
|
"linting",
|
|
60
20
|
"code-quality",
|
|
@@ -79,6 +39,7 @@
|
|
|
79
39
|
"integrations/",
|
|
80
40
|
"rules/",
|
|
81
41
|
"scripts/",
|
|
42
|
+
"templates/",
|
|
82
43
|
"docs/",
|
|
83
44
|
".sunlint.json",
|
|
84
45
|
"README.md",
|
|
@@ -139,5 +100,19 @@
|
|
|
139
100
|
"bugs": {
|
|
140
101
|
"url": "https://github.com/sun-asterisk/engineer-excellence/issues"
|
|
141
102
|
},
|
|
142
|
-
"homepage": "https://github.com/sun-asterisk/engineer-excellence/tree/main/coding-quality/extensions/sunlint#readme"
|
|
143
|
-
|
|
103
|
+
"homepage": "https://github.com/sun-asterisk/engineer-excellence/tree/main/coding-quality/extensions/sunlint#readme",
|
|
104
|
+
"scripts": {
|
|
105
|
+
"test": "node examples/run-tests.js",
|
|
106
|
+
"test:perf": "node test/performance-test.js",
|
|
107
|
+
"lint": "node cli.js --all --input=. --format=summary",
|
|
108
|
+
"build": "pnpm run copy-rules && pnpm run generate-registry && pnpm run copy-arch-detect && pnpm run copy-impact",
|
|
109
|
+
"copy-rules": "node scripts/copy-rules.js",
|
|
110
|
+
"generate-registry": "node scripts/generate-rules-registry.js",
|
|
111
|
+
"copy-arch-detect": "node scripts/copy-arch-detect.js",
|
|
112
|
+
"copy-impact": "node scripts/copy-impact-analyzer.js",
|
|
113
|
+
"clean": "rm -rf coverage/ *.log reports/ *.tgz engines/arch-detect engines/impact",
|
|
114
|
+
"pack": "pnpm run build && pnpm pack",
|
|
115
|
+
"publish:npmjs": "pnpm publish --registry=https://registry.npmjs.org --no-git-checks",
|
|
116
|
+
"publish:test": "pnpm publish --dry-run --registry=https://registry.npmjs.org --no-git-checks"
|
|
117
|
+
}
|
|
118
|
+
}
|
package/scripts/build-release.sh
CHANGED
|
File without changes
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy impact-analyzer to engines/impact
|
|
3
|
+
* This script is run during build to bundle impact analysis functionality
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const SOURCE = path.resolve(__dirname, '../../../../impact-analyzer');
|
|
10
|
+
const DEST = path.resolve(__dirname, '../engines/impact');
|
|
11
|
+
|
|
12
|
+
// Files to copy from impact-analyzer
|
|
13
|
+
const FILES_TO_COPY = [
|
|
14
|
+
'index.js',
|
|
15
|
+
'cli.js',
|
|
16
|
+
'core',
|
|
17
|
+
'config',
|
|
18
|
+
'package.json'
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
// Files/folders to skip
|
|
22
|
+
const SKIP_PATTERNS = [
|
|
23
|
+
'node_modules',
|
|
24
|
+
'.git',
|
|
25
|
+
'test',
|
|
26
|
+
'tests',
|
|
27
|
+
'.DS_Store'
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function copyDir(src, dest) {
|
|
31
|
+
if (!fs.existsSync(src)) {
|
|
32
|
+
console.log('⚠️ Directory not found:', src);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!fs.existsSync(dest)) {
|
|
37
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
41
|
+
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
if (SKIP_PATTERNS.includes(entry.name)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const srcPath = path.join(src, entry.name);
|
|
48
|
+
const destPath = path.join(dest, entry.name);
|
|
49
|
+
|
|
50
|
+
if (entry.isDirectory()) {
|
|
51
|
+
copyDir(srcPath, destPath);
|
|
52
|
+
} else {
|
|
53
|
+
fs.copyFileSync(srcPath, destPath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function copyFile(src, dest) {
|
|
61
|
+
if (!fs.existsSync(src)) {
|
|
62
|
+
console.log('⚠️ File not found:', src);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const destDir = path.dirname(dest);
|
|
67
|
+
if (!fs.existsSync(destDir)) {
|
|
68
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
fs.copyFileSync(src, dest);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('📦 Copying impact-analyzer...');
|
|
76
|
+
|
|
77
|
+
if (!fs.existsSync(SOURCE)) {
|
|
78
|
+
console.log('⚠️ impact-analyzer not found. Skipping.');
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Clean destination
|
|
83
|
+
if (fs.existsSync(DEST)) {
|
|
84
|
+
fs.rmSync(DEST, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
fs.mkdirSync(DEST, { recursive: true });
|
|
87
|
+
|
|
88
|
+
let success = true;
|
|
89
|
+
|
|
90
|
+
for (const item of FILES_TO_COPY) {
|
|
91
|
+
const srcPath = path.join(SOURCE, item);
|
|
92
|
+
const destPath = path.join(DEST, item);
|
|
93
|
+
|
|
94
|
+
if (fs.existsSync(srcPath)) {
|
|
95
|
+
const stat = fs.statSync(srcPath);
|
|
96
|
+
if (stat.isDirectory()) {
|
|
97
|
+
if (!copyDir(srcPath, destPath)) {
|
|
98
|
+
success = false;
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
if (!copyFile(srcPath, destPath)) {
|
|
102
|
+
success = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (success) {
|
|
109
|
+
const size = getTotalSize(DEST);
|
|
110
|
+
console.log(`✅ Copied to engines/impact (${formatSize(size)})`);
|
|
111
|
+
} else {
|
|
112
|
+
console.log('⚠️ Some files could not be copied');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function getTotalSize(dir) {
|
|
116
|
+
let size = 0;
|
|
117
|
+
if (!fs.existsSync(dir)) return size;
|
|
118
|
+
|
|
119
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
const fullPath = path.join(dir, entry.name);
|
|
122
|
+
if (entry.isDirectory()) {
|
|
123
|
+
size += getTotalSize(fullPath);
|
|
124
|
+
} else {
|
|
125
|
+
size += fs.statSync(fullPath).size;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return size;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function formatSize(bytes) {
|
|
132
|
+
if (bytes < 1024) return bytes + ' B';
|
|
133
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
134
|
+
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
135
|
+
}
|
package/scripts/install.sh
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|