aidp 0.7.0 → 0.8.1

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -214
  3. data/bin/aidp +1 -1
  4. data/lib/aidp/analysis/kb_inspector.rb +38 -23
  5. data/lib/aidp/analysis/seams.rb +2 -31
  6. data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +1 -13
  7. data/lib/aidp/analysis/tree_sitter_scan.rb +3 -20
  8. data/lib/aidp/analyze/error_handler.rb +2 -75
  9. data/lib/aidp/analyze/json_file_storage.rb +292 -0
  10. data/lib/aidp/analyze/progress.rb +12 -0
  11. data/lib/aidp/analyze/progress_visualizer.rb +12 -17
  12. data/lib/aidp/analyze/ruby_maat_integration.rb +13 -31
  13. data/lib/aidp/analyze/runner.rb +256 -87
  14. data/lib/aidp/cli/jobs_command.rb +100 -432
  15. data/lib/aidp/cli.rb +309 -239
  16. data/lib/aidp/config.rb +298 -10
  17. data/lib/aidp/debug_logger.rb +195 -0
  18. data/lib/aidp/debug_mixin.rb +187 -0
  19. data/lib/aidp/execute/progress.rb +9 -0
  20. data/lib/aidp/execute/runner.rb +221 -40
  21. data/lib/aidp/execute/steps.rb +17 -7
  22. data/lib/aidp/execute/workflow_selector.rb +211 -0
  23. data/lib/aidp/harness/completion_checker.rb +268 -0
  24. data/lib/aidp/harness/condition_detector.rb +1526 -0
  25. data/lib/aidp/harness/config_loader.rb +373 -0
  26. data/lib/aidp/harness/config_manager.rb +382 -0
  27. data/lib/aidp/harness/config_schema.rb +1006 -0
  28. data/lib/aidp/harness/config_validator.rb +355 -0
  29. data/lib/aidp/harness/configuration.rb +477 -0
  30. data/lib/aidp/harness/enhanced_runner.rb +494 -0
  31. data/lib/aidp/harness/error_handler.rb +616 -0
  32. data/lib/aidp/harness/provider_config.rb +423 -0
  33. data/lib/aidp/harness/provider_factory.rb +306 -0
  34. data/lib/aidp/harness/provider_manager.rb +1269 -0
  35. data/lib/aidp/harness/provider_type_checker.rb +88 -0
  36. data/lib/aidp/harness/runner.rb +411 -0
  37. data/lib/aidp/harness/state/errors.rb +28 -0
  38. data/lib/aidp/harness/state/metrics.rb +219 -0
  39. data/lib/aidp/harness/state/persistence.rb +128 -0
  40. data/lib/aidp/harness/state/provider_state.rb +132 -0
  41. data/lib/aidp/harness/state/ui_state.rb +68 -0
  42. data/lib/aidp/harness/state/workflow_state.rb +123 -0
  43. data/lib/aidp/harness/state_manager.rb +586 -0
  44. data/lib/aidp/harness/status_display.rb +888 -0
  45. data/lib/aidp/harness/ui/base.rb +16 -0
  46. data/lib/aidp/harness/ui/enhanced_tui.rb +545 -0
  47. data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +252 -0
  48. data/lib/aidp/harness/ui/error_handler.rb +132 -0
  49. data/lib/aidp/harness/ui/frame_manager.rb +361 -0
  50. data/lib/aidp/harness/ui/job_monitor.rb +500 -0
  51. data/lib/aidp/harness/ui/navigation/main_menu.rb +311 -0
  52. data/lib/aidp/harness/ui/navigation/menu_formatter.rb +120 -0
  53. data/lib/aidp/harness/ui/navigation/menu_item.rb +142 -0
  54. data/lib/aidp/harness/ui/navigation/menu_state.rb +139 -0
  55. data/lib/aidp/harness/ui/navigation/submenu.rb +202 -0
  56. data/lib/aidp/harness/ui/navigation/workflow_selector.rb +176 -0
  57. data/lib/aidp/harness/ui/progress_display.rb +280 -0
  58. data/lib/aidp/harness/ui/question_collector.rb +141 -0
  59. data/lib/aidp/harness/ui/spinner_group.rb +184 -0
  60. data/lib/aidp/harness/ui/spinner_helper.rb +152 -0
  61. data/lib/aidp/harness/ui/status_manager.rb +312 -0
  62. data/lib/aidp/harness/ui/status_widget.rb +280 -0
  63. data/lib/aidp/harness/ui/workflow_controller.rb +312 -0
  64. data/lib/aidp/harness/user_interface.rb +2381 -0
  65. data/lib/aidp/provider_manager.rb +131 -7
  66. data/lib/aidp/providers/anthropic.rb +28 -103
  67. data/lib/aidp/providers/base.rb +170 -0
  68. data/lib/aidp/providers/cursor.rb +52 -181
  69. data/lib/aidp/providers/gemini.rb +24 -107
  70. data/lib/aidp/providers/macos_ui.rb +99 -5
  71. data/lib/aidp/providers/opencode.rb +194 -0
  72. data/lib/aidp/storage/csv_storage.rb +172 -0
  73. data/lib/aidp/storage/file_manager.rb +214 -0
  74. data/lib/aidp/storage/json_storage.rb +140 -0
  75. data/lib/aidp/version.rb +1 -1
  76. data/lib/aidp.rb +54 -39
  77. data/templates/COMMON/AGENT_BASE.md +11 -0
  78. data/templates/EXECUTE/00_PRD.md +4 -4
  79. data/templates/EXECUTE/02_ARCHITECTURE.md +5 -4
  80. data/templates/EXECUTE/07_TEST_PLAN.md +4 -1
  81. data/templates/EXECUTE/08_TASKS.md +4 -4
  82. data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +4 -4
  83. data/templates/README.md +279 -0
  84. data/templates/aidp-development.yml.example +373 -0
  85. data/templates/aidp-minimal.yml.example +48 -0
  86. data/templates/aidp-production.yml.example +475 -0
  87. data/templates/aidp.yml.example +598 -0
  88. metadata +93 -69
  89. data/lib/aidp/analyze/agent_personas.rb +0 -71
  90. data/lib/aidp/analyze/agent_tool_executor.rb +0 -439
  91. data/lib/aidp/analyze/data_retention_manager.rb +0 -421
  92. data/lib/aidp/analyze/database.rb +0 -260
  93. data/lib/aidp/analyze/dependencies.rb +0 -335
  94. data/lib/aidp/analyze/export_manager.rb +0 -418
  95. data/lib/aidp/analyze/focus_guidance.rb +0 -517
  96. data/lib/aidp/analyze/incremental_analyzer.rb +0 -533
  97. data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
  98. data/lib/aidp/analyze/large_analysis_progress.rb +0 -499
  99. data/lib/aidp/analyze/memory_manager.rb +0 -339
  100. data/lib/aidp/analyze/metrics_storage.rb +0 -336
  101. data/lib/aidp/analyze/parallel_processor.rb +0 -454
  102. data/lib/aidp/analyze/performance_optimizer.rb +0 -691
  103. data/lib/aidp/analyze/repository_chunker.rb +0 -697
  104. data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
  105. data/lib/aidp/analyze/storage.rb +0 -655
  106. data/lib/aidp/analyze/tool_configuration.rb +0 -441
  107. data/lib/aidp/analyze/tool_modernization.rb +0 -750
  108. data/lib/aidp/database/pg_adapter.rb +0 -148
  109. data/lib/aidp/database_config.rb +0 -69
  110. data/lib/aidp/database_connection.rb +0 -72
  111. data/lib/aidp/job_manager.rb +0 -41
  112. data/lib/aidp/jobs/base_job.rb +0 -45
  113. data/lib/aidp/jobs/provider_execution_job.rb +0 -83
  114. data/lib/aidp/project_detector.rb +0 -117
  115. data/lib/aidp/providers/agent_supervisor.rb +0 -348
  116. data/lib/aidp/providers/supervised_base.rb +0 -317
  117. data/lib/aidp/providers/supervised_cursor.rb +0 -22
  118. data/lib/aidp/sync.rb +0 -13
  119. data/lib/aidp/workspace.rb +0 -19
