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.
Files changed (65) hide show
  1. package/.github/copilot-instructions.md +108 -0
  2. package/.idea/aianalyzer.iml +9 -0
  3. package/.idea/misc.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/API_REFERENCE.md +244 -0
  7. package/ENHANCEMENTS.md +282 -0
  8. package/README.md +179 -0
  9. package/USAGE.md +189 -0
  10. package/analysis.txt +0 -0
  11. package/bin/cli.js +135 -0
  12. package/docs/SONARCLOUD_ANALYSIS_COVERED.md +144 -0
  13. package/docs/SonarCloud_Presentation_Points.md +81 -0
  14. package/docs/UI_IMPROVEMENTS.md +117 -0
  15. package/package-lock_cmd.json +542 -0
  16. package/package.json +44 -0
  17. package/package_command.json +16 -0
  18. package/public/analysis-options.json +31 -0
  19. package/public/images/README.txt +2 -0
  20. package/public/images/rws-logo.png +0 -0
  21. package/public/index.html +2433 -0
  22. package/repositories.example.txt +17 -0
  23. package/sample-repos.txt +20 -0
  24. package/src/analyzers/accessibility.js +47 -0
  25. package/src/analyzers/cicd-enhanced.js +113 -0
  26. package/src/analyzers/codeReview-enhanced.js +599 -0
  27. package/src/analyzers/codeReview-enhanced.js:Zone.Identifier +3 -0
  28. package/src/analyzers/codeReview.js +171 -0
  29. package/src/analyzers/codeReview.js:Zone.Identifier +3 -0
  30. package/src/analyzers/documentation-enhanced.js +137 -0
  31. package/src/analyzers/performance-enhanced.js +747 -0
  32. package/src/analyzers/performance-enhanced.js:Zone.Identifier +3 -0
  33. package/src/analyzers/performance.js +211 -0
  34. package/src/analyzers/performance.js:Zone.Identifier +3 -0
  35. package/src/analyzers/performance_cmd.js +216 -0
  36. package/src/analyzers/quality-enhanced.js +386 -0
  37. package/src/analyzers/quality-enhanced.js:Zone.Identifier +3 -0
  38. package/src/analyzers/quality.js +92 -0
  39. package/src/analyzers/quality.js:Zone.Identifier +3 -0
  40. package/src/analyzers/security-enhanced.js +512 -0
  41. package/src/analyzers/security-enhanced.js:Zone.Identifier +3 -0
  42. package/src/analyzers/snyk-ai.js:Zone.Identifier +3 -0
  43. package/src/analyzers/sonarcloud.js +928 -0
  44. package/src/analyzers/vulnerability.js +185 -0
  45. package/src/analyzers/vulnerability.js:Zone.Identifier +3 -0
  46. package/src/cli.js:Zone.Identifier +3 -0
  47. package/src/config.js +43 -0
  48. package/src/core/analyzerEngine.js +68 -0
  49. package/src/core/reportGenerator.js +21 -0
  50. package/src/gemini.js +321 -0
  51. package/src/github/client.js +124 -0
  52. package/src/github/client.js:Zone.Identifier +3 -0
  53. package/src/index.js +93 -0
  54. package/src/index_cmd.js +130 -0
  55. package/src/openai.js +297 -0
  56. package/src/report/generator.js +459 -0
  57. package/src/report/generator_cmd.js +459 -0
  58. package/src/report/pdf-generator.js +387 -0
  59. package/src/report/pdf-generator.js:Zone.Identifier +3 -0
  60. package/src/server.js +431 -0
  61. package/src/server.js:Zone.Identifier +3 -0
  62. package/src/server_cmd.js +434 -0
  63. package/src/sonarcloud/client.js +365 -0
  64. package/src/sonarcloud/scanner.js +171 -0
  65. package/src.zip +0 -0
