ratatui_ruby 0.5.0 → 0.7.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 +1 -1
- data/.builds/ruby-3.3.yml +1 -1
- data/.builds/ruby-3.4.yml +1 -1
- data/.builds/ruby-4.0.0.yml +1 -1
- data/AGENTS.md +10 -4
- data/CHANGELOG.md +79 -7
- data/README.md +37 -5
- data/REUSE.toml +2 -7
- data/doc/application_architecture.md +96 -22
- data/doc/application_testing.md +76 -30
- data/doc/contributors/architectural_overhaul/chat_conversations.md +4952 -0
- data/doc/contributors/architectural_overhaul/implementation_plan.md +60 -0
- data/doc/contributors/architectural_overhaul/task.md +37 -0
- data/doc/contributors/design/ruby_frontend.md +288 -56
- data/doc/contributors/design/rust_backend.md +349 -54
- data/doc/contributors/developing_examples.md +134 -49
- data/doc/contributors/index.md +7 -5
- data/doc/contributors/v1.0.0_blockers.md +1729 -0
- data/doc/event_handling.md +11 -3
- data/doc/images/app_all_events.png +0 -0
- data/doc/images/app_color_picker.png +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_demo.png +0 -0
- data/doc/images/widget_block_demo.png +0 -0
- data/doc/images/widget_canvas_demo.png +0 -0
- data/doc/images/widget_cell_demo.png +0 -0
- data/doc/images/widget_center_demo.png +0 -0
- data/doc/images/widget_chart_demo.png +0 -0
- data/doc/images/widget_list_demo.png +0 -0
- data/doc/images/widget_overlay_demo.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_sparkline_demo.png +0 -0
- data/doc/images/widget_table_demo.png +0 -0
- data/doc/images/widget_tabs_demo.png +0 -0
- data/doc/images/widget_text_width.png +0 -0
- data/doc/index.md +11 -6
- data/doc/interactive_design.md +2 -2
- data/doc/quickstart.md +127 -165
- data/doc/terminal_limitations.md +92 -0
- data/doc/v0.7.0_migration.md +236 -0
- data/doc/why.md +93 -0
- data/examples/app_all_events/README.md +47 -27
- data/examples/app_all_events/app.rb +38 -35
- data/examples/app_all_events/model/app_model.rb +157 -0
- data/examples/app_all_events/model/event_entry.rb +17 -0
- data/examples/app_all_events/model/msg.rb +37 -0
- data/examples/app_all_events/update.rb +73 -0
- data/examples/app_all_events/view/app_view.rb +9 -9
- data/examples/app_all_events/view/controls_view.rb +9 -7
- data/examples/app_all_events/view/counts_view.rb +13 -9
- data/examples/app_all_events/view/live_view.rb +9 -8
- data/examples/app_all_events/view/log_view.rb +11 -16
- data/examples/app_color_picker/README.md +84 -42
- data/examples/app_color_picker/app.rb +24 -62
- data/examples/app_color_picker/controls.rb +90 -0
- data/examples/app_color_picker/copy_dialog.rb +45 -49
- data/examples/app_color_picker/export_pane.rb +126 -0
- data/examples/app_color_picker/input.rb +99 -67
- data/examples/app_color_picker/main_container.rb +178 -0
- data/examples/app_color_picker/palette.rb +55 -26
- data/examples/app_login_form/README.md +49 -0
- data/examples/app_login_form/app.rb +2 -3
- data/examples/app_stateful_interaction/README.md +33 -0
- data/examples/app_stateful_interaction/app.rb +272 -0
- data/examples/timeout_demo.rb +43 -0
- data/examples/verify_quickstart_dsl/README.md +49 -0
- data/examples/verify_quickstart_dsl/app.rb +2 -0
- data/examples/verify_quickstart_layout/README.md +71 -0
- data/examples/verify_quickstart_layout/app.rb +2 -0
- data/examples/verify_quickstart_lifecycle/README.md +56 -0
- data/examples/verify_quickstart_lifecycle/app.rb +10 -4
- data/examples/verify_readme_usage/README.md +43 -0
- data/examples/verify_readme_usage/app.rb +8 -2
- data/examples/widget_barchart_demo/README.md +50 -0
- data/examples/widget_barchart_demo/app.rb +5 -5
- data/examples/widget_block_demo/README.md +36 -0
- data/examples/widget_block_demo/app.rb +256 -0
- data/examples/widget_box_demo/README.md +45 -0
- data/examples/widget_calendar_demo/README.md +39 -0
- data/examples/widget_calendar_demo/app.rb +5 -1
- data/examples/widget_canvas_demo/README.md +27 -0
- data/examples/widget_canvas_demo/app.rb +123 -0
- data/examples/widget_cell_demo/README.md +36 -0
- data/examples/widget_cell_demo/app.rb +31 -24
- data/examples/widget_center_demo/README.md +29 -0
- data/examples/widget_center_demo/app.rb +116 -0
- data/examples/widget_chart_demo/README.md +41 -0
- data/examples/widget_chart_demo/app.rb +7 -2
- data/examples/widget_gauge_demo/README.md +41 -0
- data/examples/widget_layout_split/README.md +44 -0
- data/examples/widget_line_gauge_demo/README.md +41 -0
- data/examples/widget_list_demo/README.md +49 -0
- data/examples/widget_list_demo/app.rb +91 -107
- data/examples/widget_map_demo/README.md +39 -0
- data/examples/{app_map_demo → widget_map_demo}/app.rb +4 -4
- data/examples/widget_overlay_demo/README.md +36 -0
- data/examples/widget_overlay_demo/app.rb +248 -0
- data/examples/widget_popup_demo/README.md +36 -0
- data/examples/widget_ratatui_logo_demo/README.md +34 -0
- data/examples/widget_ratatui_logo_demo/app.rb +1 -1
- data/examples/widget_ratatui_mascot_demo/README.md +34 -0
- data/examples/widget_rect/README.md +38 -0
- data/examples/widget_render/README.md +37 -0
- data/examples/widget_render/app.rb +3 -3
- data/examples/widget_rich_text/README.md +35 -0
- data/examples/widget_rich_text/app.rb +62 -33
- data/examples/widget_scroll_text/README.md +37 -0
- data/examples/widget_scroll_text/app.rb +0 -1
- data/examples/widget_scrollbar_demo/README.md +37 -0
- data/examples/widget_sparkline_demo/README.md +42 -0
- data/examples/widget_sparkline_demo/app.rb +4 -3
- data/examples/widget_style_colors/README.md +34 -0
- data/examples/widget_table_demo/README.md +48 -0
- data/examples/{app_table_select → widget_table_demo}/app.rb +65 -12
- data/examples/widget_tabs_demo/README.md +41 -0
- data/examples/widget_tabs_demo/app.rb +15 -1
- data/examples/widget_text_width/README.md +35 -0
- data/examples/widget_text_width/app.rb +113 -0
- data/exe/.gitkeep +0 -0
- data/ext/ratatui_ruby/Cargo.lock +11 -4
- data/ext/ratatui_ruby/Cargo.toml +2 -1
- data/ext/ratatui_ruby/src/events.rs +238 -26
- data/ext/ratatui_ruby/src/frame.rs +116 -3
- data/ext/ratatui_ruby/src/lib.rs +37 -6
- data/ext/ratatui_ruby/src/rendering.rs +22 -21
- data/ext/ratatui_ruby/src/string_width.rs +101 -0
- data/ext/ratatui_ruby/src/terminal.rs +39 -15
- data/ext/ratatui_ruby/src/text.rs +13 -4
- data/ext/ratatui_ruby/src/widgets/barchart.rs +24 -6
- data/ext/ratatui_ruby/src/widgets/canvas.rs +5 -5
- data/ext/ratatui_ruby/src/widgets/gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/line_gauge.rs +9 -2
- data/ext/ratatui_ruby/src/widgets/list.rs +179 -3
- data/ext/ratatui_ruby/src/widgets/list_state.rs +137 -0
- data/ext/ratatui_ruby/src/widgets/mod.rs +3 -0
- data/ext/ratatui_ruby/src/widgets/scrollbar.rs +93 -1
- data/ext/ratatui_ruby/src/widgets/scrollbar_state.rs +169 -0
- data/ext/ratatui_ruby/src/widgets/table.rs +191 -34
- data/ext/ratatui_ruby/src/widgets/table_state.rs +121 -0
- data/lib/ratatui_ruby/buffer/cell.rb +168 -0
- data/lib/ratatui_ruby/buffer.rb +15 -0
- data/lib/ratatui_ruby/cell.rb +4 -4
- data/lib/ratatui_ruby/event/key/character.rb +35 -0
- data/lib/ratatui_ruby/event/key/media.rb +44 -0
- data/lib/ratatui_ruby/event/key/modifier.rb +95 -0
- data/lib/ratatui_ruby/event/key/navigation.rb +55 -0
- data/lib/ratatui_ruby/event/key/system.rb +45 -0
- data/lib/ratatui_ruby/event/key.rb +111 -51
- data/lib/ratatui_ruby/event/mouse.rb +3 -3
- data/lib/ratatui_ruby/event/paste.rb +1 -1
- data/lib/ratatui_ruby/frame.rb +100 -4
- data/lib/ratatui_ruby/layout/constraint.rb +95 -0
- data/lib/ratatui_ruby/layout/layout.rb +106 -0
- data/lib/ratatui_ruby/layout/rect.rb +118 -0
- data/lib/ratatui_ruby/layout.rb +19 -0
- data/lib/ratatui_ruby/list_state.rb +88 -0
- data/lib/ratatui_ruby/schema/bar_chart/bar.rb +2 -2
- data/lib/ratatui_ruby/schema/cursor.rb +5 -0
- data/lib/ratatui_ruby/schema/gauge.rb +3 -1
- data/lib/ratatui_ruby/schema/layout.rb +1 -1
- data/lib/ratatui_ruby/schema/line_gauge.rb +2 -2
- data/lib/ratatui_ruby/schema/list.rb +25 -4
- data/lib/ratatui_ruby/schema/list_item.rb +41 -0
- data/lib/ratatui_ruby/schema/rect.rb +43 -0
- data/lib/ratatui_ruby/schema/row.rb +66 -0
- data/lib/ratatui_ruby/schema/style.rb +24 -4
- data/lib/ratatui_ruby/schema/table.rb +29 -11
- data/lib/ratatui_ruby/schema/text.rb +96 -3
- data/lib/ratatui_ruby/scrollbar_state.rb +112 -0
- data/lib/ratatui_ruby/style/style.rb +81 -0
- data/lib/ratatui_ruby/style.rb +15 -0
- data/lib/ratatui_ruby/table_state.rb +90 -0
- data/lib/ratatui_ruby/test_helper/event_injection.rb +169 -0
- data/lib/ratatui_ruby/test_helper/snapshot.rb +414 -0
- data/lib/ratatui_ruby/test_helper/style_assertions.rb +351 -0
- data/lib/ratatui_ruby/test_helper/terminal.rb +127 -0
- data/lib/ratatui_ruby/test_helper/test_doubles.rb +68 -0
- data/lib/ratatui_ruby/test_helper.rb +65 -358
- data/lib/ratatui_ruby/tui/buffer_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/canvas_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/core.rb +38 -0
- data/lib/ratatui_ruby/tui/layout_factories.rb +74 -0
- data/lib/ratatui_ruby/tui/state_factories.rb +33 -0
- data/lib/ratatui_ruby/tui/style_factories.rb +20 -0
- data/lib/ratatui_ruby/tui/text_factories.rb +44 -0
- data/lib/ratatui_ruby/tui/widget_factories.rb +195 -0
- data/lib/ratatui_ruby/tui.rb +75 -0
- data/lib/ratatui_ruby/version.rb +1 -1
- data/lib/ratatui_ruby/widgets/bar_chart/bar.rb +47 -0
- data/lib/ratatui_ruby/widgets/bar_chart/bar_group.rb +25 -0
- data/lib/ratatui_ruby/widgets/bar_chart.rb +239 -0
- data/lib/ratatui_ruby/widgets/block.rb +192 -0
- data/lib/ratatui_ruby/widgets/calendar.rb +84 -0
- data/lib/ratatui_ruby/widgets/canvas.rb +231 -0
- data/lib/ratatui_ruby/widgets/cell.rb +47 -0
- data/lib/ratatui_ruby/widgets/center.rb +59 -0
- data/lib/ratatui_ruby/widgets/chart.rb +185 -0
- data/lib/ratatui_ruby/widgets/clear.rb +54 -0
- data/lib/ratatui_ruby/widgets/cursor.rb +42 -0
- data/lib/ratatui_ruby/widgets/gauge.rb +72 -0
- data/lib/ratatui_ruby/widgets/line_gauge.rb +80 -0
- data/lib/ratatui_ruby/widgets/list.rb +127 -0
- data/lib/ratatui_ruby/widgets/list_item.rb +43 -0
- data/lib/ratatui_ruby/widgets/overlay.rb +43 -0
- data/lib/ratatui_ruby/widgets/paragraph.rb +99 -0
- data/lib/ratatui_ruby/widgets/ratatui_logo.rb +31 -0
- data/lib/ratatui_ruby/widgets/ratatui_mascot.rb +36 -0
- data/lib/ratatui_ruby/widgets/row.rb +68 -0
- data/lib/ratatui_ruby/widgets/scrollbar.rb +143 -0
- data/lib/ratatui_ruby/widgets/shape/label.rb +68 -0
- data/lib/ratatui_ruby/widgets/sparkline.rb +134 -0
- data/lib/ratatui_ruby/widgets/table.rb +141 -0
- data/lib/ratatui_ruby/widgets/tabs.rb +85 -0
- data/lib/ratatui_ruby/widgets.rb +40 -0
- data/lib/ratatui_ruby.rb +64 -57
- data/sig/examples/app_all_events/view.rbs +1 -1
- data/sig/examples/app_all_events/view_state.rbs +1 -1
- data/sig/examples/app_stateful_interaction/app.rbs +33 -0
- data/sig/examples/widget_block_demo/app.rbs +32 -0
- data/sig/examples/{app_map_demo → widget_map_demo}/app.rbs +2 -2
- data/sig/examples/{app_table_select → widget_table_demo}/app.rbs +2 -2
- data/sig/examples/{widget_table_flex → widget_text_width}/app.rbs +2 -3
- data/sig/ratatui_ruby/event.rbs +11 -1
- data/sig/ratatui_ruby/frame.rbs +2 -0
- data/sig/ratatui_ruby/list_state.rbs +13 -0
- data/sig/ratatui_ruby/ratatui_ruby.rbs +2 -2
- data/sig/ratatui_ruby/schema/bar_chart/bar.rbs +3 -3
- data/sig/ratatui_ruby/schema/gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/line_gauge.rbs +2 -2
- data/sig/ratatui_ruby/schema/list.rbs +4 -2
- data/sig/ratatui_ruby/schema/list_item.rbs +10 -0
- data/sig/ratatui_ruby/schema/rect.rbs +3 -0
- data/sig/ratatui_ruby/schema/row.rbs +22 -0
- data/sig/ratatui_ruby/schema/style.rbs +3 -3
- data/sig/ratatui_ruby/schema/table.rbs +3 -1
- data/sig/ratatui_ruby/schema/text.rbs +9 -6
- data/sig/ratatui_ruby/scrollbar_state.rbs +18 -0
- data/sig/ratatui_ruby/session.rbs +41 -48
- data/sig/ratatui_ruby/table_state.rbs +15 -0
- data/sig/ratatui_ruby/test_helper/event_injection.rbs +16 -0
- data/sig/ratatui_ruby/test_helper/snapshot.rbs +12 -0
- data/sig/ratatui_ruby/test_helper/style_assertions.rbs +64 -0
- data/sig/ratatui_ruby/test_helper/terminal.rbs +14 -0
- data/sig/ratatui_ruby/test_helper/test_doubles.rbs +22 -0
- data/sig/ratatui_ruby/test_helper.rbs +5 -4
- data/sig/ratatui_ruby/tui/buffer_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/canvas_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/core.rbs +14 -0
- data/sig/ratatui_ruby/tui/layout_factories.rbs +19 -0
- data/sig/ratatui_ruby/tui/state_factories.rbs +12 -0
- data/sig/ratatui_ruby/tui/style_factories.rbs +10 -0
- data/sig/ratatui_ruby/tui/text_factories.rbs +14 -0
- data/sig/ratatui_ruby/tui/widget_factories.rbs +39 -0
- data/sig/ratatui_ruby/tui.rbs +19 -0
- data/tasks/autodoc/examples.rb +79 -0
- data/tasks/autodoc.rake +7 -35
- data/tasks/bump/changelog.rb +3 -3
- data/tasks/bump/links.rb +67 -0
- data/tasks/sourcehut.rake +64 -21
- data/tasks/terminal_preview/app_screenshot.rb +13 -3
- data/tasks/terminal_preview/saved_screenshot.rb +4 -3
- metadata +169 -48
- data/doc/contributors/dwim_dx.md +0 -366
- data/doc/images/app_analytics.png +0 -0
- data/doc/images/app_custom_widget.png +0 -0
- data/doc/images/app_mouse_events.png +0 -0
- data/doc/images/app_table_select.png +0 -0
- data/doc/images/widget_block_padding.png +0 -0
- data/doc/images/widget_block_titles.png +0 -0
- data/doc/images/widget_list_styles.png +0 -0
- data/doc/images/widget_table_flex.png +0 -0
- data/examples/app_all_events/model/events.rb +0 -180
- data/examples/app_all_events/model/highlight.rb +0 -57
- data/examples/app_all_events/test/snapshots/after_focus_lost.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_focus_regained.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_horizontal_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_key_a.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_key_ctrl_x.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_mouse_click.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_mouse_drag.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_multiple_events.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_paste.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_right_click.txt +0 -24
- data/examples/app_all_events/test/snapshots/after_vertical_resize.txt +0 -24
- data/examples/app_all_events/test/snapshots/initial_state.txt +0 -24
- data/examples/app_all_events/view_state.rb +0 -42
- data/examples/app_color_picker/scene.rb +0 -201
- data/examples/widget_block_padding/app.rb +0 -67
- data/examples/widget_block_titles/app.rb +0 -69
- data/examples/widget_list_styles/app.rb +0 -141
- data/examples/widget_table_flex/app.rb +0 -95
- data/lib/ratatui_ruby/session/autodoc.rb +0 -417
- data/lib/ratatui_ruby/session.rb +0 -163
- data/sig/examples/widget_block_padding/app.rbs +0 -11
- data/sig/examples/widget_block_titles/app.rbs +0 -11
- data/sig/examples/widget_list_styles/app.rbs +0 -11
- data/tasks/autodoc/inventory.rb +0 -61
- data/tasks/autodoc/notice.rb +0 -26
- data/tasks/autodoc/rbs.rb +0 -38
- data/tasks/autodoc/rdoc.rb +0 -45
- data/tasks/bump/comparison_links.rb +0 -41
- /data/doc/images/{app_map_demo.png → widget_map_demo.png} +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
+
|
|
6
|
+
module Autodoc
|
|
7
|
+
class Examples
|
|
8
|
+
def self.sync
|
|
9
|
+
new.sync
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def sync
|
|
13
|
+
Dir.glob("{README.md,doc/*.md,examples/*/README.md}").each do |readme_path|
|
|
14
|
+
sync_readme(readme_path)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private def sync_readme(readme_path)
|
|
19
|
+
content = File.read(readme_path)
|
|
20
|
+
dir = File.dirname(readme_path)
|
|
21
|
+
|
|
22
|
+
new_content = content.gsub(/<!-- SYNC:START:([^ ]+) -->.*?<!-- SYNC:END -->/m) do
|
|
23
|
+
marker_info = $1
|
|
24
|
+
source_rel_path, segment_id = marker_info.split(":")
|
|
25
|
+
source_path = File.join(dir, source_rel_path)
|
|
26
|
+
|
|
27
|
+
unless File.exist?(source_path)
|
|
28
|
+
warn "Warning: Source file not found: #{source_path}"
|
|
29
|
+
next $&
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
source_content = File.read(source_path)
|
|
33
|
+
extracted_content = if segment_id
|
|
34
|
+
extract_segment(source_content, segment_id, source_path)
|
|
35
|
+
else
|
|
36
|
+
source_content
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Detect language from extension
|
|
40
|
+
ext = File.extname(source_path).delete(".")
|
|
41
|
+
lang = (ext == "rb") ? "ruby" : ext
|
|
42
|
+
|
|
43
|
+
# Build replacement
|
|
44
|
+
"<!-- SYNC:START:#{marker_info} -->\n```#{lang}\n#{extracted_content}```\n<!-- SYNC:END -->"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if new_content != content
|
|
48
|
+
puts "Syncing #{readme_path}..."
|
|
49
|
+
File.write(readme_path, new_content)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def extract_segment(content, segment_id, source_path)
|
|
54
|
+
start_marker = /#\s*\[SYNC:START:#{segment_id}\]/
|
|
55
|
+
end_marker = /#\s*\[SYNC:END:#{segment_id}\]/
|
|
56
|
+
|
|
57
|
+
lines = content.lines
|
|
58
|
+
start_idx = lines.find_index { |l| l =~ start_marker }
|
|
59
|
+
end_idx = lines.find_index { |l| l =~ end_marker }
|
|
60
|
+
|
|
61
|
+
if start_idx && end_idx
|
|
62
|
+
"#{unindent(lines[(start_idx + 1)...end_idx].join).strip}\n"
|
|
63
|
+
else
|
|
64
|
+
warn "Warning: Segment '#{segment_id}' not found in #{source_path}"
|
|
65
|
+
content # Fallback to full content or error? Let's fallback to original for now.
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def unindent(text)
|
|
70
|
+
lines = text.lines
|
|
71
|
+
# Don't unindent if empty or just one line
|
|
72
|
+
return text if lines.empty?
|
|
73
|
+
|
|
74
|
+
# Find common leading whitespace
|
|
75
|
+
indentation = lines.grep(/\S/).map { |l| l[/^\s*/].length }.min || 0
|
|
76
|
+
lines.map { |l| (l.length > indentation) ? l[indentation..-1] : "#{l.strip}\n" }.join
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
data/tasks/autodoc.rake
CHANGED
|
@@ -3,45 +3,17 @@
|
|
|
3
3
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
|
-
require_relative "autodoc/
|
|
7
|
-
require_relative "autodoc/notice"
|
|
8
|
-
require_relative "autodoc/rbs"
|
|
9
|
-
require_relative "autodoc/rdoc"
|
|
6
|
+
require_relative "autodoc/examples"
|
|
10
7
|
|
|
11
8
|
namespace :autodoc do
|
|
12
|
-
desc "
|
|
13
|
-
task all: [:
|
|
9
|
+
desc "Update all automatically generated documentation"
|
|
10
|
+
task all: [:examples]
|
|
14
11
|
|
|
15
|
-
desc "
|
|
16
|
-
task
|
|
17
|
-
|
|
18
|
-
desc "Generate all RDoc findings"
|
|
19
|
-
task rdoc: ["rdoc:session"]
|
|
20
|
-
|
|
21
|
-
namespace :rbs do
|
|
22
|
-
desc "Generate RBS for RatatuiRuby::Session"
|
|
23
|
-
task :session do
|
|
24
|
-
require_relative "../lib/ratatui_ruby"
|
|
25
|
-
|
|
26
|
-
Autodoc::Rbs.new(
|
|
27
|
-
path: File.expand_path("../sig/ratatui_ruby/session.rbs", __dir__),
|
|
28
|
-
notice: Autodoc::Notice.new("autodoc:rbs:session")
|
|
29
|
-
).write(Autodoc::Inventory.new)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
namespace :rdoc do
|
|
34
|
-
desc "Generate RDoc autodoc for RatatuiRuby::Session"
|
|
35
|
-
task :session do
|
|
36
|
-
require_relative "../lib/ratatui_ruby"
|
|
37
|
-
|
|
38
|
-
Autodoc::Rdoc.new(
|
|
39
|
-
path: File.expand_path("../lib/ratatui_ruby/session/autodoc.rb", __dir__),
|
|
40
|
-
notice: Autodoc::Notice.new("autodoc:rdoc:session")
|
|
41
|
-
).write(Autodoc::Inventory.new)
|
|
42
|
-
end
|
|
12
|
+
desc "Sync code snippets in example READMEs with source files"
|
|
13
|
+
task :examples do
|
|
14
|
+
Autodoc::Examples.sync
|
|
43
15
|
end
|
|
44
16
|
end
|
|
45
17
|
|
|
46
|
-
desc "
|
|
18
|
+
desc "Update all automatically generated documentation"
|
|
47
19
|
task autodoc: "autodoc:all"
|
data/tasks/bump/changelog.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
|
-
require_relative "
|
|
6
|
+
require_relative "links"
|
|
7
7
|
require_relative "unreleased_section"
|
|
8
8
|
require_relative "history"
|
|
9
9
|
require_relative "header"
|
|
@@ -22,13 +22,13 @@ class Changelog
|
|
|
22
22
|
|
|
23
23
|
header = Header.parse(content)
|
|
24
24
|
unreleased = UnreleasedSection.parse(content)
|
|
25
|
-
links =
|
|
25
|
+
links = Links.from_markdown(content)
|
|
26
26
|
|
|
27
27
|
raise "Could not parse CHANGELOG.md" unless header && unreleased && links
|
|
28
28
|
|
|
29
29
|
history = History.parse(content, header.length, unreleased.to_s.length, links.to_s)
|
|
30
30
|
|
|
31
|
-
links.
|
|
31
|
+
links.release(new_version)
|
|
32
32
|
history.add(unreleased.as_version(new_version))
|
|
33
33
|
|
|
34
34
|
File.write(@path, "#{header}#{UnreleasedSection.fresh}\n\n#{history}\n#{links}")
|
data/tasks/bump/links.rb
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SPDX-FileCopyrightText: 2025 Kerrick Long <me@kerricklong.com>
|
|
4
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
|
+
|
|
6
|
+
# Manages the version comparison links at the botton of the changelog.
|
|
7
|
+
#
|
|
8
|
+
# Release automation needs to update links. Manually calculating git diff URLs
|
|
9
|
+
# for every release is tedious and error-prone. SourceHut does not have
|
|
10
|
+
# standard comparison views, complicating matters further.
|
|
11
|
+
#
|
|
12
|
+
# This class manages the collection of links. It parses them from the markdown.
|
|
13
|
+
# It generates the correct tree links for SourceHut. It properly shifts the
|
|
14
|
+
# "Unreleased" pointer.
|
|
15
|
+
#
|
|
16
|
+
# Use it to update the changelog during a release.
|
|
17
|
+
class Links
|
|
18
|
+
PATTERN = /^(\[Unreleased\]: .*)$/m
|
|
19
|
+
UNRELEASED_PATTERN = %r{^\[Unreleased\]: (.*?/refs/)HEAD$}
|
|
20
|
+
|
|
21
|
+
# Creates a Links object from the full markdown content.
|
|
22
|
+
#
|
|
23
|
+
# [content] String. The full text of the changelog.
|
|
24
|
+
def self.from_markdown(content)
|
|
25
|
+
match = content.match(PATTERN)
|
|
26
|
+
return unless match
|
|
27
|
+
|
|
28
|
+
new(match[1].strip)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the raw text of the links.
|
|
32
|
+
attr_reader :text
|
|
33
|
+
|
|
34
|
+
# Creates a new Links object.
|
|
35
|
+
#
|
|
36
|
+
# [text] String. The raw text of the links section.
|
|
37
|
+
def initialize(text)
|
|
38
|
+
@text = text.dup
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Releases a new version.
|
|
42
|
+
#
|
|
43
|
+
# Updates the "Unreleased" link to point to the new head. Adds a new link for
|
|
44
|
+
# the just-released version pointing to its specific tag.
|
|
45
|
+
#
|
|
46
|
+
# [version] String. The new version number (e.g., <tt>"0.5.0"</tt>).
|
|
47
|
+
def release(version)
|
|
48
|
+
return unless base_url
|
|
49
|
+
|
|
50
|
+
new_unreleased = "[Unreleased]: #{base_url}HEAD" # .../HEAD
|
|
51
|
+
new_version_link = "[#{version}]: #{base_url}v#{version}" # .../v1.0.0
|
|
52
|
+
|
|
53
|
+
@text.sub!(UNRELEASED_PATTERN, "#{new_unreleased}\n#{new_version_link}")
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns the string representation of the links.
|
|
58
|
+
def to_s
|
|
59
|
+
@text
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The base URL for the repository's references.
|
|
63
|
+
private def base_url
|
|
64
|
+
match = @text.match(UNRELEASED_PATTERN)
|
|
65
|
+
match[1] if match
|
|
66
|
+
end
|
|
67
|
+
end
|
data/tasks/sourcehut.rake
CHANGED
|
@@ -4,35 +4,78 @@
|
|
|
4
4
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
5
5
|
|
|
6
6
|
desc "Generate SourceHut build manifests from template"
|
|
7
|
-
task :sourcehut
|
|
8
|
-
require "erb"
|
|
9
|
-
require "yaml"
|
|
7
|
+
task sourcehut: "sourcehut:build"
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
namespace :sourcehut do
|
|
10
|
+
desc "Build SourceHut manifests"
|
|
11
|
+
task build: "sourcehut:build:manifest"
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
namespace :build do
|
|
14
|
+
desc "Generate SourceHut build manifests from template"
|
|
15
|
+
task :manifest do
|
|
16
|
+
require "erb"
|
|
17
|
+
require "yaml"
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
spec = Gem::Specification.load("ratatui_ruby.gemspec")
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
# Read version directly from file to ensure we get the latest version
|
|
22
|
+
# even if it was just bumped in the same Rake execution
|
|
23
|
+
version_content = File.read("lib/ratatui_ruby/version.rb")
|
|
24
|
+
version = version_content.match(/VERSION = "(.+?)"/)[1]
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
gem_filename = "#{spec.name}-#{version}.gem"
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
erb = ERB.new(template, trim_mode: "-")
|
|
28
|
+
rubies = YAML.load_file("tasks/resources/rubies.yml")
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
bundler_version = File.read("Gemfile.lock").match(/BUNDLED WITH\n\s+([\d.]+)/)[1]
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
template = File.read("tasks/resources/build.yml.erb")
|
|
33
|
+
erb = ERB.new(template, trim_mode: "-")
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
FileUtils.mkdir_p ".builds"
|
|
36
|
+
|
|
37
|
+
# Remove old generated files to ensure a clean state
|
|
38
|
+
Dir.glob(".builds/*.yml").each { |f| File.delete(f) }
|
|
39
|
+
|
|
40
|
+
rubies.each do |ruby_version|
|
|
41
|
+
filename = ".builds/ruby-#{ruby_version}.yml"
|
|
42
|
+
puts "Generating #{filename}..."
|
|
43
|
+
content = erb.result_with_hash(ruby_version:, gem_filename:, bundler_version:)
|
|
44
|
+
File.write(filename, content)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc "Update stable branch to match release and set as default"
|
|
50
|
+
task :update_stable do
|
|
51
|
+
# Read version to determine tag
|
|
52
|
+
version_content = File.read("lib/ratatui_ruby/version.rb")
|
|
53
|
+
version = version_content.match(/VERSION = "(.+?)"/)[1]
|
|
54
|
+
tag_name = "v#{version}"
|
|
55
|
+
|
|
56
|
+
# Verify that the version file matches the actual git tag
|
|
57
|
+
# This prevents updating stable to the wrong version if the release failed
|
|
58
|
+
latest_tag = `git describe --tags --abbrev=0`.strip
|
|
59
|
+
if latest_tag != tag_name
|
|
60
|
+
abort "Fatal: Version mismatch! 'lib/ratatui_ruby/version.rb' says #{tag_name}, but the latest git tag is #{latest_tag}."
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
puts "Updating stable branch to point to #{tag_name}..."
|
|
64
|
+
# Resolve the tag to a commit hash (peel annotated tags)
|
|
65
|
+
# This renders a commit SHA that can be pushed to a branch head
|
|
66
|
+
commit_sha = `git rev-parse #{tag_name}^{}`.strip
|
|
67
|
+
|
|
68
|
+
# Update local stable branch to match
|
|
69
|
+
sh "git branch -f stable #{commit_sha}"
|
|
70
|
+
|
|
71
|
+
# Push the commit to remote stable branch
|
|
72
|
+
# This creates 'stable' if it doesn't exist, or fast-forwards it.
|
|
73
|
+
sh "git push origin #{commit_sha}:stable"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if Rake::Task.task_defined?("release")
|
|
78
|
+
Rake::Task["release"].enhance do
|
|
79
|
+
Rake::Task["sourcehut:update_stable"].invoke
|
|
37
80
|
end
|
|
38
81
|
end
|
|
@@ -15,8 +15,18 @@ class AppScreenshot < Data.define(:app, :output_path)
|
|
|
15
15
|
LauncherScript.new(app.app_path, Dir.pwd).run do |launcher|
|
|
16
16
|
TerminalWindow.new(launcher.path, launcher.pid_file).open do |window|
|
|
17
17
|
take_snapshot(window.window_id)
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
|
|
19
|
+
if File.size?(output_path)
|
|
20
|
+
puts " done."
|
|
21
|
+
true
|
|
22
|
+
else
|
|
23
|
+
FileUtils.rm_f(output_path)
|
|
24
|
+
puts " FAILED"
|
|
25
|
+
puts
|
|
26
|
+
puts " Window rendered nothing (app may have crashed before drawing)"
|
|
27
|
+
puts
|
|
28
|
+
false
|
|
29
|
+
end
|
|
20
30
|
end
|
|
21
31
|
end
|
|
22
32
|
rescue => e
|
|
@@ -28,6 +38,6 @@ class AppScreenshot < Data.define(:app, :output_path)
|
|
|
28
38
|
end
|
|
29
39
|
|
|
30
40
|
private def take_snapshot(window_id)
|
|
31
|
-
system("screencapture -l
|
|
41
|
+
system("screencapture", "-l", window_id.to_s, "-o", "-x", output_path)
|
|
32
42
|
end
|
|
33
43
|
end
|
|
@@ -11,13 +11,14 @@ class SavedScreenshot < Data.define(:app, :path)
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def stale?
|
|
14
|
-
return true unless
|
|
14
|
+
return true unless valid?
|
|
15
15
|
|
|
16
16
|
app_last_modified > screenshot_last_commit_time
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
private def
|
|
20
|
-
File
|
|
19
|
+
private def valid?
|
|
20
|
+
# File must exist and have content (not 0 bytes)
|
|
21
|
+
File.size?(path) || false
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
private def app_last_modified
|