@@ -1,148 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Aidp
4
- module Database
5
- class PgAdapter
6
- def initialize(connection)
7
- @connection = connection
8
- end
9
-
10
- def execute(sql, params = [])
11
- result = @connection.exec_params(sql, params)
12
- result.to_a.map { |row| row.transform_keys(&:to_sym) }
13
- end
14
-
15
- def in_transaction?
16
- @connection.transaction_status != PG::PQTRANS_IDLE
17
- end
18
-
19
- def checkout
20
- yield self
21
- end
22
-
23
- def after_commit
24
- yield
25
- end
26
-
27
- def server_version
28
- @connection.server_version
29
- end
30
-
31
- def transaction_status
32
- @connection.transaction_status
33
- end
34
-
35
- def transaction
36
- @connection.transaction do
37
- yield
38
- end
39
- end
40
-
41
- def quote_table_name(name)
42
- "\"#{name}\""
43
- end
44
-
45
- def quote_identifier(name)
46
- "\"#{name}\""
47
- end
48
-
49
- def quote_string(string)
50
- "'#{string.gsub("'", "''")}'"
51
- end
52
-
53
- def quote_date(date)
54
- date.strftime("%Y-%m-%d")
55
- end
56
-
57
- def quote_time(time)
58
- time.strftime("%Y-%m-%d %H:%M:%S.%6N %z")
59
- end
60
-
61
- # Additional methods required by Que
62
- def async_connection
63
- self
64
- end
65
-
66
- def wait_for_notify(timeout = nil)
67
- @connection.wait_for_notify(timeout)
68
- end
69
-
70
- def listen(channel)
71
- @connection.exec("LISTEN #{quote_identifier(channel)}")
72
- end
73
-
74
- def unlisten(channel)
75
- @connection.exec("UNLISTEN #{quote_identifier(channel)}")
76
- end
77
-
78
- def unlisten_all
79
- @connection.exec("UNLISTEN *")
80
- end
81
-
82
- def notifications
83
- @connection.notifications
84
- end
85
-
86
- def reset
87
- @connection.reset
88
- end
89
-
90
- def type_map_for_queries
91
- @connection.type_map_for_queries
92
- end
93
-
94
- def type_map_for_results
95
- @connection.type_map_for_results
96
- end
97
-
98
- # Additional methods for Que compatibility
99
- def adapter_name
100
- "pg"
101
- end
102
-
103
- def active?
104
- @connection.status == PG::CONNECTION_OK
105
- end
106
-
107
- def disconnect!
108
- @connection.close
109
- end
110
-
111
- def reconnect!
112
- @connection.reset
113
- end
114
-
115
- def raw_connection
116
- @connection
117
- end
118
-
119
- def schema_search_path
120
- execute("SHOW search_path")[0][:search_path]
121
- end
122
-
123
- def schema_search_path=(path)
124
- execute("SET search_path TO #{path}")
125
- end
126
-
127
- def table_exists?(name)
128
- execute(<<~SQL, [name]).any?
129
- SELECT 1
130
- FROM pg_tables
131
- WHERE tablename = $1
132
- SQL
133
- end
134
-
135
- def advisory_lock(id)
136
- execute("SELECT pg_advisory_lock($1)", [id])
137
- end
138
-
139
- def advisory_unlock(id)
140
- execute("SELECT pg_advisory_unlock($1)", [id])
141
- end
142
-
143
- def advisory_unlock_all
144
- execute("SELECT pg_advisory_unlock_all()")
145
- end
146
- end
147
- end
148
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yaml"
4
- require "fileutils"
5
-
6
- module Aidp
7
- class DatabaseConfig
8
- DEFAULT_CONFIG = {
9
- "database" => {
10
- "adapter" => "postgresql",
11
- "host" => "localhost",
12
- "port" => 5432,
13
- "database" => "aidp",
14
- "username" => ENV["USER"],
15
- "password" => nil,
16
- "pool" => 5,
17
- "timeout" => 5000
18
- }
19
- }.freeze
20
-
21
- def self.load(project_dir = Dir.pwd)
22
- new(project_dir).load
23
- end
24
-
25
- def initialize(project_dir)
26
- @project_dir = project_dir
27
- @config_file = File.join(project_dir, ".aidp-config.yml")
28
- end
29
-
30
- def load
31
- ensure_config_exists
32
- config = YAML.load_file(@config_file)
33
- validate_config(config)
34
- config["database"]
35
- end
36
-
37
- private
38
-
39
- def ensure_config_exists
40
- return if File.exist?(@config_file)
41
-
42
- # Create config directory if it doesn't exist
43
- FileUtils.mkdir_p(File.dirname(@config_file))
44
-
45
- # Write default config
46
- File.write(@config_file, YAML.dump(DEFAULT_CONFIG))
47
-
48
- puts "Created default database configuration at #{@config_file}"
49
- puts "Please update the configuration with your database settings"
50
- end
51
-
52
- def validate_config(config)
53
- unless config.is_a?(Hash) && config["database"].is_a?(Hash)
54
- raise "Invalid configuration format in #{@config_file}"
55
- end
56
-
57
- required_keys = %w[adapter host port database username]
58
- missing_keys = required_keys - config["database"].keys
59
-
60
- unless missing_keys.empty?
61
- raise "Missing required configuration keys: #{missing_keys.join(", ")}"
62
- end
63
-
64
- unless config["database"]["adapter"] == "postgresql"
65
- raise "Only PostgreSQL is supported as a database adapter"
66
- end
67
- end
68
- end
69
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pg"
4
- require "que"
5
- require "sequel"
6
-
7
- module Aidp
8
- class DatabaseConnection
9
- class << self
10
- def initialize_mutex
11
- @mutex ||= Mutex.new
12
- end
13
-
14
- def establish_connection
15
- initialize_mutex
16
- @mutex.synchronize do
17
- # Return existing connection if already established
18
- return @connection if @connection && !@connection.finished?
19
- @connection = PG.connect(connection_params)
20
- @sequel_db = Sequel.connect(
21
- adapter: "postgres",
22
- host: ENV["AIDP_DB_HOST"] || "localhost",
23
- port: (ENV["AIDP_DB_PORT"] || 5432).to_i,
24
- database: ENV["AIDP_DB_NAME"] || "aidp",
25
- user: ENV["AIDP_DB_USER"] || ENV["USER"],
26
- password: ENV["AIDP_DB_PASSWORD"]
27
- )
28
- Que.connection = @sequel_db
29
- Que.migrate!(version: Que::Migrations::CURRENT_VERSION)
30
- @connection
31
- end
32
- end
33
-
34
- def connection
35
- return @connection if @connection && !@connection.finished?
36
- establish_connection
37
- end
38
-
39
- def disconnect
40
- initialize_mutex
41
- @mutex.synchronize do
42
- return unless @connection
43
-
44
- # Safely disconnect in reverse order
45
- begin
46
- Que.connection = nil
47
- rescue => e
48
- # Log but don't fail on Que disconnection issues
49
- puts "Warning: Error setting Que.connection to nil: #{e.message}" if ENV["AIDP_DEBUG"]
50
- end
51
-
52
- @sequel_db&.disconnect
53
- @connection&.close
54
- @connection = nil
55
- @sequel_db = nil
56
- end
57
- end
58
-
59
- private
60
-
61
- def connection_params
62
- {
63
- host: ENV["AIDP_DB_HOST"] || "localhost",
64
- port: (ENV["AIDP_DB_PORT"] || 5432).to_i,
65
- dbname: ENV["AIDP_DB_NAME"] || "aidp",
66
- user: ENV["AIDP_DB_USER"] || ENV["USER"],
67
- password: ENV["AIDP_DB_PASSWORD"]
68
- }
69
- end
70
- end
71
- end
72
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Aidp
4
- class JobManager
5
- def initialize(project_dir)
6
- @project_dir = project_dir
7
- end
8
-
9
- def create_job(job_class, args = {})
10
- # Create a new job and return job ID
11
- # This is a placeholder implementation
12
- job_id = rand(1000..9999)
13
-
14
- # Store job metadata for testing
15
- @jobs ||= {}
16
- @jobs[job_id] = {
17
- id: job_id,
18
- job_class: job_class,
19
- args: args,
20
- status: "queued",
21
- created_at: Time.now
22
- }
23
-
24
- job_id
25
- end
26
-
27
- def get_job(job_id)
28
- @jobs ||= {}
29
- @jobs[job_id]
30
- end
31
-
32
- def update_job_status(job_id, status, error: nil)
33
- @jobs ||= {}
34
- return unless @jobs[job_id]
35
-
36
- @jobs[job_id][:status] = status
37
- @jobs[job_id][:error] = error if error
38
- @jobs[job_id][:updated_at] = Time.now
39
- end
40
- end
41
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "que"
4
-
5
- module Aidp
6
- module Jobs
7
- class BaseJob < Que::Job
8
- # Default settings
9
- self.retry_interval = 30.0 # 30 seconds between retries
10
- self.maximum_retry_count = 3
11
-
12
- # Error tracking
13
- class_attribute :error_handlers
14
- self.error_handlers = []
15
-
16
- def self.on_error(&block)
17
- error_handlers << block
18
- end
19
-
20
- protected
21
-
22
- def log_info(message)
23
- Que.logger.info "[#{self.class.name}] #{message}"
24
- end
25
-
26
- def log_error(message)
27
- Que.logger.error "[#{self.class.name}] #{message}"
28
- end
29
-
30
- def handle_error(error)
31
- self.class.error_handlers.each do |handler|
32
- handler.call(error, self)
33
- end
34
- end
35
-
36
- # Override run to add error handling
37
- def run(*args)
38
- raise NotImplementedError, "#{self.class} must implement #run"
39
- rescue => error
40
- handle_error(error)
41
- raise # Re-raise to trigger Que's retry mechanism
42
- end
43
- end
44
- end
45
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Aidp
4
- module Jobs
5
- class ProviderExecutionJob < BaseJob
6
- def self.enqueue(provider_type:, prompt:, session: nil, metadata: {})
7
- job = super
8
- # Extract job ID explicitly for better readability and debugging
9
- job_id = job.que_attrs[:job_id]
10
- raise "Failed to enqueue job: no job ID returned" unless job_id
11
- job_id
12
- end
13
-
14
- def run(provider_type:, prompt:, session: nil, metadata: {})
15
- start_time = Time.now
16
-
17
- # Get provider instance
18
- provider = Aidp::ProviderManager.get_provider(provider_type)
19
- raise "Provider #{provider_type} not available" unless provider
20
-
21
- # Execute provider
22
- result = provider.send(prompt: prompt, session: session)
23
-
24
- # Store result
25
- store_result(result, metadata)
26
-
27
- # Record metrics
28
- record_metrics(
29
- provider_type: provider_type,
30
- duration: Time.now - start_time,
31
- success: true,
32
- error: nil
33
- )
34
- end
35
-
36
- private
37
-
38
- def store_result(result, metadata)
39
- return unless metadata[:step_name]
40
-
41
- Aidp::DatabaseConnection.connection.exec_params(
42
- <<~SQL,
43
- INSERT INTO analysis_results (step_name, data, metadata, created_at, updated_at)
44
- VALUES ($1, $2, $3, $4, $5)
45
- ON CONFLICT (step_name)
46
- DO UPDATE SET
47
- data = EXCLUDED.data,
48
- metadata = EXCLUDED.metadata,
49
- updated_at = EXCLUDED.updated_at
50
- SQL
51
- [
52
- metadata[:step_name],
53
- result.to_json,
54
- metadata.to_json,
55
- Time.now,
56
- Time.now
57
- ]
58
- )
59
- end
60
-
61
- def record_metrics(provider_type:, duration:, success:, error: nil)
62
- Aidp::DatabaseConnection.connection.exec_params(
63
- <<~SQL,
64
- INSERT INTO provider_metrics (
65
- provider_type, duration, success, error,
66
- job_id, attempt, created_at
67
- )
68
- VALUES ($1, $2, $3, $4, $5, $6, $7)
69
- SQL
70
- [
71
- provider_type,
72
- duration,
73
- success,
74
- error,
75
- que_attrs[:job_id],
76
- que_attrs[:error_count] + 1,
77
- Time.now
78
- ]
79
- )
80
- end
81
- end
82
- end
83
- end
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require "yaml"
5
-
6
- module Aidp
7
- # Detects project type, language, framework, and other characteristics
8
- class ProjectDetector
9
- attr_reader :project_dir
10
-
11
- def initialize(project_dir = Dir.pwd)
12
- @project_dir = project_dir
13
- end
14
-
15
- def detect
16
- {
17
- language: detect_language,
18
- framework: detect_framework,
19
- build_system: detect_build_system,
20
- package_manager: detect_package_manager,
21
- static_analysis_tools: detect_static_analysis_tools,
22
- test_framework: detect_test_framework,
23
- database: detect_database,
24
- deployment: detect_deployment
25
- }
26
- end
27
-
28
- private
29
-
30
- def detect_language
31
- return "ruby" if File.exist?(File.join(@project_dir, "Gemfile"))
32
- return "javascript" if File.exist?(File.join(@project_dir, "package.json"))
33
- return "python" if File.exist?(File.join(@project_dir, "requirements.txt")) || File.exist?(File.join(@project_dir, "pyproject.toml"))
34
- return "java" if File.exist?(File.join(@project_dir, "pom.xml")) || File.exist?(File.join(@project_dir, "build.gradle"))
35
- return "go" if File.exist?(File.join(@project_dir, "go.mod"))
36
- return "rust" if File.exist?(File.join(@project_dir, "Cargo.toml"))
37
- return "csharp" if File.exist?(File.join(@project_dir, "*.csproj"))
38
- "unknown"
39
- end
40
-
41
- def detect_framework
42
- case detect_language
43
- when "ruby"
44
- return "rails" if File.exist?(File.join(@project_dir, "config", "application.rb"))
45
- return "sinatra" if File.exist?(File.join(@project_dir, "app.rb")) && File.read(File.join(@project_dir, "app.rb")).include?("Sinatra")
46
- when "javascript"
47
- return "react" if File.exist?(File.join(@project_dir, "package.json")) && File.read(File.join(@project_dir, "package.json")).include?("react")
48
- return "vue" if File.exist?(File.join(@project_dir, "package.json")) && File.read(File.join(@project_dir, "package.json")).include?("vue")
49
- return "angular" if File.exist?(File.join(@project_dir, "angular.json"))
50
- return "express" if File.exist?(File.join(@project_dir, "package.json")) && File.read(File.join(@project_dir, "package.json")).include?("express")
51
- when "python"
52
- return "django" if File.exist?(File.join(@project_dir, "manage.py"))
53
- return "flask" if File.exist?(File.join(@project_dir, "app.py")) && File.read(File.join(@project_dir, "app.py")).include?("Flask")
54
- when "java"
55
- return "spring" if File.exist?(File.join(@project_dir, "pom.xml")) && File.read(File.join(@project_dir, "pom.xml")).include?("spring-boot")
56
- end
57
- "unknown"
58
- end
59
-
60
- def detect_build_system
61
- return "maven" if File.exist?(File.join(@project_dir, "pom.xml"))
62
- return "gradle" if File.exist?(File.join(@project_dir, "build.gradle"))
63
- return "npm" if File.exist?(File.join(@project_dir, "package.json"))
64
- return "bundler" if File.exist?(File.join(@project_dir, "Gemfile"))
65
- return "pip" if File.exist?(File.join(@project_dir, "requirements.txt"))
66
- return "cargo" if File.exist?(File.join(@project_dir, "Cargo.toml"))
67
- return "go" if File.exist?(File.join(@project_dir, "go.mod"))
68
- "unknown"
69
- end
70
-
71
- def detect_package_manager
72
- detect_build_system
73
- end
74
-
75
- def detect_static_analysis_tools
76
- tools = []
77
- tools << "rubocop" if File.exist?(File.join(@project_dir, ".rubocop.yml"))
78
- tools << "eslint" if File.exist?(File.join(@project_dir, ".eslintrc"))
79
- tools << "flake8" if File.exist?(File.join(@project_dir, ".flake8"))
80
- tools << "checkstyle" if File.exist?(File.join(@project_dir, "checkstyle.xml"))
81
- tools << "clippy" if File.exist?(File.join(@project_dir, "Cargo.toml"))
82
- tools
83
- end
84
-
85
- def detect_test_framework
86
- case detect_language
87
- when "ruby"
88
- return "rspec" if File.exist?(File.join(@project_dir, "spec"))
89
- return "minitest" if File.exist?(File.join(@project_dir, "test"))
90
- when "javascript"
91
- return "jest" if File.exist?(File.join(@project_dir, "package.json")) && File.read(File.join(@project_dir, "package.json")).include?("jest")
92
- return "mocha" if File.exist?(File.join(@project_dir, "package.json")) && File.read(File.join(@project_dir, "package.json")).include?("mocha")
93
- when "python"
94
- return "pytest" if File.exist?(File.join(@project_dir, "pytest.ini"))
95
- return "unittest" if Dir.exist?(File.join(@project_dir, "tests"))
96
- when "java"
97
- return "junit" if File.exist?(File.join(@project_dir, "src", "test"))
98
- end
99
- "unknown"
100
- end
101
-
102
- def detect_database
103
- return "postgresql" if File.exist?(File.join(@project_dir, "config", "database.yml")) && File.read(File.join(@project_dir, "config", "database.yml")).include?("postgresql")
104
- return "mysql" if File.exist?(File.join(@project_dir, "config", "database.yml")) && File.read(File.join(@project_dir, "config", "database.yml")).include?("mysql")
105
- return "sqlite" if File.exist?(File.join(@project_dir, "config", "database.yml")) && File.read(File.join(@project_dir, "config", "database.yml")).include?("sqlite")
106
- "unknown"
107
- end
108
-
109
- def detect_deployment
110
- return "docker" if File.exist?(File.join(@project_dir, "Dockerfile"))
111
- return "kubernetes" if File.exist?(File.join(@project_dir, "k8s")) || File.exist?(File.join(@project_dir, "kubernetes"))
112
- return "heroku" if File.exist?(File.join(@project_dir, "Procfile"))
113
- return "aws" if File.exist?(File.join(@project_dir, "serverless.yml")) || File.exist?(File.join(@project_dir, "template.yaml"))
114
- "unknown"
115
- end
116
- end
117
- end