ruby_raider 2.0.0 → 3.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.
- checksums.yaml +4 -4
- data/.github/workflows/e2e_tests.yml +58 -0
- data/.github/workflows/steep.yml +21 -0
- data/.gitignore +1 -1
- data/.reek.yml +46 -4
- data/.ruby-version +1 -1
- data/README.md +138 -77
- data/Steepfile +22 -0
- data/assets/ruby_raider_logo.svg +51 -0
- data/lib/adopter/adopt_menu.rb +11 -15
- data/lib/adopter/converters/base_converter.rb +1 -2
- data/lib/adopter/converters/identity_converter.rb +3 -6
- data/lib/adopter/migration_plan.rb +0 -1
- data/lib/adopter/plan_builder.rb +2 -5
- data/lib/adopter/project_analyzer.rb +1 -5
- data/lib/adopter/project_detector.rb +3 -5
- data/lib/commands/adopt_commands.rb +0 -1
- data/lib/commands/plugin_commands.rb +0 -2
- data/lib/commands/scaffolding_commands.rb +220 -37
- data/lib/commands/utility_commands.rb +82 -2
- data/lib/generators/automation/automation_generator.rb +0 -7
- data/lib/generators/automation/templates/partials/element.tt +1 -1
- data/lib/generators/automation/templates/partials/initialize_selector.tt +0 -7
- data/lib/generators/automation/templates/partials/url_methods.tt +0 -1
- data/lib/generators/common_generator.rb +12 -0
- data/lib/generators/cucumber/cucumber_generator.rb +36 -0
- data/lib/generators/cucumber/templates/accessibility_feature.tt +5 -0
- data/lib/generators/cucumber/templates/accessibility_steps.tt +21 -0
- data/lib/generators/cucumber/templates/cucumber.tt +8 -1
- data/lib/generators/cucumber/templates/feature.tt +0 -4
- data/lib/generators/cucumber/templates/partials/appium_env.tt +5 -0
- data/lib/generators/cucumber/templates/partials/capybara_env.tt +19 -1
- data/lib/generators/cucumber/templates/partials/driver_world.tt +1 -4
- data/lib/generators/cucumber/templates/partials/selenium_env.tt +22 -35
- data/lib/generators/cucumber/templates/partials/watir_env.tt +20 -1
- data/lib/generators/cucumber/templates/partials/web_steps.tt +6 -12
- data/lib/generators/cucumber/templates/performance_feature.tt +5 -0
- data/lib/generators/cucumber/templates/performance_steps.tt +17 -0
- data/lib/generators/cucumber/templates/visual_feature.tt +5 -0
- data/lib/generators/cucumber/templates/visual_steps.tt +19 -0
- data/lib/generators/generator.rb +38 -7
- data/lib/generators/helper_generator.rb +24 -7
- data/lib/generators/infrastructure/templates/github.tt +1 -1
- data/lib/generators/infrastructure/templates/github_appium.tt +2 -2
- data/lib/generators/infrastructure/templates/gitlab.tt +1 -1
- data/lib/generators/invoke_generators.rb +42 -9
- data/lib/generators/menu_generator.rb +120 -11
- data/lib/generators/minitest/minitest_generator.rb +16 -4
- data/lib/generators/minitest/templates/accessibility_test.tt +26 -0
- data/lib/generators/minitest/templates/performance_test.tt +18 -0
- data/lib/generators/minitest/templates/test.tt +5 -34
- data/lib/generators/minitest/templates/visual_test.tt +23 -0
- data/lib/generators/rspec/rspec_generator.rb +16 -4
- data/lib/generators/rspec/templates/accessibility_spec.tt +25 -0
- data/lib/generators/rspec/templates/performance_spec.tt +18 -0
- data/lib/generators/rspec/templates/spec.tt +5 -35
- data/lib/generators/rspec/templates/visual_spec.tt +20 -0
- data/lib/generators/template_renderer/partial_cache.rb +11 -1
- data/lib/generators/template_renderer/partial_resolver.rb +17 -10
- data/lib/generators/template_renderer.rb +17 -1
- data/lib/generators/templates/common/gemfile.tt +21 -6
- data/lib/generators/templates/common/git_ignore.tt +6 -1
- data/lib/generators/templates/common/partials/mobile_config.tt +5 -1
- data/lib/generators/templates/common/partials/web_config.tt +16 -7
- data/lib/generators/templates/common/rakefile.tt +36 -0
- data/lib/generators/templates/common/read_me.tt +41 -91
- data/lib/generators/templates/common/rspec.tt +3 -0
- data/lib/generators/templates/common/ruby_version.tt +1 -0
- data/lib/generators/templates/helpers/allure_helper.tt +11 -0
- data/lib/generators/templates/helpers/browser_helper.tt +12 -2
- data/lib/generators/templates/helpers/capybara_helper.tt +5 -1
- data/lib/generators/templates/helpers/debug_helper.tt +190 -0
- data/lib/generators/templates/helpers/driver_helper.tt +2 -10
- data/lib/generators/templates/helpers/partials/appium_driver.tt +0 -2
- data/lib/generators/templates/helpers/partials/debug_diagnostics.tt +7 -0
- data/lib/generators/templates/helpers/partials/debug_start.tt +7 -0
- data/lib/generators/templates/helpers/partials/driver_and_options.tt +1 -3
- data/lib/generators/templates/helpers/partials/selenium_driver.tt +8 -7
- data/lib/generators/templates/helpers/partials/video_start.tt +9 -0
- data/lib/generators/templates/helpers/partials/video_stop.tt +4 -0
- data/lib/generators/templates/helpers/performance_helper.tt +57 -0
- data/lib/generators/templates/helpers/spec_helper.tt +57 -8
- data/lib/generators/templates/helpers/test_helper.tt +69 -1
- data/lib/generators/templates/helpers/video_helper.tt +270 -0
- data/lib/generators/templates/helpers/visual_helper.tt +39 -46
- data/lib/llm/client.rb +79 -0
- data/lib/llm/config.rb +57 -0
- data/lib/llm/prompts.rb +84 -0
- data/lib/llm/provider.rb +27 -0
- data/lib/llm/providers/anthropic_provider.rb +43 -0
- data/lib/llm/providers/ollama_provider.rb +56 -0
- data/lib/llm/providers/openai_provider.rb +42 -0
- data/lib/llm/response_parser.rb +67 -0
- data/lib/plugin/plugin.rb +22 -20
- data/lib/plugin/plugin_exposer.rb +16 -38
- data/lib/ruby_raider.rb +47 -12
- data/lib/scaffolding/crud_generator.rb +94 -0
- data/lib/scaffolding/dry_run_presenter.rb +16 -0
- data/lib/scaffolding/name_normalizer.rb +63 -0
- data/lib/scaffolding/page_introspector.rb +45 -0
- data/lib/scaffolding/project_detector.rb +72 -0
- data/lib/scaffolding/scaffold_menu.rb +103 -0
- data/lib/scaffolding/scaffolding.rb +158 -11
- data/lib/scaffolding/templates/component.tt +30 -0
- data/lib/scaffolding/templates/feature.tt +4 -4
- data/lib/scaffolding/templates/helper.tt +15 -1
- data/lib/scaffolding/templates/page_from_url.tt +75 -0
- data/lib/scaffolding/templates/page_object.tt +50 -1
- data/lib/scaffolding/templates/spec.tt +33 -2
- data/lib/scaffolding/templates/spec_from_page.tt +31 -0
- data/lib/scaffolding/templates/spec_from_url.tt +46 -0
- data/lib/scaffolding/templates/steps.tt +17 -5
- data/lib/scaffolding/url_analyzer.rb +179 -0
- data/lib/utilities/desktop_downloader.rb +177 -0
- data/lib/utilities/logo.rb +83 -0
- data/lib/utilities/utilities.rb +53 -20
- data/lib/version +1 -1
- data/ruby_raider.gemspec +1 -0
- data/sig/adopter/adopt_menu.rbs +25 -0
- data/sig/adopter/converters/base_converter.rbs +23 -0
- data/sig/adopter/converters/identity_converter.rbs +16 -0
- data/sig/adopter/migration_plan.rbs +34 -0
- data/sig/adopter/migrator.rbs +21 -0
- data/sig/adopter/plan_builder.rbs +38 -0
- data/sig/adopter/project_analyzer.rbs +39 -0
- data/sig/adopter/project_detector.rbs +26 -0
- data/sig/commands/adopt_commands.rbs +8 -0
- data/sig/commands/loaded_commands.rbs +5 -0
- data/sig/commands/plugin_commands.rbs +9 -0
- data/sig/commands/scaffolding_commands.rbs +28 -0
- data/sig/commands/utility_commands.rbs +21 -0
- data/sig/generators/automation/automation_generator.rbs +20 -0
- data/sig/generators/common_generator.rbs +12 -0
- data/sig/generators/cucumber/cucumber_generator.rbs +16 -0
- data/sig/generators/generator.rbs +40 -0
- data/sig/generators/helper_generator.rbs +18 -0
- data/sig/generators/infrastructure/github_generator.rbs +5 -0
- data/sig/generators/infrastructure/gitlab_generator.rbs +4 -0
- data/sig/generators/invoke_generators.rbs +10 -0
- data/sig/generators/menu_generator.rbs +29 -0
- data/sig/generators/minitest/minitest_generator.rbs +8 -0
- data/sig/generators/rspec/rspec_generator.rbs +8 -0
- data/sig/generators/template_renderer/partial_cache.rbs +20 -0
- data/sig/generators/template_renderer/partial_resolver.rbs +20 -0
- data/sig/generators/template_renderer/template_error.rbs +19 -0
- data/sig/generators/template_renderer.rbs +10 -0
- data/sig/llm/client.rbs +15 -0
- data/sig/llm/config.rbs +20 -0
- data/sig/llm/prompts.rbs +8 -0
- data/sig/llm/provider.rbs +12 -0
- data/sig/llm/providers/anthropic_provider.rbs +16 -0
- data/sig/llm/providers/ollama_provider.rbs +18 -0
- data/sig/llm/providers/openai_provider.rbs +16 -0
- data/sig/llm/response_parser.rbs +13 -0
- data/sig/plugin/plugin.rbs +24 -0
- data/sig/plugin/plugin_exposer.rbs +20 -0
- data/sig/ruby_raider.rbs +15 -0
- data/sig/scaffolding/crud_generator.rbs +16 -0
- data/sig/scaffolding/dry_run_presenter.rbs +4 -0
- data/sig/scaffolding/name_normalizer.rbs +17 -0
- data/sig/scaffolding/page_introspector.rbs +14 -0
- data/sig/scaffolding/project_detector.rbs +14 -0
- data/sig/scaffolding/scaffold_menu.rbs +18 -0
- data/sig/scaffolding/scaffolding.rbs +55 -0
- data/sig/scaffolding/url_analyzer.rbs +28 -0
- data/sig/utilities/desktop_downloader.rbs +23 -0
- data/sig/utilities/logger.rbs +13 -0
- data/sig/utilities/logo.rbs +16 -0
- data/sig/utilities/utilities.rbs +30 -0
- data/sig/vendor/thor.rbs +34 -0
- data/sig/vendor/tty_prompt.rbs +15 -0
- data/spec/adopter/adopt_menu_spec.rb +12 -12
- data/spec/adopter/migration_plan_spec.rb +1 -1
- data/spec/adopter/migrator_spec.rb +2 -2
- data/spec/adopter/project_detector_spec.rb +1 -1
- data/spec/commands/raider_commands_spec.rb +129 -0
- data/spec/generators/generator_spec.rb +23 -0
- data/spec/integration/commands/scaffolding_commands_spec.rb +1 -1
- data/spec/integration/commands/utility_commands_spec.rb +23 -3
- data/spec/integration/content/ci_content_spec.rb +119 -0
- data/spec/integration/content/common_content_spec.rb +288 -0
- data/spec/integration/content/config_content_spec.rb +175 -0
- data/spec/integration/content/content_helper.rb +32 -0
- data/spec/integration/content/gemfile_content_spec.rb +209 -0
- data/spec/integration/content/helper_content_spec.rb +485 -0
- data/spec/integration/content/page_content_spec.rb +259 -0
- data/spec/integration/content/reporter_content_spec.rb +236 -0
- data/spec/integration/content/skip_flags_content_spec.rb +206 -0
- data/spec/integration/content/syntax_validation_spec.rb +30 -0
- data/spec/integration/content/test_content_spec.rb +266 -0
- data/spec/integration/end_to_end_features_spec.rb +690 -0
- data/spec/integration/end_to_end_spec.rb +52 -16
- data/spec/integration/generators/automation_generator_spec.rb +0 -12
- data/spec/integration/generators/axe_addon_spec.rb +150 -0
- data/spec/integration/generators/common_generator_spec.rb +12 -13
- data/spec/integration/generators/config_features_spec.rb +155 -0
- data/spec/integration/generators/debug_helper_spec.rb +68 -0
- data/spec/integration/generators/helpers_generator_spec.rb +0 -12
- data/spec/integration/generators/lighthouse_addon_spec.rb +132 -0
- data/spec/integration/generators/minitest_generator_spec.rb +0 -6
- data/spec/integration/generators/reporter_spec.rb +159 -0
- data/spec/integration/generators/skip_flags_spec.rb +134 -0
- data/spec/integration/generators/visual_addon_spec.rb +148 -0
- data/spec/integration/settings_helper.rb +0 -3
- data/spec/integration/spec_helper.rb +30 -13
- data/spec/llm/client_spec.rb +79 -0
- data/spec/llm/config_spec.rb +92 -0
- data/spec/llm/prompts_spec.rb +49 -0
- data/spec/llm/response_parser_spec.rb +92 -0
- data/spec/menus/adopter_adopt_menu_spec.rb +97 -0
- data/spec/menus/menu_generator_spec.rb +263 -0
- data/spec/scaffolding/name_normalizer_spec.rb +113 -0
- data/spec/scaffolding/page_introspector_spec.rb +82 -0
- data/spec/scaffolding/scaffold_project_detector_spec.rb +104 -0
- data/spec/scaffolding/scaffolding_features_spec.rb +311 -0
- data/spec/scaffolding/url_analyzer_spec.rb +110 -0
- data/spec/system/adopt_matrix_spec.rb +537 -0
- data/spec/system/adopt_spec.rb +225 -0
- data/spec/system/support/system_test_helper.rb +0 -2
- data/spec/utilities/desktop_downloader_spec.rb +92 -0
- metadata +150 -5
- data/lib/generators/automation/templates/visual_options.tt +0 -16
- data/lib/generators/templates/helpers/partials/axe_driver.tt +0 -10
- data/lib/generators/templates/helpers/visual_spec_helper.tt +0 -35
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
|
|
6
|
+
class UrlAnalyzer
|
|
7
|
+
INTERACTIVE_TAGS = %w[input select textarea button].freeze
|
|
8
|
+
|
|
9
|
+
attr_reader :url, :page_name, :elements
|
|
10
|
+
|
|
11
|
+
def initialize(url, name_override: nil, ai: false) # rubocop:disable Naming/MethodParameterName
|
|
12
|
+
@url = url
|
|
13
|
+
@uri = URI.parse(url)
|
|
14
|
+
@page_name = name_override || derive_page_name
|
|
15
|
+
@elements = []
|
|
16
|
+
@ai = ai
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def analyze
|
|
20
|
+
html = fetch_html
|
|
21
|
+
if @ai
|
|
22
|
+
ai_elements = analyze_with_llm(html)
|
|
23
|
+
@elements = ai_elements if ai_elements
|
|
24
|
+
end
|
|
25
|
+
parse_elements(html) if @elements.empty?
|
|
26
|
+
self
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_h
|
|
30
|
+
{ page_name: @page_name, url: @url, url_path: @uri.path, elements: @elements }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def fetch_html
|
|
36
|
+
response = Net::HTTP.get_response(@uri)
|
|
37
|
+
response.body
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
raise "Failed to fetch #{@url}: #{e.message}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def parse_elements(html)
|
|
43
|
+
# Simple regex-based HTML parsing (no external dependency needed)
|
|
44
|
+
parse_inputs(html)
|
|
45
|
+
parse_selects(html)
|
|
46
|
+
parse_textareas(html)
|
|
47
|
+
parse_buttons(html)
|
|
48
|
+
parse_links(html)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def parse_inputs(html)
|
|
52
|
+
html.scan(/<input\s+([^>]*)>/i).each do |match|
|
|
53
|
+
attrs = parse_attributes(match[0])
|
|
54
|
+
next if %w[hidden submit].include?(attrs['type'])
|
|
55
|
+
|
|
56
|
+
@elements << build_element(
|
|
57
|
+
name: attrs['name'] || attrs['id'] || attrs['placeholder'] || 'input',
|
|
58
|
+
type: :input,
|
|
59
|
+
input_type: attrs['type'] || 'text',
|
|
60
|
+
locator: best_locator(attrs)
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def parse_selects(html)
|
|
66
|
+
html.scan(/<select\s+([^>]*)>/i).each do |match|
|
|
67
|
+
attrs = parse_attributes(match[0])
|
|
68
|
+
@elements << build_element(
|
|
69
|
+
name: attrs['name'] || attrs['id'] || 'select',
|
|
70
|
+
type: :select,
|
|
71
|
+
locator: best_locator(attrs)
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def parse_textareas(html)
|
|
77
|
+
html.scan(/<textarea\s+([^>]*)>/i).each do |match|
|
|
78
|
+
attrs = parse_attributes(match[0])
|
|
79
|
+
@elements << build_element(
|
|
80
|
+
name: attrs['name'] || attrs['id'] || 'textarea',
|
|
81
|
+
type: :textarea,
|
|
82
|
+
locator: best_locator(attrs)
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def parse_buttons(html)
|
|
88
|
+
html.scan(%r{<button\s+([^>]*)>([^<]*)</button>}i).each do |match|
|
|
89
|
+
attrs = parse_attributes(match[0])
|
|
90
|
+
text = match[1].strip
|
|
91
|
+
@elements << build_element(
|
|
92
|
+
name: attrs['id'] || attrs['name'] || text.downcase.gsub(/\s+/, '_') || 'button',
|
|
93
|
+
type: :button,
|
|
94
|
+
text:,
|
|
95
|
+
locator: best_locator(attrs, text:)
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
html.scan(/<input\s+([^>]*type=["']submit["'][^>]*)>/i).each do |match|
|
|
100
|
+
attrs = parse_attributes(match[0])
|
|
101
|
+
@elements << build_element(
|
|
102
|
+
name: attrs['id'] || attrs['name'] || attrs['value']&.downcase&.gsub(/\s+/, '_') || 'submit',
|
|
103
|
+
type: :submit,
|
|
104
|
+
text: attrs['value'] || 'Submit',
|
|
105
|
+
locator: best_locator(attrs)
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def parse_links(html)
|
|
111
|
+
html.scan(%r{<a\s+([^>]*)>([^<]*)</a>}i).first(5)&.each do |match|
|
|
112
|
+
attrs = parse_attributes(match[0])
|
|
113
|
+
text = match[1].strip
|
|
114
|
+
next if text.empty?
|
|
115
|
+
|
|
116
|
+
@elements << build_element(
|
|
117
|
+
name: text.downcase.gsub(/\s+/, '_'),
|
|
118
|
+
type: :link,
|
|
119
|
+
text:,
|
|
120
|
+
locator: best_locator(attrs, text:)
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def parse_attributes(attr_string)
|
|
126
|
+
attrs = {}
|
|
127
|
+
attr_string.scan(/([\w-]+)=["']([^"']*)["']/).each do |key, value|
|
|
128
|
+
attrs[key] = value
|
|
129
|
+
end
|
|
130
|
+
attrs
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def best_locator(attrs, text: nil)
|
|
134
|
+
if attrs['id']
|
|
135
|
+
{ type: :id, value: attrs['id'] }
|
|
136
|
+
elsif attrs['name']
|
|
137
|
+
{ type: :name, value: attrs['name'] }
|
|
138
|
+
elsif attrs['class'] && !attrs['class'].empty?
|
|
139
|
+
{ type: :css, value: ".#{attrs['class'].split.first}" }
|
|
140
|
+
elsif text && !text.empty?
|
|
141
|
+
{ type: :xpath, value: "//#{infer_tag(attrs)}[contains(text(), '#{text}')]" }
|
|
142
|
+
else
|
|
143
|
+
{ type: :css, value: attrs.first&.last || 'unknown' }
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def infer_tag(attrs)
|
|
148
|
+
return 'button' if attrs['type'] == 'button' || attrs['type'] == 'submit'
|
|
149
|
+
return 'a' if attrs['href']
|
|
150
|
+
|
|
151
|
+
'*'
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def build_element(name:, type:, locator:, **extra)
|
|
155
|
+
clean_name = name.to_s.gsub(/[^a-z0-9_]/i, '_').gsub(/_+/, '_').downcase.delete_prefix('_').delete_suffix('_')
|
|
156
|
+
{ name: clean_name, type:, locator: }.merge(extra)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def analyze_with_llm(html)
|
|
160
|
+
require_relative '../llm/client'
|
|
161
|
+
require_relative '../llm/prompts'
|
|
162
|
+
require_relative '../llm/response_parser'
|
|
163
|
+
|
|
164
|
+
return nil unless Llm::Client.available?
|
|
165
|
+
|
|
166
|
+
response = Llm::Client.complete(
|
|
167
|
+
Llm::Prompts.analyze_page(html, @url),
|
|
168
|
+
system_prompt: Llm::Prompts.system_prompt
|
|
169
|
+
)
|
|
170
|
+
Llm::ResponseParser.extract_elements(response)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def derive_page_name
|
|
174
|
+
path = @uri.path.to_s.gsub(%r{^/|/$}, '')
|
|
175
|
+
return 'home' if path.empty?
|
|
176
|
+
|
|
177
|
+
path.split('/').last.gsub(/[^a-z0-9]/i, '_').downcase
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'uri'
|
|
6
|
+
require 'rbconfig'
|
|
7
|
+
|
|
8
|
+
# Downloads the latest Raider Desktop release for the current platform.
|
|
9
|
+
# Uses the GitHub API to discover the latest release and match the right artifact.
|
|
10
|
+
module DesktopDownloader
|
|
11
|
+
REPO = 'RaiderHQ/raider_desktop'
|
|
12
|
+
API_URL = "https://api.github.com/repos/#{REPO}/releases/latest".freeze
|
|
13
|
+
|
|
14
|
+
PLATFORM_PATTERNS = {
|
|
15
|
+
'mac_arm' => /\.dmg$/i,
|
|
16
|
+
'mac_intel' => /\.dmg$/i,
|
|
17
|
+
'windows' => /setup\.exe$/i,
|
|
18
|
+
'linux_deb' => /\.deb$/i,
|
|
19
|
+
'linux_appimage' => /\.AppImage$/i
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
HTTP_OPEN_TIMEOUT = 10
|
|
23
|
+
HTTP_READ_TIMEOUT = 15
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def download(destination_dir = nil)
|
|
27
|
+
destination_dir ||= default_download_dir
|
|
28
|
+
asset = find_asset
|
|
29
|
+
unless asset
|
|
30
|
+
warn '[Ruby Raider] No desktop release found for your platform'
|
|
31
|
+
return nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
destination = File.join(destination_dir, asset[:name])
|
|
35
|
+
puts "Downloading Raider Desktop (#{asset[:name]})..."
|
|
36
|
+
download_file(asset[:url], destination)
|
|
37
|
+
puts "Downloaded to: #{destination}"
|
|
38
|
+
destination
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def latest_version
|
|
42
|
+
cached_release&.dig('tag_name')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def download_url
|
|
46
|
+
asset = find_asset
|
|
47
|
+
asset&.dig(:url)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Clear cached release data (useful between operations or for testing)
|
|
51
|
+
def clear_cache
|
|
52
|
+
@cached_release = :unset
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def platform
|
|
56
|
+
host_os = RbConfig::CONFIG['host_os']
|
|
57
|
+
arch = RbConfig::CONFIG['host_cpu']
|
|
58
|
+
|
|
59
|
+
case host_os
|
|
60
|
+
when /darwin|mac os/i
|
|
61
|
+
arch =~ /arm|aarch64/i ? 'mac_arm' : 'mac_intel'
|
|
62
|
+
when /mswin|mingw|cygwin|windows/i
|
|
63
|
+
'windows'
|
|
64
|
+
when /linux/i
|
|
65
|
+
'linux_appimage'
|
|
66
|
+
else
|
|
67
|
+
'linux_appimage'
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def platform_display_name
|
|
72
|
+
case platform
|
|
73
|
+
when 'mac_arm' then 'macOS (Apple Silicon)'
|
|
74
|
+
when 'mac_intel' then 'macOS (Intel)'
|
|
75
|
+
when 'windows' then 'Windows'
|
|
76
|
+
when 'linux_deb' then 'Linux (deb)'
|
|
77
|
+
when 'linux_appimage' then 'Linux (AppImage)'
|
|
78
|
+
else 'Unknown'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def find_asset
|
|
85
|
+
release = cached_release
|
|
86
|
+
return nil unless release
|
|
87
|
+
|
|
88
|
+
assets = release['assets'] || []
|
|
89
|
+
pattern = PLATFORM_PATTERNS[platform]
|
|
90
|
+
return nil unless pattern
|
|
91
|
+
|
|
92
|
+
matched = assets.find { |a| a['name'].match?(pattern) }
|
|
93
|
+
return nil unless matched
|
|
94
|
+
|
|
95
|
+
{ name: matched['name'], url: matched['browser_download_url'], size: matched['size'] }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Cache release data to avoid duplicate GitHub API calls
|
|
99
|
+
# (latest_version, find_asset, and download_url all need the same data)
|
|
100
|
+
def cached_release
|
|
101
|
+
return @cached_release if defined?(@cached_release) && @cached_release != :unset
|
|
102
|
+
|
|
103
|
+
@cached_release = fetch_latest_release
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def fetch_latest_release
|
|
107
|
+
uri = URI(API_URL)
|
|
108
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
109
|
+
http.use_ssl = uri.scheme == 'https'
|
|
110
|
+
http.open_timeout = HTTP_OPEN_TIMEOUT
|
|
111
|
+
http.read_timeout = HTTP_READ_TIMEOUT
|
|
112
|
+
response = http.get(uri.request_uri)
|
|
113
|
+
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
114
|
+
|
|
115
|
+
JSON.parse(response.body)
|
|
116
|
+
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
|
117
|
+
warn "[Ruby Raider] GitHub API timed out: #{e.message}"
|
|
118
|
+
nil
|
|
119
|
+
rescue StandardError => e
|
|
120
|
+
warn "[Ruby Raider] Failed to check releases: #{e.message}"
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def download_file(url, destination)
|
|
125
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
|
126
|
+
uri = URI(url)
|
|
127
|
+
follow_redirects(uri, destination)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def follow_redirects(uri, destination, limit = 5)
|
|
131
|
+
raise 'Too many redirects' if limit.zero?
|
|
132
|
+
|
|
133
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https',
|
|
134
|
+
open_timeout: HTTP_OPEN_TIMEOUT, read_timeout: 60) do |http|
|
|
135
|
+
request = Net::HTTP::Get.new(uri)
|
|
136
|
+
http.request(request) do |response|
|
|
137
|
+
case response
|
|
138
|
+
when Net::HTTPRedirection
|
|
139
|
+
follow_redirects(URI(response['location']), destination, limit - 1)
|
|
140
|
+
when Net::HTTPSuccess
|
|
141
|
+
write_response(response, destination)
|
|
142
|
+
else
|
|
143
|
+
raise "Download failed: #{response.code} #{response.message}"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def write_response(response, destination)
|
|
150
|
+
total = response['content-length']&.to_i
|
|
151
|
+
downloaded = 0
|
|
152
|
+
File.open(destination, 'wb') do |file|
|
|
153
|
+
response.read_body do |chunk|
|
|
154
|
+
file.write(chunk)
|
|
155
|
+
downloaded += chunk.size
|
|
156
|
+
print_progress(downloaded, total) if total&.positive?
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
puts
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def print_progress(downloaded, total)
|
|
163
|
+
percent = (downloaded * 100.0 / total).round(1)
|
|
164
|
+
bar_width = 30
|
|
165
|
+
filled = (percent / 100.0 * bar_width).round
|
|
166
|
+
bar = "#{'=' * filled}#{' ' * (bar_width - filled)}"
|
|
167
|
+
mb = (downloaded / 1_048_576.0).round(1)
|
|
168
|
+
total_mb = (total / 1_048_576.0).round(1)
|
|
169
|
+
print "\r [#{bar}] #{percent}% (#{mb}/#{total_mb} MB)"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def default_download_dir
|
|
173
|
+
downloads = File.expand_path('~/Downloads')
|
|
174
|
+
File.directory?(downloads) ? downloads : Dir.pwd
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyRaider
|
|
4
|
+
# Displays the Ruby Raider logo as colored pixel art in the terminal.
|
|
5
|
+
# Renders a faceted gem icon alongside "RUBY RAIDER" in a pixel font,
|
|
6
|
+
# using Unicode half-block characters for compact, high-detail output.
|
|
7
|
+
module Logo
|
|
8
|
+
# Color palette: 0 = empty, 1 = dark, 2 = medium, 3 = bright
|
|
9
|
+
PALETTE = {
|
|
10
|
+
1 => '130;30;48',
|
|
11
|
+
2 => '180;45;65',
|
|
12
|
+
3 => '230;70;90'
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
# Gem diamond with faceted shading (6 pixel rows × 9 cols)
|
|
16
|
+
GEM = [
|
|
17
|
+
[0, 0, 0, 3, 3, 3, 0, 0, 0],
|
|
18
|
+
[0, 2, 3, 3, 3, 3, 3, 2, 0],
|
|
19
|
+
[2, 3, 2, 3, 3, 3, 2, 3, 2],
|
|
20
|
+
[2, 2, 1, 2, 2, 2, 1, 2, 2],
|
|
21
|
+
[0, 1, 2, 1, 1, 1, 2, 1, 0],
|
|
22
|
+
[0, 0, 0, 1, 1, 1, 0, 0, 0]
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
# 5-row pixel font glyphs
|
|
26
|
+
GLYPHS = {
|
|
27
|
+
'R' => [[1, 1, 1, 0], [1, 0, 0, 1], [1, 1, 1, 0], [1, 0, 1, 0], [1, 0, 0, 1]],
|
|
28
|
+
'U' => [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
|
|
29
|
+
'B' => [[1, 1, 1, 0], [1, 0, 0, 1], [1, 1, 1, 0], [1, 0, 0, 1], [1, 1, 1, 0]],
|
|
30
|
+
'Y' => [[1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]],
|
|
31
|
+
' ' => [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
|
|
32
|
+
'A' => [[0, 1, 1, 0], [1, 0, 0, 1], [1, 1, 1, 1], [1, 0, 0, 1], [1, 0, 0, 1]],
|
|
33
|
+
'I' => [[1, 1, 1], [0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 1, 1]],
|
|
34
|
+
'D' => [[1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 1, 0]],
|
|
35
|
+
'E' => [[1, 1, 1, 1], [1, 0, 0, 0], [1, 1, 1, 0], [1, 0, 0, 0], [1, 1, 1, 1]]
|
|
36
|
+
}.freeze
|
|
37
|
+
|
|
38
|
+
TEXT_COLOR = 3
|
|
39
|
+
|
|
40
|
+
def self.display
|
|
41
|
+
text_rows = build_text('RUBY RAIDER')
|
|
42
|
+
text_width = text_rows.first.length
|
|
43
|
+
|
|
44
|
+
# Build 6-row text grid: blank top row centers text vertically with gem
|
|
45
|
+
text_grid = [Array.new(text_width, 0)]
|
|
46
|
+
text_rows.each { |row| text_grid << row.map { |px| px == 1 ? TEXT_COLOR : 0 } }
|
|
47
|
+
|
|
48
|
+
# Compose: gem(9) + gap(2) + text
|
|
49
|
+
grid = 6.times.map { |y| GEM[y] + [0, 0] + text_grid[y] }
|
|
50
|
+
|
|
51
|
+
# Render 3 terminal rows (each encodes 2 pixel rows via half-blocks)
|
|
52
|
+
3.times do |tr|
|
|
53
|
+
line = +''
|
|
54
|
+
top = grid[tr * 2]
|
|
55
|
+
bot = grid[tr * 2 + 1]
|
|
56
|
+
top.length.times { |x| line << halfblock(top[x], bot[x]) }
|
|
57
|
+
puts " #{line.rstrip}"
|
|
58
|
+
end
|
|
59
|
+
puts
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.halfblock(top, bot)
|
|
63
|
+
return ' ' if top.zero? && bot.zero?
|
|
64
|
+
return "\e[38;2;#{PALETTE[top]}m█\e[0m" if top == bot
|
|
65
|
+
return "\e[38;2;#{PALETTE[bot]}m▄\e[0m" if top.zero?
|
|
66
|
+
return "\e[38;2;#{PALETTE[top]}m▀\e[0m" if bot.zero?
|
|
67
|
+
|
|
68
|
+
"\e[38;2;#{PALETTE[top]};48;2;#{PALETTE[bot]}m▀\e[0m"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.build_text(str)
|
|
72
|
+
rows = Array.new(5) { [] }
|
|
73
|
+
str.each_char.with_index do |ch, i|
|
|
74
|
+
glyph = GLYPHS.fetch(ch.upcase, GLYPHS[' '])
|
|
75
|
+
5.times { |r| rows[r].push(0, 0) } if i.positive?
|
|
76
|
+
5.times { |r| rows[r].concat(glyph[r]) }
|
|
77
|
+
end
|
|
78
|
+
rows
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private_class_method :halfblock, :build_text
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/utilities/utilities.rb
CHANGED
|
@@ -7,46 +7,44 @@ module Utilities
|
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
9
|
def browser=(browser)
|
|
10
|
-
|
|
11
|
-
overwrite_yaml
|
|
10
|
+
set('browser', browser)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def page_path=(path)
|
|
15
|
-
|
|
16
|
-
overwrite_yaml
|
|
14
|
+
set('page_path', path)
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
def spec_path=(path)
|
|
20
|
-
|
|
21
|
-
overwrite_yaml
|
|
18
|
+
set('spec_path', path)
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
def feature_path=(path)
|
|
25
|
-
|
|
26
|
-
overwrite_yaml
|
|
22
|
+
set('feature_path', path)
|
|
27
23
|
end
|
|
28
24
|
|
|
29
25
|
def helper_path=(path)
|
|
30
|
-
|
|
31
|
-
overwrite_yaml
|
|
26
|
+
set('helper_path', path)
|
|
32
27
|
end
|
|
33
28
|
|
|
34
29
|
def url=(url)
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
set('url', url)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def timeout=(seconds)
|
|
34
|
+
set('timeout', seconds.to_i)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def viewport=(dimensions)
|
|
38
|
+
width, height = dimensions.split('x').map(&:to_i)
|
|
39
|
+
set('viewport', { 'width' => width, 'height' => height })
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def platform=(platform)
|
|
40
|
-
|
|
41
|
-
overwrite_yaml
|
|
43
|
+
set('platform', platform)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
def browser_options=(
|
|
45
|
-
|
|
46
|
-
browser_args = config['browser_arguments']
|
|
47
|
-
browser = args.first&.to_sym
|
|
48
|
-
browser_args[browser] = browser_args[browser] + args[1..] if browser_args.key?(browser)
|
|
49
|
-
overwrite_yaml
|
|
46
|
+
def browser_options=(opts)
|
|
47
|
+
set('browser_options', Array(opts).flatten)
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
def delete_browser_options
|
|
@@ -54,6 +52,35 @@ module Utilities
|
|
|
54
52
|
overwrite_yaml
|
|
55
53
|
end
|
|
56
54
|
|
|
55
|
+
def llm_provider=(provider)
|
|
56
|
+
set('llm_provider', provider)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def llm_api_key=(key)
|
|
60
|
+
set('llm_api_key', key)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def llm_model=(model)
|
|
64
|
+
set('llm_model', model)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def llm_url=(url)
|
|
68
|
+
set('llm_url', url)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def debug=(enabled)
|
|
72
|
+
config['debug'] ||= {}
|
|
73
|
+
config['debug']['enabled'] = enabled
|
|
74
|
+
overwrite_yaml
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Set multiple config keys in a single YAML write.
|
|
78
|
+
# Usage: Utilities.batch_update(browser: 'chrome', timeout: 30)
|
|
79
|
+
def batch_update(**settings)
|
|
80
|
+
settings.each { |key, value| config[key.to_s] = value }
|
|
81
|
+
overwrite_yaml
|
|
82
|
+
end
|
|
83
|
+
|
|
57
84
|
def run(opts = nil)
|
|
58
85
|
command = File.directory?('spec') ? 'rspec spec/' : 'cucumber features'
|
|
59
86
|
system "#{command} #{opts}"
|
|
@@ -66,6 +93,12 @@ module Utilities
|
|
|
66
93
|
|
|
67
94
|
private
|
|
68
95
|
|
|
96
|
+
# Single-key setter: updates in-memory config and writes once
|
|
97
|
+
def set(key, value)
|
|
98
|
+
config[key] = value
|
|
99
|
+
overwrite_yaml
|
|
100
|
+
end
|
|
101
|
+
|
|
69
102
|
def overwrite_yaml
|
|
70
103
|
File.open(@path, 'w') { |file| YAML.dump(config, file) }
|
|
71
104
|
end
|
data/lib/version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.0
|
data/ruby_raider.gemspec
CHANGED
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.add_development_dependency 'rubocop', '~> 1.27'
|
|
20
20
|
s.add_development_dependency 'rubocop-performance', '~> 1.15.0'
|
|
21
21
|
s.add_development_dependency 'rubocop-rspec', '~> 2.9.0'
|
|
22
|
+
s.add_development_dependency 'steep', '~> 1.9'
|
|
22
23
|
|
|
23
24
|
s.add_runtime_dependency 'thor', '~> 1.2.1'
|
|
24
25
|
s.add_runtime_dependency 'tty-prompt', '~> 0.23.1'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Type definitions for Adopter::AdoptMenu
|
|
2
|
+
module Adopter
|
|
3
|
+
class AdoptMenu
|
|
4
|
+
WEB_AUTOMATIONS: Array[String]
|
|
5
|
+
TEST_FRAMEWORKS: Array[String]
|
|
6
|
+
CI_PLATFORMS: Array[String]
|
|
7
|
+
|
|
8
|
+
def initialize: () -> void
|
|
9
|
+
def run: () -> void
|
|
10
|
+
|
|
11
|
+
def self.adopt: (Hash[Symbol, untyped] params) -> Hash[Symbol, untyped]
|
|
12
|
+
def self.validate_params!: (Hash[Symbol, untyped] params) -> void
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def ask_source_path: () -> String
|
|
17
|
+
def preview_detection: (String source_path) -> Hash[Symbol, untyped]
|
|
18
|
+
def ask_target_automation: (String? detected) -> String
|
|
19
|
+
def ask_target_framework: (String? detected) -> String
|
|
20
|
+
def ask_output_path: () -> String?
|
|
21
|
+
def ask_ci_platform: (String? detected) -> String?
|
|
22
|
+
def execute_adoption: (Hash[Symbol, untyped] params) -> void
|
|
23
|
+
def print_results: (MigrationPlan plan, Hash[Symbol, untyped] results) -> void
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Type definitions for Adopter::Converters::BaseConverter
|
|
2
|
+
module Adopter
|
|
3
|
+
module Converters
|
|
4
|
+
class BaseConverter
|
|
5
|
+
RAIDER_BASE_CLASSES: Array[String]
|
|
6
|
+
|
|
7
|
+
def convert_page: (String content, untyped _page_info) -> String
|
|
8
|
+
def convert_test: (String content, untyped _test_info) -> String
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def ensure_frozen_string_literal: (String content) -> String
|
|
13
|
+
def update_base_class: (String content, String target_base) -> String
|
|
14
|
+
def raider_compatible_base?: (String base_class) -> bool
|
|
15
|
+
def update_require_paths: (String content, String target_automation) -> String
|
|
16
|
+
def update_page_requires: (String content) -> String
|
|
17
|
+
def update_helper_requires: (String content, String target_automation) -> String
|
|
18
|
+
def remove_driver_arg: (String content) -> String
|
|
19
|
+
def swap_driver_arg: (String content, String target_arg) -> String
|
|
20
|
+
def driver_arg_for: (String target_automation) -> String?
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Type definitions for Adopter::Converters::IdentityConverter
|
|
2
|
+
module Adopter
|
|
3
|
+
module Converters
|
|
4
|
+
class IdentityConverter < BaseConverter
|
|
5
|
+
def initialize: (String target_automation) -> void
|
|
6
|
+
def convert_page: (String content, untyped _page_info) -> String
|
|
7
|
+
def convert_test: (String content, untyped _test_info) -> String
|
|
8
|
+
def convert_step: (String content) -> String
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def add_page_require: (String content) -> String
|
|
13
|
+
def update_page_instantiation: (String content) -> String
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Type definitions for Adopter::MigrationPlan and ConvertedFile
|
|
2
|
+
module Adopter
|
|
3
|
+
class MigrationPlan
|
|
4
|
+
attr_reader source_path: String
|
|
5
|
+
attr_reader output_path: String
|
|
6
|
+
attr_reader target_automation: String
|
|
7
|
+
attr_reader target_framework: String
|
|
8
|
+
attr_reader ci_platform: String?
|
|
9
|
+
attr_reader skeleton_structure: Hash[Symbol, untyped]
|
|
10
|
+
attr_reader converted_pages: Array[ConvertedFile]
|
|
11
|
+
attr_reader converted_tests: Array[ConvertedFile]
|
|
12
|
+
attr_reader converted_features: Array[ConvertedFile]
|
|
13
|
+
attr_reader converted_steps: Array[ConvertedFile]
|
|
14
|
+
attr_reader gemfile_additions: Array[String]
|
|
15
|
+
attr_reader config_overrides: Hash[String, untyped]
|
|
16
|
+
attr_reader warnings: Array[String]
|
|
17
|
+
attr_reader manual_actions: Array[String]
|
|
18
|
+
|
|
19
|
+
def initialize: (?Hash[Symbol, untyped]? attrs) -> void
|
|
20
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
21
|
+
def to_json: (*untyped args) -> String
|
|
22
|
+
def summary: () -> Hash[Symbol, untyped]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class ConvertedFile
|
|
26
|
+
attr_accessor output_path: String
|
|
27
|
+
attr_accessor content: String
|
|
28
|
+
attr_accessor source_file: String?
|
|
29
|
+
attr_accessor conversion_notes: String?
|
|
30
|
+
|
|
31
|
+
def initialize: (?output_path: String, ?content: String, ?source_file: String?, ?conversion_notes: String?) -> void
|
|
32
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Type definitions for Adopter::Migrator
|
|
2
|
+
module Adopter
|
|
3
|
+
class Migrator
|
|
4
|
+
attr_reader plan: MigrationPlan
|
|
5
|
+
attr_reader results: Hash[Symbol, untyped]
|
|
6
|
+
|
|
7
|
+
def initialize: (MigrationPlan plan) -> void
|
|
8
|
+
def execute: () -> Hash[Symbol, untyped]
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def generate_skeleton: () -> void
|
|
13
|
+
def write_converted_pages: () -> void
|
|
14
|
+
def write_converted_tests: () -> void
|
|
15
|
+
def write_converted_features: () -> void
|
|
16
|
+
def write_converted_steps: () -> void
|
|
17
|
+
def write_file: (ConvertedFile converted_file) -> void
|
|
18
|
+
def merge_gemfile: () -> void
|
|
19
|
+
def apply_config_overrides: () -> void
|
|
20
|
+
end
|
|
21
|
+
end
|