git-repo-analyzer-test 1.0.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/.github/copilot-instructions.md +108 -0
- package/.idea/aianalyzer.iml +9 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/API_REFERENCE.md +244 -0
- package/ENHANCEMENTS.md +282 -0
- package/README.md +179 -0
- package/USAGE.md +189 -0
- package/analysis.txt +0 -0
- package/bin/cli.js +135 -0
- package/docs/SONARCLOUD_ANALYSIS_COVERED.md +144 -0
- package/docs/SonarCloud_Presentation_Points.md +81 -0
- package/docs/UI_IMPROVEMENTS.md +117 -0
- package/package-lock_cmd.json +542 -0
- package/package.json +44 -0
- package/package_command.json +16 -0
- package/public/analysis-options.json +31 -0
- package/public/images/README.txt +2 -0
- package/public/images/rws-logo.png +0 -0
- package/public/index.html +2433 -0
- package/repositories.example.txt +17 -0
- package/sample-repos.txt +20 -0
- package/src/analyzers/accessibility.js +47 -0
- package/src/analyzers/cicd-enhanced.js +113 -0
- package/src/analyzers/codeReview-enhanced.js +599 -0
- package/src/analyzers/codeReview-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/codeReview.js +171 -0
- package/src/analyzers/codeReview.js:Zone.Identifier +3 -0
- package/src/analyzers/documentation-enhanced.js +137 -0
- package/src/analyzers/performance-enhanced.js +747 -0
- package/src/analyzers/performance-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/performance.js +211 -0
- package/src/analyzers/performance.js:Zone.Identifier +3 -0
- package/src/analyzers/performance_cmd.js +216 -0
- package/src/analyzers/quality-enhanced.js +386 -0
- package/src/analyzers/quality-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/quality.js +92 -0
- package/src/analyzers/quality.js:Zone.Identifier +3 -0
- package/src/analyzers/security-enhanced.js +512 -0
- package/src/analyzers/security-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/snyk-ai.js:Zone.Identifier +3 -0
- package/src/analyzers/sonarcloud.js +928 -0
- package/src/analyzers/vulnerability.js +185 -0
- package/src/analyzers/vulnerability.js:Zone.Identifier +3 -0
- package/src/cli.js:Zone.Identifier +3 -0
- package/src/config.js +43 -0
- package/src/core/analyzerEngine.js +68 -0
- package/src/core/reportGenerator.js +21 -0
- package/src/gemini.js +321 -0
- package/src/github/client.js +124 -0
- package/src/github/client.js:Zone.Identifier +3 -0
- package/src/index.js +93 -0
- package/src/index_cmd.js +130 -0
- package/src/openai.js +297 -0
- package/src/report/generator.js +459 -0
- package/src/report/generator_cmd.js +459 -0
- package/src/report/pdf-generator.js +387 -0
- package/src/report/pdf-generator.js:Zone.Identifier +3 -0
- package/src/server.js +431 -0
- package/src/server.js:Zone.Identifier +3 -0
- package/src/server_cmd.js +434 -0
- package/src/sonarcloud/client.js +365 -0
- package/src/sonarcloud/scanner.js +171 -0
- package/src.zip +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Example: repositories.txt
|
|
2
|
+
|
|
3
|
+
Add repositories you want to analyze, one per line. Example:
|
|
4
|
+
|
|
5
|
+
facebook/react
|
|
6
|
+
google/angular
|
|
7
|
+
vuejs/vue
|
|
8
|
+
pytorch/pytorch
|
|
9
|
+
tensorflow/tensorflow
|
|
10
|
+
angular/angular
|
|
11
|
+
golang/go
|
|
12
|
+
kubernetes/kubernetes
|
|
13
|
+
nodejs/node
|
|
14
|
+
rust-lang/rust
|
|
15
|
+
|
|
16
|
+
# Save this file and run:
|
|
17
|
+
# npm run analyze -- batch repositories.txt --output-dir ./reports
|
package/sample-repos.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
facebook/react
|
|
2
|
+
google/angular
|
|
3
|
+
vuejs/vue
|
|
4
|
+
nodejs/node
|
|
5
|
+
torvalds/linux
|
|
6
|
+
kubernetes/kubernetes
|
|
7
|
+
tensorflow/tensorflow
|
|
8
|
+
pytorch/pytorch
|
|
9
|
+
golang/go
|
|
10
|
+
rust-lang/rust
|
|
11
|
+
microsoft/vscode
|
|
12
|
+
apache/kafka
|
|
13
|
+
elastic/elasticsearch
|
|
14
|
+
mongodb/mongo
|
|
15
|
+
redis/redis
|
|
16
|
+
docker/cli
|
|
17
|
+
ansible/ansible
|
|
18
|
+
jenkins-ci/jenkins
|
|
19
|
+
prometheus/prometheus
|
|
20
|
+
grafana/grafana
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
process.env.OPENAI_API_KEY="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";
|
|
3
|
+
|
|
4
|
+
const client = new OpenAI({
|
|
5
|
+
apiKey: process.env.OPENAI_API_KEY
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export class AccessibilityAnalyzer {
|
|
9
|
+
async analyze(repoUrl) {
|
|
10
|
+
const prompt = `
|
|
11
|
+
You are an Accessibility expert (WCAG 2.1 AA).
|
|
12
|
+
|
|
13
|
+
Analyze the following GitHub repository:
|
|
14
|
+
${repoUrl}
|
|
15
|
+
|
|
16
|
+
Check:
|
|
17
|
+
- Semantic HTML usage
|
|
18
|
+
- ARIA roles
|
|
19
|
+
- Forms (labels, inputs)
|
|
20
|
+
- Keyboard accessibility
|
|
21
|
+
- Images (alt text)
|
|
22
|
+
- Color contrast issues
|
|
23
|
+
|
|
24
|
+
Return JSON:
|
|
25
|
+
{
|
|
26
|
+
"score": 0-100,
|
|
27
|
+
"issues": [
|
|
28
|
+
{
|
|
29
|
+
"severity": "high|medium|low",
|
|
30
|
+
"issue": "...",
|
|
31
|
+
"file": "...",
|
|
32
|
+
"fix": "..."
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"summary": "..."
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const response = await client.chat.completions.create({
|
|
40
|
+
model: "gpt-4o-mini",
|
|
41
|
+
messages: [{ role: "user", content: prompt }],
|
|
42
|
+
temperature: 0.3
|
|
43
|
+
});
|
|
44
|
+
return response.choices[0].message.content;
|
|
45
|
+
// return JSON.parse(response.choices[0].message.content);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CI/CD & automation analyzer
|
|
3
|
+
* Checks for GitHub Actions workflows, branch protection signals, and automation health
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class CICDAnalyzer {
|
|
7
|
+
constructor(githubClient) {
|
|
8
|
+
this.client = githubClient;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async analyzeCICD(owner, repo) {
|
|
12
|
+
let workflows = [];
|
|
13
|
+
try {
|
|
14
|
+
const contents = await this.client.getRepositoryContents(owner, repo, '.github/workflows');
|
|
15
|
+
if (Array.isArray(contents)) workflows = contents.filter((f) => f.name && (f.name.endsWith('.yml') || f.name.endsWith('.yaml')));
|
|
16
|
+
} catch {
|
|
17
|
+
// no workflows
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const workflowNames = workflows.map((f) => f.name || '');
|
|
21
|
+
const hasTest = workflowNames.some(
|
|
22
|
+
(n) => /test|ci|build|verify/i.test(n)
|
|
23
|
+
);
|
|
24
|
+
const hasLint = workflowNames.some(
|
|
25
|
+
(n) => /lint|format|check/i.test(n)
|
|
26
|
+
);
|
|
27
|
+
const hasRelease = workflowNames.some(
|
|
28
|
+
(n) => /release|deploy|publish/i.test(n)
|
|
29
|
+
);
|
|
30
|
+
const hasDependabot = workflowNames.some((n) => /dependabot|dependabot/i.test(n));
|
|
31
|
+
|
|
32
|
+
let dependabotConfig = false;
|
|
33
|
+
try {
|
|
34
|
+
const githubRoot = await this.client.getRepositoryContents(owner, repo, '.github');
|
|
35
|
+
const list = Array.isArray(githubRoot) ? githubRoot : [githubRoot];
|
|
36
|
+
dependabotConfig = list.some((f) => (f.name || '').toLowerCase() === 'dependabot.yml');
|
|
37
|
+
} catch {
|
|
38
|
+
// ignore
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const repoData = await this.client.getRepository(owner, repo);
|
|
42
|
+
const defaultBranch = repoData.default_branch || 'main';
|
|
43
|
+
const hasBranchProtection = !!repoData.permissions?.admin; // we can't always see rules; use as hint
|
|
44
|
+
const isArchived = !!repoData.archived;
|
|
45
|
+
|
|
46
|
+
const checks = {
|
|
47
|
+
workflowCount: workflows.length,
|
|
48
|
+
hasTest,
|
|
49
|
+
hasLint,
|
|
50
|
+
hasRelease,
|
|
51
|
+
hasDependabot,
|
|
52
|
+
dependabotConfig,
|
|
53
|
+
defaultBranch,
|
|
54
|
+
isArchived,
|
|
55
|
+
workflowFiles: workflowNames,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const score = this.calculateScore(checks);
|
|
59
|
+
const rating = this.getRating(score);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
score,
|
|
63
|
+
rating,
|
|
64
|
+
checks,
|
|
65
|
+
recommendations: this.getRecommendations(checks),
|
|
66
|
+
summary: {
|
|
67
|
+
totalWorkflows: workflows.length,
|
|
68
|
+
categories: { test: hasTest, lint: hasLint, release: hasRelease },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
calculateScore(checks) {
|
|
74
|
+
let s = 0;
|
|
75
|
+
if (checks.workflowCount > 0) s += 2;
|
|
76
|
+
if (checks.hasTest) s += 2.5;
|
|
77
|
+
if (checks.hasLint) s += 1.5;
|
|
78
|
+
if (checks.hasRelease) s += 1.5;
|
|
79
|
+
if (checks.dependabotConfig || checks.hasDependabot) s += 1;
|
|
80
|
+
if (checks.workflowCount >= 2) s += 0.5;
|
|
81
|
+
if (checks.isArchived) s = Math.max(0, s - 2);
|
|
82
|
+
return Math.min(10, Math.round(s * 10) / 10);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getRating(score) {
|
|
86
|
+
if (score >= 9) return 'A+';
|
|
87
|
+
if (score >= 8) return 'A';
|
|
88
|
+
if (score >= 7) return 'B+';
|
|
89
|
+
if (score >= 6) return 'B';
|
|
90
|
+
if (score >= 5) return 'C+';
|
|
91
|
+
if (score >= 4) return 'C';
|
|
92
|
+
return 'F';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getRecommendations(checks) {
|
|
96
|
+
const recs = [];
|
|
97
|
+
if (checks.workflowCount === 0) {
|
|
98
|
+
recs.push({ priority: 'HIGH', title: 'Add CI', action: 'Add GitHub Actions workflows for tests and linting.' });
|
|
99
|
+
} else {
|
|
100
|
+
if (!checks.hasTest) recs.push({ priority: 'HIGH', title: 'Add test workflow', action: 'Add a workflow that runs tests on push/PR.' });
|
|
101
|
+
if (!checks.hasLint) recs.push({ priority: 'MEDIUM', title: 'Add lint workflow', action: 'Add a workflow for linting/formatting checks.' });
|
|
102
|
+
}
|
|
103
|
+
if (!checks.dependabotConfig && !checks.hasDependabot) {
|
|
104
|
+
recs.push({ priority: 'MEDIUM', title: 'Enable Dependabot', action: 'Add .github/dependabot.yml or enable in repo settings.' });
|
|
105
|
+
}
|
|
106
|
+
if (checks.isArchived) {
|
|
107
|
+
recs.push({ priority: 'LOW', title: 'Repository archived', action: 'Consider unarchiving if the project is maintained.' });
|
|
108
|
+
}
|
|
109
|
+
return recs;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default CICDAnalyzer;
|