rbytes 0.2.0 → 0.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/CHANGELOG.md +4 -0
- data/lib/ruby_bytes/charmed.rb +283 -0
- data/lib/ruby_bytes/thor.rb +11 -2
- data/lib/ruby_bytes/version.rb +1 -1
- data/templates/rbytes/rbytes.rb +11 -2
- metadata +4 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 040b91d608de3f8f28c7e81b3b63c604370779ed8321baa8d8a26ad249365927
|
|
4
|
+
data.tar.gz: 8b99d75e94487d7999284caf0b6ad07fd7feb8771d4ba7ab20d85e0e7c248449
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfbb924533307fed9c3ba1d62f4720ee62eb5e139946829f3f1f4d2c045a365424b42258193e9e523737ddb5f37714410028f0a74a61063ec25b883d3068cedf
|
|
7
|
+
data.tar.gz: 506aa21f7128feb9d7f71e25b94d94f4f1fcbfc3b2fcfb53d9ee295ae4cfba46384349659a9b766a1bd1287e4b9c606ac2a27af1e5f2ca510873f8f5ee247c0c
|
data/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lipgloss"
|
|
4
|
+
require "gum"
|
|
5
|
+
|
|
6
|
+
class Rbytes
|
|
7
|
+
module Charmed
|
|
8
|
+
# See https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc87b2124?permalink_comment_id=3892823#gistcomment-3892823
|
|
9
|
+
FG_COLORS = {
|
|
10
|
+
black: "8",
|
|
11
|
+
red: "9",
|
|
12
|
+
green: "10",
|
|
13
|
+
yellow: "11",
|
|
14
|
+
blue: "12",
|
|
15
|
+
magenta: "13",
|
|
16
|
+
cyan: "14",
|
|
17
|
+
white: "15",
|
|
18
|
+
grey: "243"
|
|
19
|
+
}.freeze
|
|
20
|
+
|
|
21
|
+
BG_COLORS = {
|
|
22
|
+
black: "16",
|
|
23
|
+
red: "124",
|
|
24
|
+
green: "28",
|
|
25
|
+
yellow: "214",
|
|
26
|
+
blue: "25",
|
|
27
|
+
magenta: "95",
|
|
28
|
+
cyan: "45",
|
|
29
|
+
white: "231",
|
|
30
|
+
grey: "252"
|
|
31
|
+
}.freeze
|
|
32
|
+
|
|
33
|
+
# Print a message to the user.
|
|
34
|
+
# say accumulates messages to print them in a box in case more than a single message is provided.
|
|
35
|
+
# the empty string is used to flush the output; any other command flushes the output, too.
|
|
36
|
+
def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
|
|
37
|
+
return if quiet?
|
|
38
|
+
|
|
39
|
+
return draw_box! if message == ""
|
|
40
|
+
|
|
41
|
+
buffer = set_color(message, *Array(color))
|
|
42
|
+
|
|
43
|
+
append_to_current_box(buffer)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
STATUS_COLORS = {
|
|
47
|
+
debug: :grey,
|
|
48
|
+
info: :blue,
|
|
49
|
+
warn: :yellow,
|
|
50
|
+
error: :red,
|
|
51
|
+
fatal: :red
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
# Print a status badge followed by a message (e.g. " create config/routes.rb").
|
|
55
|
+
# Thor default: right-aligns the status word, colors it, appends the message.
|
|
56
|
+
def say_status(status, message, log_status = true)
|
|
57
|
+
return if quiet? || log_status == false
|
|
58
|
+
|
|
59
|
+
draw_box!
|
|
60
|
+
|
|
61
|
+
color_code = log_status.is_a?(Symbol) ? FG_COLORS.fetch(log_status) : FG_COLORS.fetch(STATUS_COLORS.fetch(status, STATUS_COLORS[:info]))
|
|
62
|
+
|
|
63
|
+
status_style = Lipgloss::Style.new.bold(true).foreground(color_code).inline(true)
|
|
64
|
+
buffer = "#{status_style.render(status.to_s.upcase)}\t#{message}"
|
|
65
|
+
|
|
66
|
+
stdout.puts(buffer)
|
|
67
|
+
stdout.flush
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Print an error message to $stderr.
|
|
71
|
+
# Thor default: same as +say+ but writes to $stderr.
|
|
72
|
+
def say_error(message = "", color = :red, force_new_line = (message.to_s !~ /( |\t)\Z/))
|
|
73
|
+
return if quiet?
|
|
74
|
+
|
|
75
|
+
draw_box!
|
|
76
|
+
|
|
77
|
+
# Print error in a box
|
|
78
|
+
error_style = Lipgloss::Style.new
|
|
79
|
+
.padding(1, 1)
|
|
80
|
+
.align(:center)
|
|
81
|
+
.background(FG_COLORS.fetch(color))
|
|
82
|
+
buffer = error_style.render(message)
|
|
83
|
+
stderr.puts(buffer)
|
|
84
|
+
stderr.flush
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Print an unformatted error statement to $stderr (legacy Thor method).
|
|
88
|
+
# Thor default: $stderr.puts statement.
|
|
89
|
+
def error(statement)
|
|
90
|
+
say_error(statement)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Print an array of strings in evenly-spaced columns.
|
|
94
|
+
# Thor default: calculates column widths and pads with spaces.
|
|
95
|
+
def print_in_columns(array)
|
|
96
|
+
return if quiet?
|
|
97
|
+
|
|
98
|
+
draw_box!
|
|
99
|
+
|
|
100
|
+
return if array.empty?
|
|
101
|
+
|
|
102
|
+
if array.size <= 4
|
|
103
|
+
stdout.puts Lipgloss::List.new.items(array.map(&:to_s)).render
|
|
104
|
+
stdout.flush
|
|
105
|
+
return
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
col_width = array.map { |e| e.to_s.size }.max + 2
|
|
109
|
+
cols = [terminal_width / col_width, array.size].min.clamp(4..)
|
|
110
|
+
|
|
111
|
+
# Shrink columns so the last row has at least cols-2 items
|
|
112
|
+
while cols > 4
|
|
113
|
+
remainder = array.size % cols
|
|
114
|
+
break if remainder.zero? || remainder >= cols - 2
|
|
115
|
+
cols -= 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
even_style = Lipgloss::Style.new.width(col_width).inline(true).align(:center).background("254").foreground("0")
|
|
119
|
+
odd_style = Lipgloss::Style.new.width(col_width).inline(true).align(:center).background("234")
|
|
120
|
+
|
|
121
|
+
rows = array.each_slice(cols).map.with_index do |row, ri|
|
|
122
|
+
Lipgloss.join_horizontal(:top, *row.map.with_index { |item, ci| ((ri + ci).even? ? even_style : odd_style).render(item.to_s) })
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
buffer = Lipgloss.join_vertical(:left, *rows)
|
|
126
|
+
|
|
127
|
+
stdout.puts(buffer)
|
|
128
|
+
stdout.flush
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Print a 2-D array as an aligned table.
|
|
132
|
+
# Thor default: ASCII table with optional indent, colwidth, borders.
|
|
133
|
+
#
|
|
134
|
+
# ==== Options
|
|
135
|
+
# indent<Integer> – indent the first column
|
|
136
|
+
# colwidth<Integer> – force the first column width
|
|
137
|
+
# borders<Boolean> – draw borders
|
|
138
|
+
def print_table(data, options = {})
|
|
139
|
+
return if quiet?
|
|
140
|
+
|
|
141
|
+
draw_box!
|
|
142
|
+
|
|
143
|
+
data = data.dup
|
|
144
|
+
headers = data.shift
|
|
145
|
+
|
|
146
|
+
header_style = Lipgloss::Style.new.bold(true).foreground("12")
|
|
147
|
+
even_style = Lipgloss::Style.new.background("254").foreground("0")
|
|
148
|
+
odd_style = Lipgloss::Style.new.background("234")
|
|
149
|
+
|
|
150
|
+
table = Lipgloss::Table.new
|
|
151
|
+
.headers(headers)
|
|
152
|
+
.rows(data)
|
|
153
|
+
.style_func(rows: data.size, columns: headers.size) do |row, column|
|
|
154
|
+
if row == Lipgloss::Table::HEADER_ROW
|
|
155
|
+
header_style
|
|
156
|
+
elsif row.even?
|
|
157
|
+
even_style
|
|
158
|
+
else
|
|
159
|
+
odd_style
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
buffer = table.render
|
|
164
|
+
|
|
165
|
+
stdout.puts(buffer)
|
|
166
|
+
stdout.flush
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Print a long string, word-wrapped to the terminal width.
|
|
170
|
+
# Thor default: wraps text at terminal_width minus indent.
|
|
171
|
+
#
|
|
172
|
+
# ==== Options
|
|
173
|
+
# indent<Integer> – left-indent each line
|
|
174
|
+
def print_wrapped(message, options = {})
|
|
175
|
+
return if quiet?
|
|
176
|
+
|
|
177
|
+
draw_box!
|
|
178
|
+
|
|
179
|
+
style = Lipgloss::Style.new.background("234")
|
|
180
|
+
buffer = style.render(message)
|
|
181
|
+
super(buffer)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# ── Input ─────────────────────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
# Prompt the user for a single line of text.
|
|
187
|
+
# Thor default: readline with optional :default, :limited_to, :echo, :path.
|
|
188
|
+
def ask(statement, *args)
|
|
189
|
+
draw_box!
|
|
190
|
+
|
|
191
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
192
|
+
# color = args.first
|
|
193
|
+
|
|
194
|
+
if options[:limited_to]
|
|
195
|
+
Gum.choose(options[:limited_to], header: statement, selected: options[:default])
|
|
196
|
+
else
|
|
197
|
+
Gum.input(value: options[:default], prompt: "> ", header: statement)
|
|
198
|
+
end.then { |v| handle_gum_result(v) }
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Ask a yes/no question, return true when the user answers "y" or "yes".
|
|
202
|
+
# Thor default: regex match on the answer string.
|
|
203
|
+
def yes?(statement, color = nil)
|
|
204
|
+
draw_box!
|
|
205
|
+
|
|
206
|
+
handle_gum_result(
|
|
207
|
+
Gum.choose(%w[Yes No], header: statement, selected: "Yes")
|
|
208
|
+
).then { |res| res == "Yes" }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Ask a yes/no question, return true when the user answers "n" or "no".
|
|
212
|
+
# Thor default: inverse of +yes?+.
|
|
213
|
+
def no?(statement, color = nil)
|
|
214
|
+
draw_box!
|
|
215
|
+
|
|
216
|
+
handle_gum_result(
|
|
217
|
+
Gum.choose(%w[Yes No], header: statement, selected: "Yes")
|
|
218
|
+
).then { |res| res == "No" }
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# ── Formatting / Utility ──────────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
# Apply color and style to a string.
|
|
224
|
+
# Thor default: wraps string in ANSI escape codes.
|
|
225
|
+
def set_color(string, *colors)
|
|
226
|
+
style = Lipgloss::Style.new.inline(true)
|
|
227
|
+
colors.each do |c|
|
|
228
|
+
case c
|
|
229
|
+
when :bold then style = style.bold(true)
|
|
230
|
+
when :on_black, :on_red, :on_green, :on_yellow, :on_blue, :on_magenta, :on_cyan, :on_white
|
|
231
|
+
style = style.background(BG_COLORS.fetch(c.to_s.sub("on_", "").to_sym))
|
|
232
|
+
when Symbol then style = style.foreground(FG_COLORS.fetch(c))
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
style.render(string.to_s)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Return the width (in columns) of the current terminal.
|
|
240
|
+
# Thor default: detects via IO/stty (class method on Thor::Shell::Terminal).
|
|
241
|
+
def terminal_width
|
|
242
|
+
Thor::Shell::Terminal.terminal_width
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
|
|
247
|
+
def box_buffer
|
|
248
|
+
@box_buffer ||= []
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def append_to_current_box(line)
|
|
252
|
+
box_buffer << line
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def draw_box!
|
|
256
|
+
return stdout.puts if box_buffer.empty?
|
|
257
|
+
|
|
258
|
+
# Single line is printed as is
|
|
259
|
+
buffer =
|
|
260
|
+
if box_buffer.size == 1
|
|
261
|
+
box_buffer.first
|
|
262
|
+
else
|
|
263
|
+
Lipgloss::Style.new
|
|
264
|
+
.border(:normal)
|
|
265
|
+
.padding(1, 2)
|
|
266
|
+
.align(:center)
|
|
267
|
+
.render(box_buffer.join("\n"))
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
stdout.puts(buffer)
|
|
271
|
+
stdout.flush
|
|
272
|
+
|
|
273
|
+
box_buffer.clear
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def handle_gum_result(res)
|
|
277
|
+
# nil means user cancelled
|
|
278
|
+
# https://github.com/marcoroth/gum-ruby/blob/faf9e2ccefa6457708a4eb31c992e0ccf585a998/lib/gum/command.rb#L46
|
|
279
|
+
Kernel.exit(130) if res.nil?
|
|
280
|
+
res
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
data/lib/ruby_bytes/thor.rb
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
class Rbytes < Thor
|
|
4
4
|
desc "template", "Load and run generator from RailsBytes"
|
|
5
5
|
def template(url)
|
|
6
|
-
|
|
6
|
+
say_status :info, "Run template from: #{url}"
|
|
7
7
|
|
|
8
8
|
# require gems typically used in templates
|
|
9
9
|
require "bundler"
|
|
10
10
|
|
|
11
|
-
Base.new.apply(url)
|
|
11
|
+
Base.new.apply(url, verbose: false)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Rails core extensions can be used in templates.
|
|
@@ -449,6 +449,15 @@ class Rbytes < Thor
|
|
|
449
449
|
include Thor::Actions
|
|
450
450
|
include Rails::Actions
|
|
451
451
|
|
|
452
|
+
unless ENV["RBYTES_DISABLE_GUM"] == "1"
|
|
453
|
+
begin
|
|
454
|
+
require "ruby_bytes/charmed"
|
|
455
|
+
Thor::Shell::Color.prepend Charmed
|
|
456
|
+
rescue LoadError
|
|
457
|
+
# No gum available
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
452
461
|
# Custom methods defined on AppGenerator
|
|
453
462
|
# https://github.com/rails/rails/blob/38275763257221e381cd4e37958ce1413fd0433c/railties/lib/rails/generators/rails/app/app_generator.rb#L558
|
|
454
463
|
def file(*args, &block)
|
data/lib/ruby_bytes/version.rb
CHANGED
data/templates/rbytes/rbytes.rb
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
class Rbytes < Thor
|
|
4
4
|
desc "template", "Load and run generator from RailsBytes"
|
|
5
5
|
def template(url)
|
|
6
|
-
|
|
6
|
+
say_status :info, "Run template from: #{url}"
|
|
7
7
|
|
|
8
8
|
# require gems typically used in templates
|
|
9
9
|
require "bundler"
|
|
10
10
|
|
|
11
|
-
Base.new.apply(url)
|
|
11
|
+
Base.new.apply(url, verbose: false)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
<%= include "core_ext", indent: 2 %>
|
|
@@ -20,6 +20,15 @@ class Rbytes < Thor
|
|
|
20
20
|
include Thor::Actions
|
|
21
21
|
include Rails::Actions
|
|
22
22
|
|
|
23
|
+
unless ENV["RBYTES_DISABLE_GUM"] == "1"
|
|
24
|
+
begin
|
|
25
|
+
require "ruby_bytes/charmed"
|
|
26
|
+
Thor::Shell::Color.prepend Charmed
|
|
27
|
+
rescue LoadError
|
|
28
|
+
# No gum available
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
23
32
|
# Custom methods defined on AppGenerator
|
|
24
33
|
# https://github.com/rails/rails/blob/38275763257221e381cd4e37958ce1413fd0433c/railties/lib/rails/generators/rails/app/app_generator.rb#L558
|
|
25
34
|
def file(*args, &block)
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbytes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vladimir Dementyev
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: thor
|
|
@@ -80,6 +79,7 @@ files:
|
|
|
80
79
|
- README.md
|
|
81
80
|
- bin/rbytes
|
|
82
81
|
- lib/rbytes.rb
|
|
82
|
+
- lib/ruby_bytes/charmed.rb
|
|
83
83
|
- lib/ruby_bytes/cli.rb
|
|
84
84
|
- lib/ruby_bytes/compiler.rb
|
|
85
85
|
- lib/ruby_bytes/publisher.rb
|
|
@@ -99,7 +99,6 @@ metadata:
|
|
|
99
99
|
documentation_uri: http://github.com/palkan/rbytes
|
|
100
100
|
homepage_uri: http://github.com/palkan/rbytes
|
|
101
101
|
source_code_uri: http://github.com/palkan/rbytes
|
|
102
|
-
post_install_message:
|
|
103
102
|
rdoc_options: []
|
|
104
103
|
require_paths:
|
|
105
104
|
- lib
|
|
@@ -114,8 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
114
113
|
- !ruby/object:Gem::Version
|
|
115
114
|
version: '0'
|
|
116
115
|
requirements: []
|
|
117
|
-
rubygems_version: 3.
|
|
118
|
-
signing_key:
|
|
116
|
+
rubygems_version: 3.6.9
|
|
119
117
|
specification_version: 4
|
|
120
118
|
summary: Ruby Bytes is a tool to build application templates for Ruby and Rails applications
|
|
121
119
|
test_files: []
|