aidp 0.5.0 → 0.8.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.
- checksums.yaml +4 -4
- data/README.md +128 -151
- data/bin/aidp +1 -1
- data/lib/aidp/analysis/kb_inspector.rb +471 -0
- data/lib/aidp/analysis/seams.rb +159 -0
- data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +480 -0
- data/lib/aidp/analysis/tree_sitter_scan.rb +686 -0
- data/lib/aidp/analyze/error_handler.rb +2 -78
- data/lib/aidp/analyze/json_file_storage.rb +292 -0
- data/lib/aidp/analyze/progress.rb +12 -0
- data/lib/aidp/analyze/progress_visualizer.rb +12 -17
- data/lib/aidp/analyze/ruby_maat_integration.rb +13 -31
- data/lib/aidp/analyze/runner.rb +256 -87
- data/lib/aidp/analyze/steps.rb +6 -0
- data/lib/aidp/cli/jobs_command.rb +103 -435
- data/lib/aidp/cli.rb +317 -191
- data/lib/aidp/config.rb +298 -10
- data/lib/aidp/debug_logger.rb +195 -0
- data/lib/aidp/debug_mixin.rb +187 -0
- data/lib/aidp/execute/progress.rb +9 -0
- data/lib/aidp/execute/runner.rb +221 -40
- data/lib/aidp/execute/steps.rb +17 -7
- data/lib/aidp/execute/workflow_selector.rb +211 -0
- data/lib/aidp/harness/completion_checker.rb +268 -0
- data/lib/aidp/harness/condition_detector.rb +1526 -0
- data/lib/aidp/harness/config_loader.rb +373 -0
- data/lib/aidp/harness/config_manager.rb +382 -0
- data/lib/aidp/harness/config_schema.rb +1006 -0
- data/lib/aidp/harness/config_validator.rb +355 -0
- data/lib/aidp/harness/configuration.rb +477 -0
- data/lib/aidp/harness/enhanced_runner.rb +494 -0
- data/lib/aidp/harness/error_handler.rb +616 -0
- data/lib/aidp/harness/provider_config.rb +423 -0
- data/lib/aidp/harness/provider_factory.rb +306 -0
- data/lib/aidp/harness/provider_manager.rb +1269 -0
- data/lib/aidp/harness/provider_type_checker.rb +88 -0
- data/lib/aidp/harness/runner.rb +411 -0
- data/lib/aidp/harness/state/errors.rb +28 -0
- data/lib/aidp/harness/state/metrics.rb +219 -0
- data/lib/aidp/harness/state/persistence.rb +128 -0
- data/lib/aidp/harness/state/provider_state.rb +132 -0
- data/lib/aidp/harness/state/ui_state.rb +68 -0
- data/lib/aidp/harness/state/workflow_state.rb +123 -0
- data/lib/aidp/harness/state_manager.rb +586 -0
- data/lib/aidp/harness/status_display.rb +888 -0
- data/lib/aidp/harness/ui/base.rb +16 -0
- data/lib/aidp/harness/ui/enhanced_tui.rb +545 -0
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +252 -0
- data/lib/aidp/harness/ui/error_handler.rb +132 -0
- data/lib/aidp/harness/ui/frame_manager.rb +361 -0
- data/lib/aidp/harness/ui/job_monitor.rb +500 -0
- data/lib/aidp/harness/ui/navigation/main_menu.rb +311 -0
- data/lib/aidp/harness/ui/navigation/menu_formatter.rb +120 -0
- data/lib/aidp/harness/ui/navigation/menu_item.rb +142 -0
- data/lib/aidp/harness/ui/navigation/menu_state.rb +139 -0
- data/lib/aidp/harness/ui/navigation/submenu.rb +202 -0
- data/lib/aidp/harness/ui/navigation/workflow_selector.rb +176 -0
- data/lib/aidp/harness/ui/progress_display.rb +280 -0
- data/lib/aidp/harness/ui/question_collector.rb +141 -0
- data/lib/aidp/harness/ui/spinner_group.rb +184 -0
- data/lib/aidp/harness/ui/spinner_helper.rb +152 -0
- data/lib/aidp/harness/ui/status_manager.rb +312 -0
- data/lib/aidp/harness/ui/status_widget.rb +280 -0
- data/lib/aidp/harness/ui/workflow_controller.rb +312 -0
- data/lib/aidp/harness/user_interface.rb +2381 -0
- data/lib/aidp/provider_manager.rb +131 -7
- data/lib/aidp/providers/anthropic.rb +28 -109
- data/lib/aidp/providers/base.rb +170 -0
- data/lib/aidp/providers/cursor.rb +52 -183
- data/lib/aidp/providers/gemini.rb +24 -109
- data/lib/aidp/providers/macos_ui.rb +99 -5
- data/lib/aidp/providers/opencode.rb +194 -0
- data/lib/aidp/storage/csv_storage.rb +172 -0
- data/lib/aidp/storage/file_manager.rb +214 -0
- data/lib/aidp/storage/json_storage.rb +140 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +56 -35
- data/templates/ANALYZE/06a_tree_sitter_scan.md +217 -0
- data/templates/COMMON/AGENT_BASE.md +11 -0
- data/templates/EXECUTE/00_PRD.md +4 -4
- data/templates/EXECUTE/02_ARCHITECTURE.md +5 -4
- data/templates/EXECUTE/07_TEST_PLAN.md +4 -1
- data/templates/EXECUTE/08_TASKS.md +4 -4
- data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +4 -4
- data/templates/README.md +279 -0
- data/templates/aidp-development.yml.example +373 -0
- data/templates/aidp-minimal.yml.example +48 -0
- data/templates/aidp-production.yml.example +475 -0
- data/templates/aidp.yml.example +598 -0
- metadata +106 -64
- data/lib/aidp/analyze/agent_personas.rb +0 -71
- data/lib/aidp/analyze/agent_tool_executor.rb +0 -445
- data/lib/aidp/analyze/data_retention_manager.rb +0 -426
- data/lib/aidp/analyze/database.rb +0 -260
- data/lib/aidp/analyze/dependencies.rb +0 -335
- data/lib/aidp/analyze/export_manager.rb +0 -425
- data/lib/aidp/analyze/focus_guidance.rb +0 -517
- data/lib/aidp/analyze/incremental_analyzer.rb +0 -543
- data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
- data/lib/aidp/analyze/large_analysis_progress.rb +0 -504
- data/lib/aidp/analyze/memory_manager.rb +0 -365
- data/lib/aidp/analyze/metrics_storage.rb +0 -336
- data/lib/aidp/analyze/parallel_processor.rb +0 -460
- data/lib/aidp/analyze/performance_optimizer.rb +0 -694
- data/lib/aidp/analyze/repository_chunker.rb +0 -704
- data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
- data/lib/aidp/analyze/storage.rb +0 -662
- data/lib/aidp/analyze/tool_configuration.rb +0 -456
- data/lib/aidp/analyze/tool_modernization.rb +0 -750
- data/lib/aidp/database/pg_adapter.rb +0 -148
- data/lib/aidp/database_config.rb +0 -69
- data/lib/aidp/database_connection.rb +0 -72
- data/lib/aidp/database_migration.rb +0 -158
- data/lib/aidp/job_manager.rb +0 -41
- data/lib/aidp/jobs/base_job.rb +0 -47
- data/lib/aidp/jobs/provider_execution_job.rb +0 -96
- data/lib/aidp/project_detector.rb +0 -117
- data/lib/aidp/providers/agent_supervisor.rb +0 -348
- data/lib/aidp/providers/supervised_base.rb +0 -317
- data/lib/aidp/providers/supervised_cursor.rb +0 -22
- data/lib/aidp/sync.rb +0 -13
- data/lib/aidp/workspace.rb +0 -19
@@ -1,750 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
module Aidp
|
6
|
-
class ToolModernization
|
7
|
-
# Define tool modernization mappings
|
8
|
-
TOOL_MODERNIZATION_MAP = {
|
9
|
-
"ruby" => {
|
10
|
-
"outdated_tools" => {
|
11
|
-
"ruby-lint" => {
|
12
|
-
name: "Ruby-Lint",
|
13
|
-
status: "deprecated",
|
14
|
-
reason: "No longer maintained, replaced by RuboCop",
|
15
|
-
modern_alternative: "rubocop",
|
16
|
-
migration_notes: "RuboCop provides better performance and more comprehensive analysis"
|
17
|
-
},
|
18
|
-
"flay" => {
|
19
|
-
name: "Flay",
|
20
|
-
status: "deprecated",
|
21
|
-
reason: "Limited maintenance, replaced by Reek",
|
22
|
-
modern_alternative: "reek",
|
23
|
-
migration_notes: "Reek provides better code smell detection and is actively maintained"
|
24
|
-
},
|
25
|
-
"flog" => {
|
26
|
-
name: "Flog",
|
27
|
-
status: "deprecated",
|
28
|
-
reason: "Limited maintenance, replaced by RuboCop complexity metrics",
|
29
|
-
modern_alternative: "rubocop",
|
30
|
-
migration_notes: "RuboCop includes complexity analysis and is more comprehensive"
|
31
|
-
}
|
32
|
-
},
|
33
|
-
"modern_tools" => {
|
34
|
-
"rubocop" => {
|
35
|
-
name: "RuboCop",
|
36
|
-
status: "active",
|
37
|
-
description: "Ruby static code analyzer and formatter",
|
38
|
-
features: %w[style quality complexity formatting],
|
39
|
-
version: "latest"
|
40
|
-
},
|
41
|
-
"reek" => {
|
42
|
-
name: "Reek",
|
43
|
-
status: "active",
|
44
|
-
description: "Code smell detector for Ruby",
|
45
|
-
features: %w[quality smells],
|
46
|
-
version: "latest"
|
47
|
-
},
|
48
|
-
"brakeman" => {
|
49
|
-
name: "Brakeman",
|
50
|
-
status: "active",
|
51
|
-
description: "Security vulnerability scanner for Ruby on Rails",
|
52
|
-
features: %w[security],
|
53
|
-
version: "latest"
|
54
|
-
}
|
55
|
-
}
|
56
|
-
},
|
57
|
-
"javascript" => {
|
58
|
-
"outdated_tools" => {
|
59
|
-
"jshint" => {
|
60
|
-
name: "JSHint",
|
61
|
-
status: "deprecated",
|
62
|
-
reason: "Limited maintenance, replaced by ESLint",
|
63
|
-
modern_alternative: "eslint",
|
64
|
-
migration_notes: "ESLint provides better configurability and plugin ecosystem"
|
65
|
-
},
|
66
|
-
"jslint" => {
|
67
|
-
name: "JSLint",
|
68
|
-
status: "deprecated",
|
69
|
-
reason: "Limited configurability, replaced by ESLint",
|
70
|
-
modern_alternative: "eslint",
|
71
|
-
migration_notes: "ESLint offers better customization and community support"
|
72
|
-
},
|
73
|
-
"coffeescript" => {
|
74
|
-
name: "CoffeeScript",
|
75
|
-
status: "deprecated",
|
76
|
-
reason: "Declining usage, replaced by modern JavaScript",
|
77
|
-
modern_alternative: "es6+",
|
78
|
-
migration_notes: "Modern JavaScript provides better tooling and ecosystem support"
|
79
|
-
}
|
80
|
-
},
|
81
|
-
"modern_tools" => {
|
82
|
-
"eslint" => {
|
83
|
-
name: "ESLint",
|
84
|
-
status: "active",
|
85
|
-
description: "JavaScript linting utility",
|
86
|
-
features: %w[style quality],
|
87
|
-
version: "latest"
|
88
|
-
},
|
89
|
-
"prettier" => {
|
90
|
-
name: "Prettier",
|
91
|
-
status: "active",
|
92
|
-
description: "Code formatter for JavaScript",
|
93
|
-
features: %w[style formatting],
|
94
|
-
version: "latest"
|
95
|
-
},
|
96
|
-
"typescript" => {
|
97
|
-
name: "TypeScript",
|
98
|
-
status: "active",
|
99
|
-
description: "Typed JavaScript",
|
100
|
-
features: %w[types safety],
|
101
|
-
version: "latest"
|
102
|
-
}
|
103
|
-
}
|
104
|
-
},
|
105
|
-
"python" => {
|
106
|
-
"outdated_tools" => {
|
107
|
-
"pep8" => {
|
108
|
-
name: "PEP8",
|
109
|
-
status: "deprecated",
|
110
|
-
reason: "Renamed to pycodestyle, replaced by flake8",
|
111
|
-
modern_alternative: "flake8",
|
112
|
-
migration_notes: "Flake8 includes PEP8 checking plus additional features"
|
113
|
-
},
|
114
|
-
"pylint1" => {
|
115
|
-
name: "Pylint 1.x",
|
116
|
-
status: "deprecated",
|
117
|
-
reason: "Old version, replaced by Pylint 2.x+",
|
118
|
-
modern_alternative: "pylint",
|
119
|
-
migration_notes: "Pylint 2.x+ provides better performance and Python 3 support"
|
120
|
-
}
|
121
|
-
},
|
122
|
-
"modern_tools" => {
|
123
|
-
"flake8" => {
|
124
|
-
name: "Flake8",
|
125
|
-
status: "active",
|
126
|
-
description: "Python linting utility",
|
127
|
-
features: %w[style quality],
|
128
|
-
version: "latest"
|
129
|
-
},
|
130
|
-
"black" => {
|
131
|
-
name: "Black",
|
132
|
-
status: "active",
|
133
|
-
description: "Uncompromising Python code formatter",
|
134
|
-
features: %w[style formatting],
|
135
|
-
version: "latest"
|
136
|
-
},
|
137
|
-
"mypy" => {
|
138
|
-
name: "MyPy",
|
139
|
-
status: "active",
|
140
|
-
description: "Static type checker for Python",
|
141
|
-
features: %w[types safety],
|
142
|
-
version: "latest"
|
143
|
-
}
|
144
|
-
}
|
145
|
-
},
|
146
|
-
"java" => {
|
147
|
-
"outdated_tools" => {
|
148
|
-
"findbugs" => {
|
149
|
-
name: "FindBugs",
|
150
|
-
status: "deprecated",
|
151
|
-
reason: "No longer maintained, replaced by SpotBugs",
|
152
|
-
modern_alternative: "spotbugs",
|
153
|
-
migration_notes: "SpotBugs is the active fork of FindBugs with Java 8+ support"
|
154
|
-
},
|
155
|
-
"pmd4" => {
|
156
|
-
name: "PMD 4.x",
|
157
|
-
status: "deprecated",
|
158
|
-
reason: "Old version, replaced by PMD 6.x+",
|
159
|
-
modern_alternative: "pmd",
|
160
|
-
migration_notes: "PMD 6.x+ provides better Java 8+ support and performance"
|
161
|
-
}
|
162
|
-
},
|
163
|
-
"modern_tools" => {
|
164
|
-
"spotbugs" => {
|
165
|
-
name: "SpotBugs",
|
166
|
-
status: "active",
|
167
|
-
description: "Java bug finder",
|
168
|
-
features: %w[quality bugs],
|
169
|
-
version: "latest"
|
170
|
-
},
|
171
|
-
"pmd" => {
|
172
|
-
name: "PMD",
|
173
|
-
status: "active",
|
174
|
-
description: "Java static code analyzer",
|
175
|
-
features: %w[quality],
|
176
|
-
version: "latest"
|
177
|
-
},
|
178
|
-
"checkstyle" => {
|
179
|
-
name: "Checkstyle",
|
180
|
-
status: "active",
|
181
|
-
description: "Java code style checker",
|
182
|
-
features: %w[style],
|
183
|
-
version: "latest"
|
184
|
-
}
|
185
|
-
}
|
186
|
-
}
|
187
|
-
}.freeze
|
188
|
-
|
189
|
-
def initialize(project_dir = Dir.pwd)
|
190
|
-
@project_dir = project_dir
|
191
|
-
end
|
192
|
-
|
193
|
-
# Detect outdated tools in the project
|
194
|
-
def detect_outdated_tools(language)
|
195
|
-
outdated_tools = []
|
196
|
-
|
197
|
-
language_map = TOOL_MODERNIZATION_MAP[language]
|
198
|
-
return outdated_tools unless language_map
|
199
|
-
|
200
|
-
outdated_definitions = language_map["outdated_tools"] || {}
|
201
|
-
|
202
|
-
outdated_definitions.each do |tool_id, tool_info|
|
203
|
-
next unless tool_detected?(tool_id, language)
|
204
|
-
|
205
|
-
outdated_tools << {
|
206
|
-
id: tool_id,
|
207
|
-
name: tool_info[:name],
|
208
|
-
status: tool_info[:status],
|
209
|
-
reason: tool_info[:reason],
|
210
|
-
modern_alternative: tool_info[:modern_alternative],
|
211
|
-
migration_notes: tool_info[:migration_notes],
|
212
|
-
detected_in: detect_tool_location(tool_id, language)
|
213
|
-
}
|
214
|
-
end
|
215
|
-
|
216
|
-
outdated_tools
|
217
|
-
end
|
218
|
-
|
219
|
-
# Generate modernization recommendations
|
220
|
-
def generate_modernization_recommendations(language)
|
221
|
-
recommendations = []
|
222
|
-
|
223
|
-
outdated_tools = detect_outdated_tools(language)
|
224
|
-
|
225
|
-
outdated_tools.each do |tool|
|
226
|
-
recommendation = {
|
227
|
-
type: "tool_modernization",
|
228
|
-
tool: tool[:name],
|
229
|
-
status: tool[:status],
|
230
|
-
reason: tool[:reason],
|
231
|
-
modern_alternative: tool[:modern_alternative],
|
232
|
-
migration_notes: tool[:migration_notes],
|
233
|
-
priority: determine_migration_priority(tool),
|
234
|
-
migration_steps: generate_migration_steps(tool, language),
|
235
|
-
benefits: generate_migration_benefits(tool)
|
236
|
-
}
|
237
|
-
|
238
|
-
recommendations << recommendation
|
239
|
-
end
|
240
|
-
|
241
|
-
# Add general modernization recommendations
|
242
|
-
recommendations.concat(generate_general_modernization_recommendations(language))
|
243
|
-
|
244
|
-
recommendations
|
245
|
-
end
|
246
|
-
|
247
|
-
# Get modern tool recommendations for a language
|
248
|
-
def get_modern_tool_recommendations(language)
|
249
|
-
language_map = TOOL_MODERNIZATION_MAP[language]
|
250
|
-
return [] unless language_map
|
251
|
-
|
252
|
-
modern_tools = language_map["modern_tools"] || {}
|
253
|
-
modern_tools.map do |tool_id, tool_info|
|
254
|
-
{
|
255
|
-
id: tool_id,
|
256
|
-
name: tool_info[:name],
|
257
|
-
status: tool_info[:status],
|
258
|
-
description: tool_info[:description],
|
259
|
-
features: tool_info[:features],
|
260
|
-
version: tool_info[:version],
|
261
|
-
installation_guide: generate_installation_guide(tool_id, language)
|
262
|
-
}
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
# Generate migration plan for outdated tools
|
267
|
-
def generate_migration_plan(language)
|
268
|
-
outdated_tools = detect_outdated_tools(language)
|
269
|
-
|
270
|
-
return {message: "No outdated tools detected"} if outdated_tools.empty?
|
271
|
-
|
272
|
-
plan = {
|
273
|
-
language: language,
|
274
|
-
outdated_tools: outdated_tools,
|
275
|
-
migration_phases: [],
|
276
|
-
timeline: estimate_migration_timeline(outdated_tools),
|
277
|
-
risks: identify_migration_risks(outdated_tools),
|
278
|
-
benefits: calculate_migration_benefits(outdated_tools)
|
279
|
-
}
|
280
|
-
|
281
|
-
# Generate migration phases
|
282
|
-
plan[:migration_phases] = generate_migration_phases(outdated_tools, language)
|
283
|
-
|
284
|
-
plan
|
285
|
-
end
|
286
|
-
|
287
|
-
# Check if a specific tool is outdated
|
288
|
-
def tool_outdated?(tool_id, language)
|
289
|
-
language_map = TOOL_MODERNIZATION_MAP[language]
|
290
|
-
return false unless language_map
|
291
|
-
|
292
|
-
outdated_tools = language_map["outdated_tools"] || {}
|
293
|
-
outdated_tools.key?(tool_id)
|
294
|
-
end
|
295
|
-
|
296
|
-
# Get modern alternative for an outdated tool
|
297
|
-
def get_modern_alternative(tool_id, language)
|
298
|
-
language_map = TOOL_MODERNIZATION_MAP[language]
|
299
|
-
return nil unless language_map
|
300
|
-
|
301
|
-
outdated_tools = language_map["outdated_tools"] || {}
|
302
|
-
outdated_tools.dig(tool_id, :modern_alternative)
|
303
|
-
end
|
304
|
-
|
305
|
-
private
|
306
|
-
|
307
|
-
def tool_detected?(tool_id, language)
|
308
|
-
case language
|
309
|
-
when "ruby"
|
310
|
-
detect_ruby_tool(tool_id)
|
311
|
-
when "javascript"
|
312
|
-
detect_javascript_tool(tool_id)
|
313
|
-
when "python"
|
314
|
-
detect_python_tool(tool_id)
|
315
|
-
when "java"
|
316
|
-
detect_java_tool(tool_id)
|
317
|
-
else
|
318
|
-
false
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
def detect_ruby_tool(tool_id)
|
323
|
-
case tool_id
|
324
|
-
when "ruby-lint"
|
325
|
-
# Check for ruby-lint gem in Gemfile
|
326
|
-
gemfile_path = File.join(@project_dir, "Gemfile")
|
327
|
-
return false unless File.exist?(gemfile_path)
|
328
|
-
|
329
|
-
gemfile_content = File.read(gemfile_path)
|
330
|
-
gemfile_content.include?("gem 'ruby-lint'") || gemfile_content.include?('gem "ruby-lint"')
|
331
|
-
when "flay"
|
332
|
-
# Check for flay gem in Gemfile
|
333
|
-
gemfile_path = File.join(@project_dir, "Gemfile")
|
334
|
-
return false unless File.exist?(gemfile_path)
|
335
|
-
|
336
|
-
gemfile_content = File.read(gemfile_path)
|
337
|
-
gemfile_content.include?("gem 'flay'") || gemfile_content.include?('gem "flay"')
|
338
|
-
when "flog"
|
339
|
-
# Check for flog gem in Gemfile
|
340
|
-
gemfile_path = File.join(@project_dir, "Gemfile")
|
341
|
-
return false unless File.exist?(gemfile_path)
|
342
|
-
|
343
|
-
gemfile_content = File.read(gemfile_path)
|
344
|
-
gemfile_content.include?("gem 'flog'") || gemfile_content.include?('gem "flog"')
|
345
|
-
else
|
346
|
-
false
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
def detect_javascript_tool(tool_id)
|
351
|
-
case tool_id
|
352
|
-
when "jshint"
|
353
|
-
# Check for jshint in package.json
|
354
|
-
package_json_path = File.join(@project_dir, "package.json")
|
355
|
-
return false unless File.exist?(package_json_path)
|
356
|
-
|
357
|
-
package_json_content = File.read(package_json_path)
|
358
|
-
package_json_content.include?('"jshint"')
|
359
|
-
when "jslint"
|
360
|
-
# Check for jslint in package.json
|
361
|
-
package_json_path = File.join(@project_dir, "package.json")
|
362
|
-
return false unless File.exist?(package_json_path)
|
363
|
-
|
364
|
-
package_json_content = File.read(package_json_path)
|
365
|
-
package_json_content.include?('"jslint"')
|
366
|
-
when "coffeescript"
|
367
|
-
# Check for coffeescript files or package
|
368
|
-
coffee_files = Dir.glob(File.join(@project_dir, "**", "*.coffee"))
|
369
|
-
return true if coffee_files.any?
|
370
|
-
|
371
|
-
package_json_path = File.join(@project_dir, "package.json")
|
372
|
-
if File.exist?(package_json_path)
|
373
|
-
package_json_content = File.read(package_json_path)
|
374
|
-
package_json_content.include?('"coffeescript"')
|
375
|
-
else
|
376
|
-
false
|
377
|
-
end
|
378
|
-
else
|
379
|
-
false
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
def detect_python_tool(tool_id)
|
384
|
-
case tool_id
|
385
|
-
when "pep8"
|
386
|
-
# Check for pep8 in requirements or setup
|
387
|
-
requirements_files = ["requirements.txt", "setup.py", "pyproject.toml"]
|
388
|
-
requirements_files.each do |file|
|
389
|
-
file_path = File.join(@project_dir, file)
|
390
|
-
next unless File.exist?(file_path)
|
391
|
-
|
392
|
-
content = File.read(file_path)
|
393
|
-
return true if content.include?("pep8")
|
394
|
-
end
|
395
|
-
when "pylint1"
|
396
|
-
# Check for old pylint version
|
397
|
-
requirements_files = ["requirements.txt", "setup.py", "pyproject.toml"]
|
398
|
-
requirements_files.each do |file|
|
399
|
-
file_path = File.join(@project_dir, file)
|
400
|
-
next unless File.exist?(file_path)
|
401
|
-
|
402
|
-
content = File.read(file_path)
|
403
|
-
return true if /pylint[<>=]?\s*1\./.match?(content)
|
404
|
-
end
|
405
|
-
end
|
406
|
-
false
|
407
|
-
end
|
408
|
-
|
409
|
-
def detect_java_tool(tool_id)
|
410
|
-
case tool_id
|
411
|
-
when "findbugs"
|
412
|
-
# Check for findbugs in build files
|
413
|
-
build_files = ["pom.xml", "build.gradle", "build.gradle.kts"]
|
414
|
-
build_files.each do |file|
|
415
|
-
file_path = File.join(@project_dir, file)
|
416
|
-
next unless File.exist?(file_path)
|
417
|
-
|
418
|
-
content = File.read(file_path)
|
419
|
-
return true if content.include?("findbugs")
|
420
|
-
end
|
421
|
-
when "pmd4"
|
422
|
-
# Check for old PMD version
|
423
|
-
build_files = ["pom.xml", "build.gradle", "build.gradle.kts"]
|
424
|
-
build_files.each do |file|
|
425
|
-
file_path = File.join(@project_dir, file)
|
426
|
-
next unless File.exist?(file_path)
|
427
|
-
|
428
|
-
content = File.read(file_path)
|
429
|
-
return true if /pmd[<>=]?\s*4\./.match?(content)
|
430
|
-
end
|
431
|
-
end
|
432
|
-
false
|
433
|
-
end
|
434
|
-
|
435
|
-
def detect_tool_location(tool_id, language)
|
436
|
-
locations = []
|
437
|
-
|
438
|
-
case language
|
439
|
-
when "ruby"
|
440
|
-
gemfile_path = File.join(@project_dir, "Gemfile")
|
441
|
-
locations << "Gemfile" if File.exist?(gemfile_path)
|
442
|
-
when "javascript"
|
443
|
-
package_json_path = File.join(@project_dir, "package.json")
|
444
|
-
locations << "package.json" if File.exist?(package_json_path)
|
445
|
-
when "python"
|
446
|
-
["requirements.txt", "setup.py", "pyproject.toml"].each do |file|
|
447
|
-
locations << file if File.exist?(File.join(@project_dir, file))
|
448
|
-
end
|
449
|
-
when "java"
|
450
|
-
["pom.xml", "build.gradle", "build.gradle.kts"].each do |file|
|
451
|
-
locations << file if File.exist?(File.join(@project_dir, file))
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
locations
|
456
|
-
end
|
457
|
-
|
458
|
-
def determine_migration_priority(tool)
|
459
|
-
case tool[:status]
|
460
|
-
when "deprecated"
|
461
|
-
"high"
|
462
|
-
when "limited"
|
463
|
-
"medium"
|
464
|
-
else
|
465
|
-
"low"
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
def generate_migration_steps(tool, language)
|
470
|
-
case language
|
471
|
-
when "ruby"
|
472
|
-
generate_ruby_migration_steps(tool)
|
473
|
-
when "javascript"
|
474
|
-
generate_javascript_migration_steps(tool)
|
475
|
-
when "python"
|
476
|
-
generate_python_migration_steps(tool)
|
477
|
-
when "java"
|
478
|
-
generate_java_migration_steps(tool)
|
479
|
-
else
|
480
|
-
["Consult documentation for migration steps"]
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
def generate_ruby_migration_steps(tool)
|
485
|
-
case tool[:id]
|
486
|
-
when "ruby-lint"
|
487
|
-
[
|
488
|
-
"Remove ruby-lint gem from Gemfile",
|
489
|
-
"Add rubocop gem to Gemfile",
|
490
|
-
"Run bundle install",
|
491
|
-
"Initialize RuboCop configuration: bundle exec rubocop --auto-gen-config",
|
492
|
-
"Update CI/CD pipeline to use RuboCop",
|
493
|
-
"Remove ruby-lint configuration files"
|
494
|
-
]
|
495
|
-
when "flay"
|
496
|
-
[
|
497
|
-
"Remove flay gem from Gemfile",
|
498
|
-
"Add reek gem to Gemfile",
|
499
|
-
"Run bundle install",
|
500
|
-
"Initialize Reek configuration: bundle exec reek --init",
|
501
|
-
"Update CI/CD pipeline to use Reek",
|
502
|
-
"Remove flay configuration files"
|
503
|
-
]
|
504
|
-
else
|
505
|
-
["Remove outdated tool", "Install modern alternative", "Update configuration"]
|
506
|
-
end
|
507
|
-
end
|
508
|
-
|
509
|
-
def generate_javascript_migration_steps(tool)
|
510
|
-
case tool[:id]
|
511
|
-
when "jshint"
|
512
|
-
[
|
513
|
-
"Remove jshint from package.json",
|
514
|
-
"Install ESLint: npm install --save-dev eslint",
|
515
|
-
"Initialize ESLint configuration: npx eslint --init",
|
516
|
-
"Update .eslintrc to match JSHint rules",
|
517
|
-
"Update CI/CD pipeline to use ESLint",
|
518
|
-
"Remove .jshintrc configuration file"
|
519
|
-
]
|
520
|
-
when "coffeescript"
|
521
|
-
[
|
522
|
-
"Convert .coffee files to .js files",
|
523
|
-
"Update import/require statements",
|
524
|
-
"Remove coffeescript dependency",
|
525
|
-
"Update build scripts to handle .js files",
|
526
|
-
"Update CI/CD pipeline",
|
527
|
-
"Test converted code thoroughly"
|
528
|
-
]
|
529
|
-
else
|
530
|
-
["Remove outdated tool", "Install modern alternative", "Update configuration"]
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
def generate_python_migration_steps(tool)
|
535
|
-
case tool[:id]
|
536
|
-
when "pep8"
|
537
|
-
[
|
538
|
-
"Remove pep8 from requirements",
|
539
|
-
"Install flake8: pip install flake8",
|
540
|
-
"Create .flake8 configuration file",
|
541
|
-
"Update CI/CD pipeline to use flake8",
|
542
|
-
"Remove pep8 configuration files"
|
543
|
-
]
|
544
|
-
when "pylint1"
|
545
|
-
[
|
546
|
-
"Update pylint to latest version",
|
547
|
-
"Update requirements.txt or setup.py",
|
548
|
-
"Review and update pylint configuration",
|
549
|
-
"Test with new pylint version",
|
550
|
-
"Update CI/CD pipeline if needed"
|
551
|
-
]
|
552
|
-
else
|
553
|
-
["Remove outdated tool", "Install modern alternative", "Update configuration"]
|
554
|
-
end
|
555
|
-
end
|
556
|
-
|
557
|
-
def generate_java_migration_steps(tool)
|
558
|
-
case tool[:id]
|
559
|
-
when "findbugs"
|
560
|
-
[
|
561
|
-
"Remove findbugs from build configuration",
|
562
|
-
"Add spotbugs to build configuration",
|
563
|
-
"Update build scripts and CI/CD pipeline",
|
564
|
-
"Review and update configuration files",
|
565
|
-
"Test with spotbugs"
|
566
|
-
]
|
567
|
-
when "pmd4"
|
568
|
-
[
|
569
|
-
"Update PMD to latest version",
|
570
|
-
"Update build configuration",
|
571
|
-
"Review and update PMD rules",
|
572
|
-
"Test with new PMD version",
|
573
|
-
"Update CI/CD pipeline if needed"
|
574
|
-
]
|
575
|
-
else
|
576
|
-
["Remove outdated tool", "Install modern alternative", "Update configuration"]
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
def generate_migration_benefits(tool)
|
581
|
-
benefits = []
|
582
|
-
|
583
|
-
case tool[:modern_alternative]
|
584
|
-
when "rubocop"
|
585
|
-
benefits.concat(["Better performance", "More comprehensive analysis", "Active maintenance", "Large community"])
|
586
|
-
when "eslint"
|
587
|
-
benefits.concat(["Better configurability", "Plugin ecosystem", "Active maintenance", "TypeScript support"])
|
588
|
-
when "flake8"
|
589
|
-
benefits.concat(["Includes PEP8 checking", "Additional features", "Better Python 3 support",
|
590
|
-
"Active maintenance"])
|
591
|
-
when "spotbugs"
|
592
|
-
benefits.concat(["Java 8+ support", "Active maintenance", "Better performance", "Modern Java features"])
|
593
|
-
end
|
594
|
-
|
595
|
-
benefits
|
596
|
-
end
|
597
|
-
|
598
|
-
def generate_general_modernization_recommendations(language)
|
599
|
-
recommendations = []
|
600
|
-
|
601
|
-
case language
|
602
|
-
when "ruby"
|
603
|
-
recommendations << {
|
604
|
-
type: "general_modernization",
|
605
|
-
title: "Ruby Tool Modernization",
|
606
|
-
description: "Consider modernizing your Ruby development tools",
|
607
|
-
recommendations: [
|
608
|
-
"Use RuboCop for code style and quality",
|
609
|
-
"Use Reek for code smell detection",
|
610
|
-
"Use Brakeman for security scanning",
|
611
|
-
"Consider using Bundler for dependency management",
|
612
|
-
"Use RSpec for testing"
|
613
|
-
]
|
614
|
-
}
|
615
|
-
when "javascript"
|
616
|
-
recommendations << {
|
617
|
-
type: "general_modernization",
|
618
|
-
title: "JavaScript Tool Modernization",
|
619
|
-
description: "Consider modernizing your JavaScript development tools",
|
620
|
-
recommendations: [
|
621
|
-
"Use ESLint for linting",
|
622
|
-
"Use Prettier for code formatting",
|
623
|
-
"Consider TypeScript for type safety",
|
624
|
-
"Use modern JavaScript features (ES6+)",
|
625
|
-
"Use Jest for testing"
|
626
|
-
]
|
627
|
-
}
|
628
|
-
end
|
629
|
-
|
630
|
-
recommendations
|
631
|
-
end
|
632
|
-
|
633
|
-
def estimate_migration_timeline(outdated_tools)
|
634
|
-
total_effort = outdated_tools.sum { |tool| get_migration_effort(tool) }
|
635
|
-
|
636
|
-
case total_effort
|
637
|
-
when 0..2
|
638
|
-
"1-2 days"
|
639
|
-
when 3..5
|
640
|
-
"3-5 days"
|
641
|
-
when 6..10
|
642
|
-
"1-2 weeks"
|
643
|
-
else
|
644
|
-
"2+ weeks"
|
645
|
-
end
|
646
|
-
end
|
647
|
-
|
648
|
-
def get_migration_effort(tool)
|
649
|
-
case tool[:id]
|
650
|
-
when "coffeescript"
|
651
|
-
5 # High effort - requires code conversion
|
652
|
-
when "ruby-lint", "jshint", "pep8"
|
653
|
-
2 # Medium effort - configuration changes
|
654
|
-
else
|
655
|
-
1 # Low effort - simple replacement
|
656
|
-
end
|
657
|
-
end
|
658
|
-
|
659
|
-
def identify_migration_risks(outdated_tools)
|
660
|
-
risks = []
|
661
|
-
|
662
|
-
outdated_tools.each do |tool|
|
663
|
-
case tool[:id]
|
664
|
-
when "coffeescript"
|
665
|
-
risks << "Code conversion may introduce bugs"
|
666
|
-
when "ruby-lint"
|
667
|
-
risks << "Different rule sets may require code changes"
|
668
|
-
when "jshint"
|
669
|
-
risks << "ESLint may have different default rules"
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
|
-
risks
|
674
|
-
end
|
675
|
-
|
676
|
-
def calculate_migration_benefits(outdated_tools)
|
677
|
-
benefits = []
|
678
|
-
|
679
|
-
outdated_tools.each do |tool|
|
680
|
-
benefits.concat(generate_migration_benefits(tool))
|
681
|
-
end
|
682
|
-
|
683
|
-
benefits.uniq
|
684
|
-
end
|
685
|
-
|
686
|
-
def generate_migration_phases(outdated_tools, language)
|
687
|
-
phases = []
|
688
|
-
|
689
|
-
# Phase 1: Low-risk migrations
|
690
|
-
low_risk_tools = outdated_tools.select { |tool| get_migration_effort(tool) <= 2 }
|
691
|
-
if low_risk_tools.any?
|
692
|
-
phases << {
|
693
|
-
phase: 1,
|
694
|
-
name: "Low-Risk Tool Migration",
|
695
|
-
tools: low_risk_tools,
|
696
|
-
duration: "1-3 days",
|
697
|
-
risk: "low"
|
698
|
-
}
|
699
|
-
end
|
700
|
-
|
701
|
-
# Phase 2: High-risk migrations
|
702
|
-
high_risk_tools = outdated_tools.select { |tool| get_migration_effort(tool) > 2 }
|
703
|
-
if high_risk_tools.any?
|
704
|
-
phases << {
|
705
|
-
phase: 2,
|
706
|
-
name: "High-Risk Tool Migration",
|
707
|
-
tools: high_risk_tools,
|
708
|
-
duration: "1-2 weeks",
|
709
|
-
risk: "high"
|
710
|
-
}
|
711
|
-
end
|
712
|
-
|
713
|
-
phases
|
714
|
-
end
|
715
|
-
|
716
|
-
def generate_installation_guide(tool_id, language)
|
717
|
-
case language
|
718
|
-
when "ruby"
|
719
|
-
case tool_id
|
720
|
-
when "rubocop"
|
721
|
-
"Add 'gem \"rubocop\"' to Gemfile and run bundle install"
|
722
|
-
when "reek"
|
723
|
-
"Add 'gem \"reek\"' to Gemfile and run bundle install"
|
724
|
-
when "brakeman"
|
725
|
-
"Add 'gem \"brakeman\"' to Gemfile and run bundle install"
|
726
|
-
end
|
727
|
-
when "javascript"
|
728
|
-
case tool_id
|
729
|
-
when "eslint"
|
730
|
-
"npm install --save-dev eslint"
|
731
|
-
when "prettier"
|
732
|
-
"npm install --save-dev prettier"
|
733
|
-
when "typescript"
|
734
|
-
"npm install --save-dev typescript"
|
735
|
-
end
|
736
|
-
when "python"
|
737
|
-
case tool_id
|
738
|
-
when "flake8"
|
739
|
-
"pip install flake8"
|
740
|
-
when "black"
|
741
|
-
"pip install black"
|
742
|
-
when "mypy"
|
743
|
-
"pip install mypy"
|
744
|
-
end
|
745
|
-
else
|
746
|
-
"Consult tool documentation for installation instructions"
|
747
|
-
end
|
748
|
-
end
|
749
|
-
end
|
750
|
-
end
|