ratatui_ruby 1.2.2 → 1.3.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/.builds/ruby-3.2.yml +54 -0
- data/.builds/ruby-3.3.yml +54 -0
- data/.builds/ruby-3.4.yml +54 -0
- data/.builds/ruby-4.0.0.yml +54 -0
- data/.pre-commit-config.yaml +16 -0
- data/.rubocop.yml +10 -0
- data/AGENTS.md +147 -0
- data/CHANGELOG.md +771 -0
- data/README.md +187 -0
- data/README.rdoc +302 -0
- data/Rakefile +11 -0
- data/Steepfile +50 -0
- data/doc/concepts/application_architecture.md +321 -0
- data/doc/concepts/application_testing.md +193 -0
- data/doc/concepts/async.md +190 -0
- data/doc/concepts/custom_widgets.md +247 -0
- data/doc/concepts/debugging.md +401 -0
- data/doc/concepts/event_handling.md +162 -0
- data/doc/concepts/interactive_design.md +146 -0
- data/doc/contributors/auditing/parity.md +239 -0
- data/doc/contributors/design/ruby_frontend.md +448 -0
- data/doc/contributors/design/rust_backend.md +434 -0
- data/doc/contributors/design.md +11 -0
- data/doc/contributors/developing_examples.md +400 -0
- data/doc/contributors/documentation_style.md +121 -0
- data/doc/contributors/index.md +21 -0
- data/doc/contributors/releasing.md +215 -0
- data/doc/contributors/todo/align/api_completeness_audit-finished.md +381 -0
- data/doc/contributors/todo/align/api_completeness_audit-unfinished.md +200 -0
- data/doc/contributors/todo/align/term.md +351 -0
- data/doc/contributors/todo/align/terminal.md +647 -0
- data/doc/contributors/todo/future_work.md +169 -0
- data/doc/contributors/upstream_requests/paragraph_span_rects.md +259 -0
- data/doc/contributors/upstream_requests/tab_rects.md +173 -0
- data/doc/contributors/upstream_requests/title_rects.md +132 -0
- data/doc/custom.css +22 -0
- data/doc/getting_started/quickstart.md +291 -0
- data/doc/getting_started/why.md +93 -0
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_cli_rich_moments.gif +0 -0
- data/doc/images/app_color_picker.png +0 -0
- data/doc/images/app_debugging_showcase.gif +0 -0
- data/doc/images/app_debugging_showcase.png +0 -0
- data/doc/images/app_external_editor.gif +0 -0
- data/doc/images/app_login_form.png +0 -0
- data/doc/images/app_stateful_interaction.png +0 -0
- data/doc/images/verify_quickstart_dsl.png +0 -0
- data/doc/images/verify_quickstart_layout.png +0 -0
- data/doc/images/verify_quickstart_lifecycle.png +0 -0
- data/doc/images/verify_readme_usage.png +0 -0
- data/doc/images/widget_barchart.png +0 -0
- data/doc/images/widget_block.png +0 -0
- data/doc/images/widget_box.png +0 -0
- data/doc/images/widget_calendar.png +0 -0
- data/doc/images/widget_canvas.png +0 -0
- data/doc/images/widget_cell.png +0 -0
- data/doc/images/widget_center.png +0 -0
- data/doc/images/widget_chart.png +0 -0
- data/doc/images/widget_gauge.png +0 -0
- data/doc/images/widget_layout_split.png +0 -0
- data/doc/images/widget_line_gauge.png +0 -0
- data/doc/images/widget_list.png +0 -0
- data/doc/images/widget_map.png +0 -0
- data/doc/images/widget_overlay.png +0 -0
- data/doc/images/widget_popup.png +0 -0
- data/doc/images/widget_ratatui_logo.png +0 -0
- data/doc/images/widget_ratatui_mascot.png +0 -0
- data/doc/images/widget_rect.png +0 -0
- data/doc/images/widget_render.png +0 -0
- data/doc/images/widget_rich_text.png +0 -0
- data/doc/images/widget_scroll_text.png +0 -0
- data/doc/images/widget_scrollbar.png +0 -0
- data/doc/images/widget_sparkline.png +0 -0
- data/doc/images/widget_style_colors.png +0 -0
- data/doc/images/widget_table.png +0 -0
- data/doc/images/widget_tabs.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/index.md +34 -0
- data/doc/troubleshooting/async.md +4 -0
- data/doc/troubleshooting/terminal_limitations.md +131 -0
- data/doc/troubleshooting/tui_output.md +197 -0
- data/examples/app_all_events/README.md +114 -0
- data/examples/app_all_events/app.rb +98 -0
- data/examples/app_all_events/model/app_model.rb +159 -0
- data/examples/app_all_events/model/event_color_cycle.rb +43 -0
- data/examples/app_all_events/model/event_entry.rb +94 -0
- data/examples/app_all_events/model/msg.rb +39 -0
- data/examples/app_all_events/model/timestamp.rb +56 -0
- data/examples/app_all_events/update.rb +75 -0
- data/examples/app_all_events/view/app_view.rb +80 -0
- data/examples/app_all_events/view/controls_view.rb +54 -0
- data/examples/app_all_events/view/counts_view.rb +61 -0
- data/examples/app_all_events/view/live_view.rb +72 -0
- data/examples/app_all_events/view/log_view.rb +57 -0
- data/examples/app_all_events/view.rb +9 -0
- data/examples/app_cli_rich_moments/README.md +81 -0
- data/examples/app_cli_rich_moments/app.rb +189 -0
- data/examples/app_color_picker/README.md +156 -0
- data/examples/app_color_picker/app.rb +76 -0
- data/examples/app_color_picker/clipboard.rb +86 -0
- data/examples/app_color_picker/color.rb +193 -0
- data/examples/app_color_picker/controls.rb +92 -0
- data/examples/app_color_picker/copy_dialog.rb +168 -0
- data/examples/app_color_picker/export_pane.rb +128 -0
- data/examples/app_color_picker/harmony.rb +58 -0
- data/examples/app_color_picker/input.rb +176 -0
- data/examples/app_color_picker/main_container.rb +180 -0
- data/examples/app_color_picker/palette.rb +111 -0
- data/examples/app_debugging_showcase/README.md +119 -0
- data/examples/app_debugging_showcase/app.rb +318 -0
- data/examples/app_external_editor/README.md +62 -0
- data/examples/app_external_editor/app.rb +344 -0
- data/examples/app_login_form/README.md +58 -0
- data/examples/app_login_form/app.rb +109 -0
- data/examples/app_stateful_interaction/README.md +35 -0
- data/examples/app_stateful_interaction/app.rb +328 -0
- data/examples/timeout_demo.rb +45 -0
- data/examples/verify_quickstart_dsl/README.md +55 -0
- data/examples/verify_quickstart_dsl/app.rb +49 -0
- data/examples/verify_quickstart_layout/README.md +77 -0
- data/examples/verify_quickstart_layout/app.rb +73 -0
- data/examples/verify_quickstart_lifecycle/README.md +68 -0
- data/examples/verify_quickstart_lifecycle/app.rb +62 -0
- data/examples/verify_readme_usage/README.md +49 -0
- data/examples/verify_readme_usage/app.rb +42 -0
- data/examples/verify_website_managed/README.md +48 -0
- data/examples/verify_website_managed/app.rb +36 -0
- data/examples/verify_website_menu/README.md +60 -0
- data/examples/verify_website_menu/app.rb +84 -0
- data/examples/verify_website_spinner/README.md +44 -0
- data/examples/verify_website_spinner/app.rb +34 -0
- data/examples/widget_barchart/README.md +58 -0
- data/examples/widget_barchart/app.rb +240 -0
- data/examples/widget_block/README.md +44 -0
- data/examples/widget_block/app.rb +258 -0
- data/examples/widget_box/README.md +54 -0
- data/examples/widget_box/app.rb +255 -0
- data/examples/widget_calendar/README.md +48 -0
- data/examples/widget_calendar/app.rb +115 -0
- data/examples/widget_canvas/README.md +31 -0
- data/examples/widget_canvas/app.rb +130 -0
- data/examples/widget_cell/README.md +45 -0
- data/examples/widget_cell/app.rb +112 -0
- data/examples/widget_center/README.md +33 -0
- data/examples/widget_center/app.rb +118 -0
- data/examples/widget_chart/README.md +50 -0
- data/examples/widget_chart/app.rb +220 -0
- data/examples/widget_gauge/README.md +50 -0
- data/examples/widget_gauge/app.rb +229 -0
- data/examples/widget_layout_split/README.md +53 -0
- data/examples/widget_layout_split/app.rb +260 -0
- data/examples/widget_line_gauge/README.md +50 -0
- data/examples/widget_line_gauge/app.rb +219 -0
- data/examples/widget_list/README.md +58 -0
- data/examples/widget_list/app.rb +382 -0
- data/examples/widget_map/README.md +48 -0
- data/examples/widget_map/app.rb +95 -0
- data/examples/widget_overlay/README.md +45 -0
- data/examples/widget_overlay/app.rb +250 -0
- data/examples/widget_popup/README.md +45 -0
- data/examples/widget_popup/app.rb +106 -0
- data/examples/widget_ratatui_logo/README.md +43 -0
- data/examples/widget_ratatui_logo/app.rb +104 -0
- data/examples/widget_ratatui_mascot/README.md +43 -0
- data/examples/widget_ratatui_mascot/app.rb +95 -0
- data/examples/widget_rect/README.md +53 -0
- data/examples/widget_rect/app.rb +222 -0
- data/examples/widget_render/README.md +46 -0
- data/examples/widget_render/app.rb +186 -0
- data/examples/widget_render/app.rbs +41 -0
- data/examples/widget_rich_text/README.md +44 -0
- data/examples/widget_rich_text/app.rb +193 -0
- data/examples/widget_scroll_text/README.md +46 -0
- data/examples/widget_scroll_text/app.rb +109 -0
- data/examples/widget_scrollbar/README.md +46 -0
- data/examples/widget_scrollbar/app.rb +155 -0
- data/examples/widget_sparkline/README.md +51 -0
- data/examples/widget_sparkline/app.rb +277 -0
- data/examples/widget_style_colors/README.md +43 -0
- data/examples/widget_style_colors/app.rb +83 -0
- data/examples/widget_table/README.md +57 -0
- data/examples/widget_table/app.rb +285 -0
- data/examples/widget_tabs/README.md +50 -0
- data/examples/widget_tabs/app.rb +183 -0
- data/examples/widget_text_width/README.md +44 -0
- data/examples/widget_text_width/app.rb +117 -0
- data/ext/ratatui_ruby/Cargo.lock +1 -2
- data/ext/ratatui_ruby/Cargo.toml +1 -2
- data/ext/ratatui_ruby/src/events.rs +18 -157
- data/lib/ratatui_ruby/event/focus_gained.rb +50 -0
- data/lib/ratatui_ruby/event/focus_lost.rb +51 -0
- data/lib/ratatui_ruby/event/key/dwim.rb +301 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +2 -0
- data/lib/ratatui_ruby/event/key.rb +9 -0
- data/lib/ratatui_ruby/event/mouse.rb +33 -0
- data/lib/ratatui_ruby/event/paste.rb +25 -0
- data/lib/ratatui_ruby/event/resize.rb +65 -0
- data/lib/ratatui_ruby/version.rb +1 -1
- data/migrate_to_buffer.rb +145 -0
- data/mise.toml +8 -0
- data/sig/ratatui_ruby/event.rbs +97 -0
- data/tasks/autodoc/examples.rb +87 -0
- data/tasks/autodoc/member.rb +58 -0
- data/tasks/autodoc/name.rb +21 -0
- data/tasks/autodoc.rake +21 -0
- data/tasks/bump/bump_workflow.rb +49 -0
- data/tasks/bump/cargo_lockfile.rb +21 -0
- data/tasks/bump/changelog.rb +104 -0
- data/tasks/bump/header.rb +32 -0
- data/tasks/bump/history.rb +32 -0
- data/tasks/bump/links.rb +69 -0
- data/tasks/bump/manifest.rb +33 -0
- data/tasks/bump/patch_release.rb +19 -0
- data/tasks/bump/release_branch.rb +17 -0
- data/tasks/bump/release_from_trunk.rb +49 -0
- data/tasks/bump/repository.rb +54 -0
- data/tasks/bump/ruby_gem.rb +29 -0
- data/tasks/bump/sem_ver.rb +44 -0
- data/tasks/bump/unreleased_section.rb +73 -0
- data/tasks/bump.rake +61 -0
- data/tasks/doc/documentation.rb +59 -0
- data/tasks/doc/link/file_url.rb +30 -0
- data/tasks/doc/link/relative_path.rb +61 -0
- data/tasks/doc/link/web_url.rb +55 -0
- data/tasks/doc/link.rb +52 -0
- data/tasks/doc/link_audit.rb +116 -0
- data/tasks/doc/problem.rb +40 -0
- data/tasks/doc/source_file.rb +93 -0
- data/tasks/doc.rake +905 -0
- data/tasks/example_viewer.html.erb +172 -0
- data/tasks/extension.rake +14 -0
- data/tasks/license/headers_md.rb +223 -0
- data/tasks/license/headers_rb.rb +210 -0
- data/tasks/license/license_utils.rb +130 -0
- data/tasks/license/snippets_md.rb +315 -0
- data/tasks/license/snippets_rdoc.rb +150 -0
- data/tasks/license.rake +91 -0
- data/tasks/lint.rake +170 -0
- data/tasks/rbs_predicates/predicate_catalog.rb +52 -0
- data/tasks/rbs_predicates/predicate_tests.rb +124 -0
- data/tasks/rbs_predicates/rbs_signature.rb +63 -0
- data/tasks/rbs_predicates.rake +31 -0
- data/tasks/rdoc_config.rb +29 -0
- data/tasks/resources/build.yml.erb +60 -0
- data/tasks/resources/index.html.erb +141 -0
- data/tasks/resources/rubies.yml +7 -0
- data/tasks/sourcehut.rake +122 -0
- data/tasks/steep.rake +11 -0
- data/tasks/terminal_preview/app_screenshot.rb +45 -0
- data/tasks/terminal_preview/crash_report.rb +54 -0
- data/tasks/terminal_preview/example_app.rb +27 -0
- data/tasks/terminal_preview/launcher_script.rb +48 -0
- data/tasks/terminal_preview/preview_collection.rb +60 -0
- data/tasks/terminal_preview/preview_timing.rb +24 -0
- data/tasks/terminal_preview/safety_confirmation.rb +58 -0
- data/tasks/terminal_preview/saved_screenshot.rb +56 -0
- data/tasks/terminal_preview/system_appearance.rb +13 -0
- data/tasks/terminal_preview/terminal_window.rb +138 -0
- data/tasks/terminal_preview/window_id.rb +16 -0
- data/tasks/terminal_preview.rake +30 -0
- data/tasks/test.rake +36 -0
- data/tasks/website/index_page.rb +30 -0
- data/tasks/website/version.rb +122 -0
- data/tasks/website/version_menu.rb +68 -0
- data/tasks/website/versioned_documentation.rb +83 -0
- data/tasks/website/website.rb +53 -0
- data/tasks/website.rake +28 -0
- metadata +256 -1
|
@@ -253,6 +253,39 @@ module RatatuiRuby
|
|
|
253
253
|
else false
|
|
254
254
|
end
|
|
255
255
|
end
|
|
256
|
+
|
|
257
|
+
alias wheel_up? scroll_up?
|
|
258
|
+
alias wheel_down? scroll_down?
|
|
259
|
+
|
|
260
|
+
# Returns true for any scroll event.
|
|
261
|
+
#
|
|
262
|
+
# event.scroll? # => true for scroll_up or scroll_down
|
|
263
|
+
def scroll?
|
|
264
|
+
scroll_up? || scroll_down?
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
alias primary? left?
|
|
268
|
+
alias secondary? right?
|
|
269
|
+
alias context_menu? right?
|
|
270
|
+
alias aux? middle?
|
|
271
|
+
alias auxiliary? aux?
|
|
272
|
+
|
|
273
|
+
# Returns true for mouse movement without button press.
|
|
274
|
+
#
|
|
275
|
+
# event.moved? # => true for moved (no button)
|
|
276
|
+
def moved?
|
|
277
|
+
@kind == "moved"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
alias hover? moved?
|
|
281
|
+
alias hovering? moved?
|
|
282
|
+
alias move? moved?
|
|
283
|
+
alias dragging? drag?
|
|
284
|
+
|
|
285
|
+
alias release? up?
|
|
286
|
+
alias released? up?
|
|
287
|
+
alias press? down?
|
|
288
|
+
alias pressed? down?
|
|
256
289
|
end
|
|
257
290
|
end
|
|
258
291
|
end
|
|
@@ -67,6 +67,9 @@ module RatatuiRuby
|
|
|
67
67
|
def paste?
|
|
68
68
|
true
|
|
69
69
|
end
|
|
70
|
+
alias clipboard? paste?
|
|
71
|
+
alias pasteboard? paste?
|
|
72
|
+
alias pasted? paste?
|
|
70
73
|
|
|
71
74
|
# Creates a new Paste event.
|
|
72
75
|
#
|
|
@@ -100,6 +103,28 @@ module RatatuiRuby
|
|
|
100
103
|
return false unless other.is_a?(Paste)
|
|
101
104
|
content == other.content
|
|
102
105
|
end
|
|
106
|
+
|
|
107
|
+
# Returns true if the pasted content is empty.
|
|
108
|
+
def empty?
|
|
109
|
+
@content.empty?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Returns true if the pasted content is empty or whitespace-only.
|
|
113
|
+
def blank?
|
|
114
|
+
@content.strip.empty?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Returns true if the pasted content spans multiple lines.
|
|
118
|
+
def multiline?
|
|
119
|
+
@content.include?("\n")
|
|
120
|
+
end
|
|
121
|
+
alias multi_line? multiline?
|
|
122
|
+
|
|
123
|
+
# Returns true if the pasted content is a single line.
|
|
124
|
+
def single_line?
|
|
125
|
+
!multiline?
|
|
126
|
+
end
|
|
127
|
+
alias singleline? single_line?
|
|
103
128
|
end
|
|
104
129
|
end
|
|
105
130
|
end
|
|
@@ -151,6 +151,71 @@ module RatatuiRuby
|
|
|
151
151
|
else false
|
|
152
152
|
end
|
|
153
153
|
end
|
|
154
|
+
|
|
155
|
+
# Returns true. Unix <tt>SIGWINCH</tt> triggers terminal resize.
|
|
156
|
+
#
|
|
157
|
+
# event.sigwinch? # => true
|
|
158
|
+
def sigwinch?
|
|
159
|
+
true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
alias winch? sigwinch?
|
|
163
|
+
alias sig_winch? sigwinch?
|
|
164
|
+
|
|
165
|
+
alias terminal_resize? resize?
|
|
166
|
+
alias window_resize? resize?
|
|
167
|
+
alias window_change? resize?
|
|
168
|
+
alias viewport_resize? resize?
|
|
169
|
+
alias viewport_change? resize?
|
|
170
|
+
alias size_change? resize?
|
|
171
|
+
alias resized? resize?
|
|
172
|
+
|
|
173
|
+
VT100_WIDTH = 80 # :nodoc:
|
|
174
|
+
VT100_HEIGHT = 24 # :nodoc:
|
|
175
|
+
|
|
176
|
+
# Returns true if width exceeds height.
|
|
177
|
+
#
|
|
178
|
+
# Event::Resize.new(width: 120, height: 24).landscape? # => true
|
|
179
|
+
def landscape?
|
|
180
|
+
@width > @height
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Returns true if height exceeds or equals width.
|
|
184
|
+
#
|
|
185
|
+
# Event::Resize.new(width: 40, height: 80).portrait? # => true
|
|
186
|
+
def portrait?
|
|
187
|
+
@height >= @width
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Returns true if dimensions are exactly 80x24.
|
|
191
|
+
#
|
|
192
|
+
# Event::Resize.new(width: 80, height: 24).vt100? # => true
|
|
193
|
+
def vt100?
|
|
194
|
+
@width == VT100_WIDTH && @height == VT100_HEIGHT
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Returns true if both dimensions meet or exceed 80x24.
|
|
198
|
+
#
|
|
199
|
+
# Event::Resize.new(width: 120, height: 40).at_least_vt100? # => true
|
|
200
|
+
def at_least_vt100?
|
|
201
|
+
@width >= VT100_WIDTH && @height >= VT100_HEIGHT
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Returns true if both dimensions exceed 80x24.
|
|
205
|
+
#
|
|
206
|
+
# Event::Resize.new(width: 81, height: 25).over_vt100? # => true
|
|
207
|
+
def over_vt100?
|
|
208
|
+
@width > VT100_WIDTH && @height > VT100_HEIGHT
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Returns true if either dimension falls below VT100 standard.
|
|
212
|
+
#
|
|
213
|
+
# Event::Resize.new(width: 60, height: 24).cramped? # => true
|
|
214
|
+
def cramped?
|
|
215
|
+
@width < VT100_WIDTH || @height < VT100_HEIGHT
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
alias constrained? cramped?
|
|
154
219
|
end
|
|
155
220
|
end
|
|
156
221
|
end
|
data/lib/ratatui_ruby/version.rb
CHANGED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
#
|
|
6
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
7
|
+
#++
|
|
8
|
+
|
|
9
|
+
# !/usr/bin/env ruby
|
|
10
|
+
|
|
11
|
+
# Migration script to refactor widget renderers from Frame to Buffer
|
|
12
|
+
|
|
13
|
+
require "fileutils"
|
|
14
|
+
|
|
15
|
+
WIDGETS_DIR = "/Users/kerrick/Developer/ratatui_ruby/ext/ratatui_ruby/src/widgets"
|
|
16
|
+
|
|
17
|
+
# Files to update (excluding block.rs which is already done)
|
|
18
|
+
WIDGET_FILES = %w[
|
|
19
|
+
barchart.rs
|
|
20
|
+
calendar.rs
|
|
21
|
+
canvas.rs
|
|
22
|
+
center.rs
|
|
23
|
+
chart.rs
|
|
24
|
+
clear.rs
|
|
25
|
+
cursor.rs
|
|
26
|
+
gauge.rs
|
|
27
|
+
layout.rs
|
|
28
|
+
line_gauge.rs
|
|
29
|
+
list.rs
|
|
30
|
+
overlay.rs
|
|
31
|
+
paragraph.rs
|
|
32
|
+
ratatui_logo.rs
|
|
33
|
+
ratatui_mascot.rs
|
|
34
|
+
scrollbar.rs
|
|
35
|
+
sparkline.rs
|
|
36
|
+
table.rs
|
|
37
|
+
tabs.rs
|
|
38
|
+
].freeze
|
|
39
|
+
|
|
40
|
+
def migrate_file(filepath)
|
|
41
|
+
puts "Migrating #{File.basename(filepath)}..."
|
|
42
|
+
|
|
43
|
+
content = File.read(filepath)
|
|
44
|
+
original_content = content.dup
|
|
45
|
+
|
|
46
|
+
# 1. Update function signature
|
|
47
|
+
content.gsub!("pub fn render(frame: &mut Frame,", "pub fn render(buffer: &mut Buffer,")
|
|
48
|
+
content.gsub!("pub fn render_ratatui_mascot(frame: &mut Frame,", "pub fn render_ratatui_mascot(buffer: &mut Buffer,")
|
|
49
|
+
|
|
50
|
+
# 2. Update imports - Add Buffer, remove Frame
|
|
51
|
+
# Handle various import patterns
|
|
52
|
+
content.gsub!(/use ratatui::\{([^}]*),\s*Frame\s*\};/, 'use ratatui::{\1};')
|
|
53
|
+
content.gsub!(/use ratatui::\{Frame,\s*([^}]*)\};/, 'use ratatui::{\1};')
|
|
54
|
+
content.gsub!("use ratatui::Frame;", "")
|
|
55
|
+
|
|
56
|
+
# Add Buffer import if not present
|
|
57
|
+
unless content.match?(/use ratatui::(?:\{[^}]*)?buffer::Buffer/)
|
|
58
|
+
# Find the ratatui use statement and add buffer::Buffer
|
|
59
|
+
content.gsub!("use ratatui::{", "use ratatui::{buffer::Buffer, ")
|
|
60
|
+
content.gsub!("use ratatui::layout::Rect;", "use ratatui::{buffer::Buffer, layout::Rect};")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# 3. Update widget.render calls
|
|
64
|
+
# frame.render_widget(widget, area) → widget.render(area, buffer)
|
|
65
|
+
content.gsub!(/frame\.render_widget\(([^,]+),\s*([^)]+)\)/, '\1.render(\2, buffer)')
|
|
66
|
+
|
|
67
|
+
# 4. Update direct buffer access
|
|
68
|
+
content.gsub!("frame.buffer_mut()", "buffer")
|
|
69
|
+
|
|
70
|
+
# 5. Update recursive render_node calls
|
|
71
|
+
content.gsub!("render_node(frame,", "render_node(buffer,")
|
|
72
|
+
|
|
73
|
+
# 5.5. Update stateful widget rendering
|
|
74
|
+
# frame.render_stateful_widget(widget, area, state) → StatefulWidget::render(widget, area, buffer, state)
|
|
75
|
+
content.gsub!(/frame\.render_stateful_widget\(([^,]+),\s*([^,]+),\s*([^)]+)\)/, 'StatefulWidget::render(\1, \2, buffer, \3)')
|
|
76
|
+
|
|
77
|
+
# Add StatefulWidget import if stateful widgets are used
|
|
78
|
+
if content.match?(/StatefulWidget::render/) && !content.match?(/use ratatui::widgets::StatefulWidget/) && content.match?(/use ratatui::/)
|
|
79
|
+
content.sub!("use ratatui::{", "use ratatui::{widgets::StatefulWidget, ")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# 6. Clean up any double-added Buffer imports and duplicate Widget imports
|
|
83
|
+
content.gsub!(/buffer::Buffer,\s*buffer::Buffer,/, "buffer::Buffer,")
|
|
84
|
+
content.gsub!(/widgets::Widget,\s*widgets::Widget/, "widgets::Widget")
|
|
85
|
+
content.gsub!(/(use ratatui::\{[^}]*widgets::Widget[^}]*),\s*widgets::Widget/, '\1')
|
|
86
|
+
|
|
87
|
+
# 7. Fix Widget trait usage - make sure Widget is imported where .render is called
|
|
88
|
+
# Add Widget to imports if calling .render on widgets
|
|
89
|
+
if content.match?(/\.render\(area,\s*buffer\)/) && !content.match?(/use ratatui::widgets::Widget/) && content.match?(/use ratatui::\{/) && !content.match?(/widgets::Widget/)
|
|
90
|
+
content.sub!("use ratatui::{", "use ratatui::{widgets::Widget, ")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# 8. For files that don't have proper Buffer imports yet, add them
|
|
94
|
+
if !content.match?(/use ratatui::\{[^}]*buffer::Buffer/) && content.match?(/use ratatui::/)
|
|
95
|
+
# Try to add to first ratatui import
|
|
96
|
+
content.sub!("use ratatui::", "use ratatui::{buffer::Buffer};\nuse ratatui::")
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# 9. Special case: cursor.rs uses frame.set_cursor_position which doesn't exist on Buffer
|
|
100
|
+
# Cursor widget needs special handling - it can't work with just Buffer
|
|
101
|
+
if File.basename(filepath) == "cursor.rs"
|
|
102
|
+
puts " ⚠ cursor.rs requires special handling - skipping set_cursor_position"
|
|
103
|
+
# This widget can't be fully migrated as set_cursor_position is Frame-only
|
|
104
|
+
# Will need manual fix or different approach
|
|
105
|
+
end
|
|
106
|
+
# Only write if content changed
|
|
107
|
+
if content != original_content
|
|
108
|
+
File.write(filepath, content)
|
|
109
|
+
puts " ✓ Updated #{File.basename(filepath)}"
|
|
110
|
+
true
|
|
111
|
+
else
|
|
112
|
+
puts " - No changes needed for #{File.basename(filepath)}"
|
|
113
|
+
false
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def main
|
|
118
|
+
puts "Starting widget renderer migration..."
|
|
119
|
+
puts "=" * 60
|
|
120
|
+
|
|
121
|
+
updated_count = 0
|
|
122
|
+
|
|
123
|
+
WIDGET_FILES.each do |filename|
|
|
124
|
+
filepath = File.join(WIDGETS_DIR, filename)
|
|
125
|
+
|
|
126
|
+
unless File.exist?(filepath)
|
|
127
|
+
puts " ⚠ File not found: #{filename}"
|
|
128
|
+
next
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Create backup
|
|
132
|
+
backup_path = "#{filepath}.premigration"
|
|
133
|
+
FileUtils.cp(filepath, backup_path) unless File.exist?(backup_path)
|
|
134
|
+
|
|
135
|
+
updated_count += 1 if migrate_file(filepath)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
puts "=" * 60
|
|
139
|
+
puts "Migration complete!"
|
|
140
|
+
puts " Files updated: #{updated_count}/#{WIDGET_FILES.length}"
|
|
141
|
+
puts "\nBackups saved with .premigration extension"
|
|
142
|
+
puts "Run 'bundle exec rake compile' to verify the changes"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
main if __FILE__ == $PROGRAM_NAME
|
data/mise.toml
ADDED
data/sig/ratatui_ruby/event.rbs
CHANGED
|
@@ -67,11 +67,46 @@ module RatatuiRuby
|
|
|
67
67
|
private def match_system_dwim?: (String key_name, Symbol key_sym) -> bool
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# DWIM predicates for common key patterns
|
|
71
|
+
module Dwim
|
|
72
|
+
NAVIGATION_KEYS: Array[String]
|
|
73
|
+
ARROW_KEYS: Array[String]
|
|
74
|
+
VIM_MOVEMENT_KEYS: Array[String]
|
|
75
|
+
PUNCTUATION_NAMES: Hash[Symbol, String]
|
|
76
|
+
|
|
77
|
+
def space?: () -> bool
|
|
78
|
+
def cr?: () -> bool
|
|
79
|
+
def letter?: () -> bool
|
|
80
|
+
def digit?: () -> bool
|
|
81
|
+
def alphanumeric?: () -> bool
|
|
82
|
+
def punctuation?: () -> bool
|
|
83
|
+
def whitespace?: () -> bool
|
|
84
|
+
def interrupt?: () -> bool
|
|
85
|
+
def eof?: () -> bool
|
|
86
|
+
def cancel?: () -> bool
|
|
87
|
+
def sigint?: () -> bool
|
|
88
|
+
def suspend?: () -> bool
|
|
89
|
+
def quit?: () -> bool
|
|
90
|
+
def navigation?: () -> bool
|
|
91
|
+
def arrow?: () -> bool
|
|
92
|
+
def vim?: () -> bool
|
|
93
|
+
def vim_left?: () -> bool
|
|
94
|
+
def vim_down?: () -> bool
|
|
95
|
+
def vim_up?: () -> bool
|
|
96
|
+
def vim_right?: () -> bool
|
|
97
|
+
def vim_word_forward?: () -> bool
|
|
98
|
+
def vim_word_backward?: () -> bool
|
|
99
|
+
def vim_top?: () -> bool
|
|
100
|
+
def vim_bottom?: () -> bool
|
|
101
|
+
def quote?: () -> bool
|
|
102
|
+
end
|
|
103
|
+
|
|
70
104
|
include Character
|
|
71
105
|
include Modifier
|
|
72
106
|
include Media
|
|
73
107
|
include Navigation
|
|
74
108
|
include System
|
|
109
|
+
include Dwim
|
|
75
110
|
|
|
76
111
|
attr_reader code: String
|
|
77
112
|
attr_reader modifiers: Array[String]
|
|
@@ -114,6 +149,23 @@ module RatatuiRuby
|
|
|
114
149
|
def left?: () -> bool
|
|
115
150
|
def right?: () -> bool
|
|
116
151
|
def middle?: () -> bool
|
|
152
|
+
def scroll?: () -> bool
|
|
153
|
+
def moved?: () -> bool
|
|
154
|
+
def hover?: () -> bool
|
|
155
|
+
def hovering?: () -> bool
|
|
156
|
+
def move?: () -> bool
|
|
157
|
+
def primary?: () -> bool
|
|
158
|
+
def secondary?: () -> bool
|
|
159
|
+
def context_menu?: () -> bool
|
|
160
|
+
def aux?: () -> bool
|
|
161
|
+
def auxiliary?: () -> bool
|
|
162
|
+
def wheel_up?: () -> bool
|
|
163
|
+
def wheel_down?: () -> bool
|
|
164
|
+
def release?: () -> bool
|
|
165
|
+
def released?: () -> bool
|
|
166
|
+
def press?: () -> bool
|
|
167
|
+
def pressed?: () -> bool
|
|
168
|
+
def dragging?: () -> bool
|
|
117
169
|
def to_sym: () -> Symbol
|
|
118
170
|
def ==: (top other) -> bool
|
|
119
171
|
def deconstruct_keys: (Array[Symbol]?) -> { type: :mouse, kind: String, x: Integer, y: Integer, button: String, modifiers: Array[String] }
|
|
@@ -127,6 +179,20 @@ module RatatuiRuby
|
|
|
127
179
|
def to_sym: () -> Symbol
|
|
128
180
|
def ==: (top other) -> bool
|
|
129
181
|
def deconstruct_keys: (Array[Symbol]?) -> { type: :resize, width: Integer, height: Integer }
|
|
182
|
+
|
|
183
|
+
# DWIM predicates
|
|
184
|
+
VT100_WIDTH: Integer
|
|
185
|
+
VT100_HEIGHT: Integer
|
|
186
|
+
def sigwinch?: () -> bool
|
|
187
|
+
def winch?: () -> bool
|
|
188
|
+
def sig_winch?: () -> bool
|
|
189
|
+
def landscape?: () -> bool
|
|
190
|
+
def portrait?: () -> bool
|
|
191
|
+
def vt100?: () -> bool
|
|
192
|
+
def at_least_vt100?: () -> bool
|
|
193
|
+
def over_vt100?: () -> bool
|
|
194
|
+
def cramped?: () -> bool
|
|
195
|
+
def constrained?: () -> bool
|
|
130
196
|
end
|
|
131
197
|
|
|
132
198
|
class Paste < Event
|
|
@@ -134,14 +200,45 @@ module RatatuiRuby
|
|
|
134
200
|
|
|
135
201
|
def initialize: (content: String) -> void
|
|
136
202
|
def deconstruct_keys: (Array[Symbol]?) -> { type: :paste, content: String }
|
|
203
|
+
|
|
204
|
+
# DWIM predicates
|
|
205
|
+
def clipboard?: () -> bool
|
|
206
|
+
def pasteboard?: () -> bool
|
|
207
|
+
def pasted?: () -> bool
|
|
208
|
+
def empty?: () -> bool
|
|
209
|
+
def blank?: () -> bool
|
|
210
|
+
def multiline?: () -> bool
|
|
211
|
+
def multi_line?: () -> bool
|
|
212
|
+
def single_line?: () -> bool
|
|
213
|
+
def singleline?: () -> bool
|
|
137
214
|
end
|
|
138
215
|
|
|
139
216
|
class FocusGained < Event
|
|
140
217
|
def deconstruct_keys: (Array[Symbol]?) -> { type: :focus_gained }
|
|
218
|
+
|
|
219
|
+
# DWIM predicates
|
|
220
|
+
def focus?: () -> bool
|
|
221
|
+
def gained?: () -> bool
|
|
222
|
+
def lost?: () -> bool
|
|
223
|
+
def blur?: () -> bool
|
|
224
|
+
def active?: () -> bool
|
|
225
|
+
def inactive?: () -> bool
|
|
226
|
+
def foreground?: () -> bool
|
|
227
|
+
def background?: () -> bool
|
|
141
228
|
end
|
|
142
229
|
|
|
143
230
|
class FocusLost < Event
|
|
144
231
|
def deconstruct_keys: (Array[Symbol]?) -> { type: :focus_lost }
|
|
232
|
+
|
|
233
|
+
# DWIM predicates
|
|
234
|
+
def focus?: () -> bool
|
|
235
|
+
def gained?: () -> bool
|
|
236
|
+
def lost?: () -> bool
|
|
237
|
+
def blur?: () -> bool
|
|
238
|
+
def active?: () -> bool
|
|
239
|
+
def inactive?: () -> bool
|
|
240
|
+
def foreground?: () -> bool
|
|
241
|
+
def background?: () -> bool
|
|
145
242
|
end
|
|
146
243
|
|
|
147
244
|
class None < Event
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module Autodoc
|
|
9
|
+
class Examples
|
|
10
|
+
def self.sync
|
|
11
|
+
new.sync
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def sync
|
|
15
|
+
Dir.glob("{README.md,doc/**/*.md,examples/*/README.md}").each do |readme_path|
|
|
16
|
+
sync_readme(readme_path)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private def sync_readme(readme_path)
|
|
21
|
+
content = File.read(readme_path)
|
|
22
|
+
dir = File.dirname(readme_path)
|
|
23
|
+
|
|
24
|
+
new_content = content.gsub(/<!-- SYNC:START:([^ ]+) -->.*?<!-- SYNC:END -->/m) do
|
|
25
|
+
marker_info = $1
|
|
26
|
+
source_rel_path, segment_id = marker_info.split(":")
|
|
27
|
+
|
|
28
|
+
# Support both repo-root-relative paths (no leading ./) and file-relative paths
|
|
29
|
+
source_path = if source_rel_path.start_with?("./", "../")
|
|
30
|
+
File.join(dir, source_rel_path)
|
|
31
|
+
else
|
|
32
|
+
source_rel_path # Already relative to repo root
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
unless File.exist?(source_path)
|
|
36
|
+
warn "Warning: Source file not found: #{source_path}"
|
|
37
|
+
next $&
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
source_content = File.read(source_path)
|
|
41
|
+
extracted_content = if segment_id
|
|
42
|
+
extract_segment(source_content, segment_id, source_path)
|
|
43
|
+
else
|
|
44
|
+
source_content
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Detect language from extension
|
|
48
|
+
ext = File.extname(source_path).delete(".")
|
|
49
|
+
lang = (ext == "rb") ? "ruby" : ext
|
|
50
|
+
|
|
51
|
+
# Build replacement
|
|
52
|
+
"<!-- SYNC:START:#{marker_info} -->\n```#{lang}\n#{extracted_content}```\n<!-- SYNC:END -->"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if new_content != content
|
|
56
|
+
puts "Syncing #{readme_path}..."
|
|
57
|
+
File.write(readme_path, new_content)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def extract_segment(content, segment_id, source_path)
|
|
62
|
+
start_marker = /#\s*\[SYNC:START:#{segment_id}\]/
|
|
63
|
+
end_marker = /#\s*\[SYNC:END:#{segment_id}\]/
|
|
64
|
+
|
|
65
|
+
lines = content.lines
|
|
66
|
+
start_idx = lines.find_index { |l| l =~ start_marker }
|
|
67
|
+
end_idx = lines.find_index { |l| l =~ end_marker }
|
|
68
|
+
|
|
69
|
+
if start_idx && end_idx
|
|
70
|
+
"#{unindent(lines[(start_idx + 1)...end_idx].join).strip}\n"
|
|
71
|
+
else
|
|
72
|
+
warn "Warning: Segment '#{segment_id}' not found in #{source_path}"
|
|
73
|
+
content # Fallback to full content or error? Let's fallback to original for now.
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def unindent(text)
|
|
78
|
+
lines = text.lines
|
|
79
|
+
# Don't unindent if empty or just one line
|
|
80
|
+
return text if lines.empty?
|
|
81
|
+
|
|
82
|
+
# Find common leading whitespace
|
|
83
|
+
indentation = lines.grep(/\S/).map { |l| l[/^\s*/].length }.min || 0
|
|
84
|
+
lines.map { |l| (l.length > indentation) ? l[indentation..-1] : "#{l.strip}\n" }.join
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module Autodoc
|
|
9
|
+
module Member
|
|
10
|
+
class Delegate < Data.define(:name)
|
|
11
|
+
def rbs
|
|
12
|
+
" def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def rdoc
|
|
16
|
+
[
|
|
17
|
+
" # :method: #{name}",
|
|
18
|
+
" # :call-seq: #{name}(*args, **kwargs, &block)",
|
|
19
|
+
" #",
|
|
20
|
+
" # Delegates to RatatuiRuby.#{name}.",
|
|
21
|
+
" #",
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Factory < Data.define(:name, :const_name)
|
|
27
|
+
def rbs
|
|
28
|
+
" def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def rdoc
|
|
32
|
+
[
|
|
33
|
+
" # :method: #{name}",
|
|
34
|
+
" # :call-seq: #{name}(*args, **kwargs, &block)",
|
|
35
|
+
" #",
|
|
36
|
+
" # Factory for RatatuiRuby::#{const_name}.new.",
|
|
37
|
+
" #",
|
|
38
|
+
]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class Helper < Data.define(:name, :class_method, :const_name)
|
|
43
|
+
def rbs
|
|
44
|
+
" def #{name}: (*untyped args, **untyped kwargs) ?{ (*untyped) -> untyped } -> untyped"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def rdoc
|
|
48
|
+
[
|
|
49
|
+
" # :method: #{name}",
|
|
50
|
+
" # :call-seq: #{name}(*args, **kwargs, &block)",
|
|
51
|
+
" #",
|
|
52
|
+
" # Helper for RatatuiRuby::#{const_name}.#{class_method}.",
|
|
53
|
+
" #",
|
|
54
|
+
]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
module Autodoc
|
|
9
|
+
class Name < Data.define(:string)
|
|
10
|
+
def snake
|
|
11
|
+
string.to_s
|
|
12
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
13
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
14
|
+
.downcase
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s
|
|
18
|
+
string.to_s
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/tasks/autodoc.rake
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
require_relative "autodoc/examples"
|
|
9
|
+
|
|
10
|
+
namespace :autodoc do
|
|
11
|
+
desc "Update all automatically generated documentation"
|
|
12
|
+
task all: [:examples]
|
|
13
|
+
|
|
14
|
+
desc "Sync code snippets in example READMEs with source files"
|
|
15
|
+
task :examples do
|
|
16
|
+
Autodoc::Examples.sync
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc "Update all automatically generated documentation"
|
|
21
|
+
task autodoc: "autodoc:all"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
|
|
5
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
6
|
+
#++
|
|
7
|
+
|
|
8
|
+
require_relative "repository"
|
|
9
|
+
require_relative "changelog"
|
|
10
|
+
|
|
11
|
+
# Base class for version bump workflows.
|
|
12
|
+
# Subclasses implement the template methods: prepare, release_on_branch, finalize.
|
|
13
|
+
class BumpWorkflow
|
|
14
|
+
def initialize(gem:, repository: Repository.new)
|
|
15
|
+
@gem = gem
|
|
16
|
+
@repository = repository
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call(segment)
|
|
20
|
+
@repository.assert_can_bump!(segment)
|
|
21
|
+
@target = @gem.version.next(segment)
|
|
22
|
+
|
|
23
|
+
prepare(segment)
|
|
24
|
+
release_on_branch
|
|
25
|
+
finalize
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
attr_reader :target
|
|
29
|
+
|
|
30
|
+
private def release_on_branch
|
|
31
|
+
changelog = Changelog.new
|
|
32
|
+
@commit_message = changelog.commit_message(target)
|
|
33
|
+
changelog.release(target)
|
|
34
|
+
@gem.update_version(target)
|
|
35
|
+
generate_ci_manifests
|
|
36
|
+
@repository.commit_all(@commit_message)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private def generate_ci_manifests
|
|
40
|
+
Rake::Task["sourcehut:build:manifest"].reenable
|
|
41
|
+
Rake::Task["sourcehut:build"].reenable
|
|
42
|
+
Rake::Task["sourcehut"].reenable
|
|
43
|
+
Rake::Task["sourcehut"].invoke
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Template methods for subclasses
|
|
47
|
+
private def prepare(segment) = nil
|
|
48
|
+
private def finalize = nil
|
|
49
|
+
end
|