@@ -0,0 +1,386 @@
1
+ /**
2
+ * Enhanced Code Quality Analyzer
3
+ * Provides detailed insights on code quality metrics against standards
4
+ */
5
+ export class CodeQualityAnalyzer {
6
+ constructor(githubClient) {
7
+ this.client = githubClient;
8
+ }
9
+
10
+ /**
11
+ * Comprehensive code quality analysis
12
+ */
13
+ async analyzeCodeQuality(owner, repo) {
14
+ try {
15
+ const [repoData, languages, commits] = await Promise.all([
16
+ this.client.getRepository(owner, repo),
17
+ this.client.getLanguages(owner, repo),
18
+ this.client.getCommits(owner, repo, { perPage: 100 }),
19
+ ]);
20
+
21
+ const issues = this.identifyCodeQualityIssues(repoData, languages);
22
+ const score = this.calculateQualityScore(repoData, issues);
23
+ const rating = this.getRating(score);
24
+
25
+ return {
26
+ score,
27
+ rating,
28
+ metrics: {
29
+ stars: repoData.stargazers_count || 0,
30
+ forks: repoData.forks_count || 0,
31
+ watchers: repoData.watchers_count || 0,
32
+ openIssues: repoData.open_issues_count || 0,
33
+ hasWiki: repoData.has_wiki,
34
+ hasPages: repoData.has_pages,
35
+ languages: Object.keys(languages).length,
36
+ primaryLanguage: repoData.language,
37
+ lastUpdate: repoData.updated_at,
38
+ daysInactive: this.getDaysSinceUpdate(repoData.updated_at),
39
+ description: repoData.description,
40
+ topics: repoData.topics || [],
41
+ license: repoData.license?.name || 'None',
42
+ isArchived: repoData.archived,
43
+ size: repoData.size,
44
+ },
45
+ issues,
46
+ recommendations: this.generateQualityRecommendations(issues),
47
+ details: {
48
+ codeStandards: this.analyzeCodeStandards(repoData, languages),
49
+ libraryAudit: this.auditLibraries(repoData),
50
+ documentationQuality: this.assessDocumentation(repoData),
51
+ maintenanceStatus: this.assessMaintenanceStatus(repoData, commits),
52
+ },
53
+ };
54
+ } catch (error) {
55
+ throw new Error(`Code quality analysis failed: ${error.message}`);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Identify specific code quality issues
61
+ */
62
+ identifyCodeQualityIssues(repoData, languages) {
63
+ const issues = [];
64
+
65
+ // Issue 1: Outdated or archived repository
66
+ if (repoData.archived) {
67
+ issues.push({
68
+ type: 'ARCHIVED_REPOSITORY',
69
+ severity: 'HIGH',
70
+ message: 'Repository is archived and no longer maintained',
71
+ location: 'Repository Status',
72
+ impact: 'No updates or security patches expected',
73
+ recommendation: 'Consider using an actively maintained fork or alternative',
74
+ });
75
+ }
76
+
77
+ // Issue 2: No license
78
+ if (!repoData.license) {
79
+ issues.push({
80
+ type: 'NO_LICENSE',
81
+ severity: 'MEDIUM',
82
+ message: 'Repository has no license defined',
83
+ location: 'LICENSE file',
84
+ impact: 'Legal and usage clarity issues for contributors',
85
+ recommendation: 'Add a LICENSE file (MIT, Apache 2.0, GPL, etc.)',
86
+ });
87
+ }
88
+
89
+ // Issue 3: Stale repository (>1 year inactive)
90
+ const daysSinceUpdate = this.getDaysSinceUpdate(repoData.updated_at);
91
+ if (daysSinceUpdate > 365) {
92
+ issues.push({
93
+ type: 'STALE_CODEBASE',
94
+ severity: 'MEDIUM',
95
+ message: `Repository not updated for ${daysSinceUpdate} days`,
96
+ location: 'Last commit/update',
97
+ impact: 'Potential security vulnerabilities, outdated dependencies',
98
+ recommendation: 'Regular maintenance and dependency updates needed',
99
+ });
100
+ }
101
+
102
+ // Issue 4: High number of open issues
103
+ if (repoData.open_issues_count > 100) {
104
+ issues.push({
105
+ type: 'UNRESOLVED_ISSUES',
106
+ severity: 'MEDIUM',
107
+ message: `${repoData.open_issues_count} open issues`,
108
+ location: 'Issues tracker',
109
+ impact: 'Code quality concerns, bug backlog',
110
+ recommendation: 'Implement issue triage and prioritization strategy',
111
+ });
112
+ }
113
+
114
+ // Issue 5: Lack of documentation
115
+ if (!repoData.has_wiki && !repoData.has_pages && !repoData.description) {
116
+ issues.push({
117
+ type: 'POOR_DOCUMENTATION',
118
+ severity: 'MEDIUM',
119
+ message: 'Insufficient documentation for code clarity',
120
+ location: 'README, Wiki, GitHub Pages',
121
+ impact: 'Hard to understand code purpose and usage',
122
+ recommendation: 'Add comprehensive README.md, API documentation, examples',
123
+ });
124
+ }
125
+
126
+ // Issue 6: Too many languages (indicates scattered codebase)
127
+ const languageCount = Object.keys(languages).length;
128
+ if (languageCount > 8) {
129
+ issues.push({
130
+ type: 'EXCESSIVE_LANGUAGES',
131
+ severity: 'LOW',
132
+ message: `Using ${languageCount} different programming languages`,
133
+ location: 'Various file types across repo',
134
+ impact: 'Maintenance complexity, inconsistent code standards',
135
+ recommendation: 'Consider consolidating to core languages only',
136
+ });
137
+ }
138
+
139
+ // Issue 7: No primary language detected
140
+ if (!repoData.language) {
141
+ issues.push({
142
+ type: 'NO_PRIMARY_LANGUAGE',
143
+ severity: 'LOW',
144
+ message: 'No primary programming language identified',
145
+ location: 'Repository structure',
146
+ impact: 'Unclear project type and technical stack',
147
+ recommendation: 'Ensure majority of code is in a single language',
148
+ });
149
+ }
150
+
151
+ // Issue 8: Large repository (code smell)
152
+ if (repoData.size > 500000) {
153
+ issues.push({
154
+ type: 'LARGE_REPOSITORY',
155
+ severity: 'LOW',
156
+ message: `Repository size is ${Math.round(repoData.size / 1024)} MB`,
157
+ location: 'Overall repository',
158
+ impact: 'Slow clone times, harder to navigate',
159
+ recommendation: 'Consider splitting into multiple repositories or removing artifacts',
160
+ });
161
+ }
162
+
163
+ return issues;
164
+ }
165
+
166
+ /**
167
+ * Analyze code standards compliance
168
+ */
169
+ analyzeCodeStandards(repoData, languages) {
170
+ const languageList = Object.keys(languages);
171
+ const standards = {
172
+ hasLinter: this.hasLinterConfiguration(repoData),
173
+ hasFormatter: this.hasFormatterConfiguration(repoData),
174
+ hasTests: this.hasTestSetup(repoData),
175
+ hasBuildProcess: this.hasBuildConfiguration(repoData),
176
+ hasCICD: this.hasCICDConfiguration(repoData),
177
+ primaryLanguages: languageList.slice(0, 3),
178
+ languageDetails: this.getLanguageDetails(languageList),
179
+ };
180
+ return standards;
181
+ }
182
+
183
+ /**
184
+ * Audit dependencies and libraries
185
+ */
186
+ auditLibraries(repoData) {
187
+ const hasPackageJson = repoData.topics?.includes('npm') ||
188
+ repoData.language === 'JavaScript' ||
189
+ repoData.language === 'TypeScript';
190
+ const hasPyproject = repoData.topics?.includes('python') ||
191
+ repoData.language === 'Python';
192
+ const hasGemfile = repoData.language === 'Ruby';
193
+
194
+ return {
195
+ dependencyManagement: {
196
+ npm: hasPackageJson,
197
+ python: hasPyproject,
198
+ ruby: hasGemfile,
199
+ other: !hasPackageJson && !hasPyproject && !hasGemfile,
200
+ },
201
+ recommendations: [
202
+ 'Regular dependency updates recommended',
203
+ 'Use dependency scanning tools (npm audit, pip-audit)',
204
+ 'Keep frameworks and libraries up to date',
205
+ 'Monitor security advisories for used libraries',
206
+ ],
207
+ };
208
+ }
209
+
210
+ /**
211
+ * Assess documentation quality
212
+ */
213
+ assessDocumentation(repoData) {
214
+ const score = {
215
+ readme: repoData.description ? 2 : 0,
216
+ wiki: repoData.has_wiki ? 2 : 0,
217
+ pages: repoData.has_pages ? 2 : 0,
218
+ license: repoData.license ? 2 : 0,
219
+ changelog: 0, // Would need file scanning
220
+ contributing: 0, // Would need file scanning
221
+ };
222
+ const total = Object.values(score).reduce((a, b) => a + b, 0);
223
+ return {
224
+ score: total,
225
+ maxScore: 12,
226
+ percentage: Math.round((total / 12) * 100),
227
+ details: score,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Assess repository maintenance status
233
+ */
234
+ assessMaintenanceStatus(repoData, commits) {
235
+ const daysSinceUpdate = this.getDaysSinceUpdate(repoData.updated_at);
236
+ let status = 'ACTIVE';
237
+ let points = 10;
238
+
239
+ if (daysSinceUpdate > 365) {
240
+ status = 'INACTIVE';
241
+ points = 2;
242
+ } else if (daysSinceUpdate > 180) {
243
+ status = 'DORMANT';
244
+ points = 4;
245
+ } else if (daysSinceUpdate > 30) {
246
+ status = 'MODERATE';
247
+ points = 7;
248
+ }
249
+
250
+ return {
251
+ status,
252
+ points,
253
+ daysSinceUpdate,
254
+ commitFrequency: commits.length > 0 ? 'Active' : 'None',
255
+ recommendations:
256
+ status === 'ACTIVE'
257
+ ? ['Maintain current update frequency']
258
+ : ['Resume active maintenance', 'Update dependencies', 'Address open issues'],
259
+ };
260
+ }
261
+
262
+ /**
263
+ * Helper: Get days since last update
264
+ */
265
+ getDaysSinceUpdate(lastUpdate) {
266
+ const lastUpdateDate = new Date(lastUpdate);
267
+ const daysSince = Math.floor((new Date() - lastUpdateDate) / (1000 * 60 * 60 * 24));
268
+ return daysSince;
269
+ }
270
+
271
+ /**
272
+ * Helper: Check for linter configuration
273
+ */
274
+ hasLinterConfiguration(repoData) {
275
+ return repoData.topics?.some((t) =>
276
+ ['eslint', 'pylint', 'rubocop', 'prettier'].includes(t)
277
+ );
278
+ }
279
+
280
+ /**
281
+ * Helper: Check for formatter configuration
282
+ */
283
+ hasFormatterConfiguration(repoData) {
284
+ return repoData.topics?.some((t) =>
285
+ ['prettier', 'black', 'rustfmt'].includes(t)
286
+ );
287
+ }
288
+
289
+ /**
290
+ * Helper: Check for test setup
291
+ */
292
+ hasTestSetup(repoData) {
293
+ return repoData.topics?.some((t) =>
294
+ ['testing', 'jest', 'pytest', 'rspec', 'vitest'].includes(t)
295
+ );
296
+ }
297
+
298
+ /**
299
+ * Helper: Check for build configuration
300
+ */
301
+ hasBuildConfiguration(repoData) {
302
+ return repoData.topics?.some((t) =>
303
+ ['webpack', 'gradle', 'maven', 'cargo', 'rust'].includes(t)
304
+ );
305
+ }
306
+
307
+ /**
308
+ * Helper: Check for CI/CD configuration
309
+ */
310
+ hasCICDConfiguration(repoData) {
311
+ return repoData.topics?.some((t) =>
312
+ ['github-actions', 'ci', 'cd', 'travis', 'gitlab-ci'].includes(t)
313
+ );
314
+ }
315
+
316
+ /**
317
+ * Helper: Get language details
318
+ */
319
+ getLanguageDetails(languages) {
320
+ const languageMap = {
321
+ JavaScript: 'Dynamic, web-focused',
322
+ TypeScript: 'Typed JavaScript, enterprise',
323
+ Python: 'Scripting, data science, automation',
324
+ Java: 'Enterprise, large-scale systems',
325
+ Go: 'Concurrent, cloud-native',
326
+ Rust: 'Systems, performance-critical',
327
+ 'C++': 'Performance, systems programming',
328
+ 'C#': 'Enterprise, .NET ecosystem',
329
+ Ruby: 'Rapid development, web frameworks',
330
+ PHP: 'Web backend, rapid deployment',
331
+ };
332
+ return languages.map((lang) => ({
333
+ language: lang,
334
+ description: languageMap[lang] || 'General purpose',
335
+ }));
336
+ }
337
+
338
+ /**
339
+ * Calculate quality score
340
+ */
341
+ calculateQualityScore(repoData, issues) {
342
+ let score = 100;
343
+
344
+ // Deduct points for issues
345
+ issues.forEach((issue) => {
346
+ if (issue.severity === 'HIGH') score -= 20;
347
+ else if (issue.severity === 'MEDIUM') score -= 10;
348
+ else if (issue.severity === 'LOW') score -= 3;
349
+ });
350
+
351
+ // Add bonus points for good practices
352
+ if (repoData.has_wiki) score += 2;
353
+ if (repoData.has_pages) score += 2;
354
+ if (repoData.license) score += 3;
355
+ if (repoData.stargazers_count > 1000) score += 5;
356
+
357
+ return Math.max(0, Math.min(100, score));
358
+ }
359
+
360
+ /**
361
+ * Generate recommendations
362
+ */
363
+ generateQualityRecommendations(issues) {
364
+ return issues.map((issue) => ({
365
+ priority: issue.severity,
366
+ issue: issue.message,
367
+ location: issue.location,
368
+ action: issue.recommendation,
369
+ }));
370
+ }
371
+
372
+ /**
373
+ * Get rating from score
374
+ */
375
+ getRating(score) {
376
+ if (score >= 90) return 'A+';
377
+ if (score >= 80) return 'A';
378
+ if (score >= 70) return 'B+';
379
+ if (score >= 60) return 'B';
380
+ if (score >= 50) return 'C+';
381
+ if (score >= 40) return 'C';
382
+ return 'F';
383
+ }
384
+ }
385
+
386
+ export default CodeQualityAnalyzer;
@@ -0,0 +1,3 @@
1
+ [ZoneTransfer]
2
+ ZoneId=3
3
+ ReferrerUrl=C:\Users\jitendra.yadav\Downloads\GitRepoAnalyzer - Shabbir.zip
@@ -0,0 +1,92 @@
1
+ import { GitHubClient } from '../github/client.js';
2
+
3
+ export class QualityAnalyzer {
4
+ constructor(githubClient) {
5
+ this.client = githubClient;
6
+ }
7
+
8
+ /**
9
+ * Analyze code quality metrics
10
+ */
11
+ async analyzeCodeQuality(owner, repo) {
12
+ if (!owner || !repo) {
13
+ throw new Error('Owner and repo are required');
14
+ }
15
+
16
+ try {
17
+ console.info(`Analyzing repo: ${owner}/${repo}`);
18
+
19
+ const [repoData, languages] = await Promise.all([
20
+ this.client.getRepository(owner, repo),
21
+ this.client.getLanguages(owner, repo),
22
+ ]);
23
+
24
+ const daysInactive = repoData.pushed_at
25
+ ? Math.floor((Date.now() - new Date(repoData.pushed_at)) / (1000 * 60 * 60 * 24))
26
+ : null;
27
+
28
+ return {
29
+ score: this.calculateQualityScore(repoData),
30
+ metrics: {
31
+ stars: repoData.stargazers_count || 0,
32
+ forks: repoData.forks_count || 0,
33
+ watchers: repoData.watchers_count || 0,
34
+ openIssues: repoData.open_issues_count || 0,
35
+ hasWiki: repoData.has_wiki || false,
36
+ hasPages: repoData.has_pages || false,
37
+ languageCount: languages ? Object.keys(languages).length : 0,
38
+ primaryLanguage: repoData.language,
39
+ lastUpdate: repoData.updated_at,
40
+ daysInactive,
41
+ description: repoData.description,
42
+ topics: repoData.topics || [],
43
+ },
44
+ };
45
+
46
+ } catch (error) {
47
+ console.error('QualityAnalyzer Error:', error);
48
+ throw error;
49
+ }
50
+ }
51
+ /**
52
+ * Calculate overall quality score (0-100)
53
+ */
54
+ calculateQualityScore(repoData) {
55
+ let score = 50; // Base score
56
+
57
+ // Stars contribution (0-15)
58
+ score += Math.min(repoData.stargazers_count / 1000, 15);
59
+
60
+ // Forks contribution (0-10)
61
+ score += Math.min(repoData.forks_count / 500, 10);
62
+
63
+ // Issues contribution (0-10)
64
+ const issueScore = Math.max(10 - repoData.open_issues_count / 100, 0);
65
+ score += issueScore;
66
+
67
+ // Documentation (0-10)
68
+ if (repoData.has_wiki || repoData.description) {
69
+ score += 5;
70
+ }
71
+ if (repoData.has_pages) {
72
+ score += 5;
73
+ }
74
+
75
+ // Activity (0-10)
76
+ const lastUpdate = new Date(repoData.updated_at);
77
+ const daysSinceUpdate = Math.floor(
78
+ (new Date() - lastUpdate) / (1000 * 60 * 60 * 24)
79
+ );
80
+ if (daysSinceUpdate < 30) {
81
+ score += 10;
82
+ } else if (daysSinceUpdate < 90) {
83
+ score += 7;
84
+ } else if (daysSinceUpdate < 365) {
85
+ score += 3;
86
+ }
87
+
88
+ return Math.min(Math.round(score), 100);
89
+ }
90
+ }
91
+
92
+ export default QualityAnalyzer;
@@ -0,0 +1,3 @@
1
+ [ZoneTransfer]
2
+ ZoneId=3
3
+ ReferrerUrl=C:\Users\jitendra.yadav\Downloads\GitRepoAnalyzer - Shabbir.zip