rfix 2.0.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/rfix +11 -90
- data/lib/rfix.rb +10 -9
- data/lib/rfix/branch/reference.rb +2 -2
- data/lib/rfix/branch/upstream.rb +2 -4
- data/lib/rfix/cli/command.rb +14 -1
- data/lib/rfix/cli/command/all.rb +21 -0
- data/lib/rfix/cli/command/base.rb +30 -19
- data/lib/rfix/cli/command/branch.rb +2 -0
- data/lib/rfix/cli/command/help.rb +2 -0
- data/lib/rfix/cli/command/info.rb +6 -1
- data/lib/rfix/cli/command/local.rb +2 -0
- data/lib/rfix/cli/command/origin.rb +2 -0
- data/lib/rfix/cli/command/setup.rb +2 -0
- data/lib/rfix/cli/command/status.rb +39 -0
- data/lib/rfix/collector.rb +69 -0
- data/lib/rfix/diff.rb +69 -0
- data/lib/rfix/extension/comment_config.rb +15 -0
- data/lib/rfix/extension/offense.rb +17 -14
- data/lib/rfix/extension/pastel.rb +7 -4
- data/lib/rfix/extension/progresbar.rb +15 -0
- data/lib/rfix/extension/strings.rb +10 -2
- data/lib/rfix/file.rb +5 -3
- data/lib/rfix/file/base.rb +21 -14
- data/lib/rfix/file/deleted.rb +2 -0
- data/lib/rfix/file/ignored.rb +2 -0
- data/lib/rfix/file/null.rb +17 -0
- data/lib/rfix/file/tracked.rb +39 -23
- data/lib/rfix/file/undefined.rb +17 -0
- data/lib/rfix/file/untracked.rb +3 -1
- data/lib/rfix/formatter.rb +67 -71
- data/lib/rfix/highlighter.rb +1 -3
- data/lib/rfix/rake/gemfile.rb +26 -23
- data/lib/rfix/repository.rb +59 -96
- data/lib/rfix/types.rb +24 -14
- data/lib/rfix/version.rb +1 -1
- data/rfix.gemspec +11 -3
- data/vendor/cli-ui/Gemfile +17 -0
- data/vendor/cli-ui/Gemfile.lock +60 -0
- data/vendor/cli-ui/LICENSE.txt +21 -0
- data/vendor/cli-ui/README.md +224 -0
- data/vendor/cli-ui/Rakefile +20 -0
- data/vendor/cli-ui/bin/console +14 -0
- data/vendor/cli-ui/cli-ui.gemspec +25 -0
- data/vendor/cli-ui/dev.yml +14 -0
- data/vendor/cli-ui/lib/cli/ui.rb +233 -0
- data/vendor/cli-ui/lib/cli/ui/ansi.rb +157 -0
- data/vendor/cli-ui/lib/cli/ui/color.rb +84 -0
- data/vendor/cli-ui/lib/cli/ui/formatter.rb +192 -0
- data/vendor/cli-ui/lib/cli/ui/frame.rb +269 -0
- data/vendor/cli-ui/lib/cli/ui/frame/frame_stack.rb +98 -0
- data/vendor/cli-ui/lib/cli/ui/frame/frame_style.rb +120 -0
- data/vendor/cli-ui/lib/cli/ui/frame/frame_style/box.rb +166 -0
- data/vendor/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +139 -0
- data/vendor/cli-ui/lib/cli/ui/glyph.rb +84 -0
- data/vendor/cli-ui/lib/cli/ui/os.rb +67 -0
- data/vendor/cli-ui/lib/cli/ui/printer.rb +59 -0
- data/vendor/cli-ui/lib/cli/ui/progress.rb +90 -0
- data/vendor/cli-ui/lib/cli/ui/prompt.rb +297 -0
- data/vendor/cli-ui/lib/cli/ui/prompt/interactive_options.rb +484 -0
- data/vendor/cli-ui/lib/cli/ui/prompt/options_handler.rb +29 -0
- data/vendor/cli-ui/lib/cli/ui/spinner.rb +66 -0
- data/vendor/cli-ui/lib/cli/ui/spinner/async.rb +40 -0
- data/vendor/cli-ui/lib/cli/ui/spinner/spin_group.rb +263 -0
- data/vendor/cli-ui/lib/cli/ui/stdout_router.rb +232 -0
- data/vendor/cli-ui/lib/cli/ui/terminal.rb +46 -0
- data/vendor/cli-ui/lib/cli/ui/truncater.rb +102 -0
- data/vendor/cli-ui/lib/cli/ui/version.rb +5 -0
- data/vendor/cli-ui/lib/cli/ui/widgets.rb +77 -0
- data/vendor/cli-ui/lib/cli/ui/widgets/base.rb +27 -0
- data/vendor/cli-ui/lib/cli/ui/widgets/status.rb +61 -0
- data/vendor/cli-ui/lib/cli/ui/wrap.rb +56 -0
- data/vendor/cli-ui/test/cli/ui/ansi_test.rb +32 -0
- data/vendor/cli-ui/test/cli/ui/cli_ui_test.rb +23 -0
- data/vendor/cli-ui/test/cli/ui/color_test.rb +40 -0
- data/vendor/cli-ui/test/cli/ui/formatter_test.rb +79 -0
- data/vendor/cli-ui/test/cli/ui/glyph_test.rb +68 -0
- data/vendor/cli-ui/test/cli/ui/printer_test.rb +103 -0
- data/vendor/cli-ui/test/cli/ui/progress_test.rb +46 -0
- data/vendor/cli-ui/test/cli/ui/prompt/options_handler_test.rb +39 -0
- data/vendor/cli-ui/test/cli/ui/prompt_test.rb +348 -0
- data/vendor/cli-ui/test/cli/ui/spinner/spin_group_test.rb +39 -0
- data/vendor/cli-ui/test/cli/ui/spinner_test.rb +141 -0
- data/vendor/cli-ui/test/cli/ui/stdout_router_test.rb +32 -0
- data/vendor/cli-ui/test/cli/ui/terminal_test.rb +26 -0
- data/vendor/cli-ui/test/cli/ui/truncater_test.rb +31 -0
- data/vendor/cli-ui/test/cli/ui/widgets/status_test.rb +49 -0
- data/vendor/cli-ui/test/cli/ui/widgets_test.rb +15 -0
- data/vendor/cli-ui/test/test_helper.rb +53 -0
- data/vendor/cli-ui/tmp/cache/bootsnap/compile-cache/d9/c036af0f3dc494 +0 -0
- data/vendor/cli-ui/tmp/cache/bootsnap/load-path-cache +0 -0
- data/vendor/dry-cli/lib/dry/cli/command.rb +2 -1
- data/vendor/dry-cli/tmp/cache/bootsnap/compile-cache/ff/a22a5daafbd74c +0 -0
- data/vendor/dry-cli/tmp/cache/bootsnap/load-path-cache +0 -0
- data/vendor/strings-ansi/tmp/cache/bootsnap/compile-cache/79/49cf49407b370e +0 -0
- data/vendor/strings-ansi/tmp/cache/bootsnap/load-path-cache +0 -0
- metadata +170 -9
- data/lib/rfix/extension/string.rb +0 -12
- data/lib/rfix/indicator.rb +0 -19
@@ -0,0 +1,98 @@
|
|
1
|
+
module CLI
|
2
|
+
module UI
|
3
|
+
module Frame
|
4
|
+
module FrameStack
|
5
|
+
COLOR_ENVVAR = 'CLI_FRAME_STACK'
|
6
|
+
STYLE_ENVVAR = 'CLI_STYLE_STACK'
|
7
|
+
|
8
|
+
class StackItem
|
9
|
+
attr_reader :color, :frame_style
|
10
|
+
|
11
|
+
def initialize(color_name, style_name)
|
12
|
+
@color = CLI::UI.resolve_color(color_name)
|
13
|
+
@frame_style = CLI::UI.resolve_style(style_name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Fetch all items off the frame stack
|
19
|
+
def items
|
20
|
+
colors = ENV.fetch(COLOR_ENVVAR, '').split(':').map(&:to_sym)
|
21
|
+
styles = ENV.fetch(STYLE_ENVVAR, '').split(':').map(&:to_sym)
|
22
|
+
|
23
|
+
colors.length.times.map do |i|
|
24
|
+
StackItem.new(colors[i], styles[i] || Frame.frame_style)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Push a new item onto the frame stack.
|
29
|
+
#
|
30
|
+
# Either an item or a :color/:style pair should be pushed onto the stack.
|
31
|
+
#
|
32
|
+
# ==== Attributes
|
33
|
+
#
|
34
|
+
# * +item+ a +StackItem+ to push onto the stack. Defaults to nil
|
35
|
+
#
|
36
|
+
# ==== Options
|
37
|
+
#
|
38
|
+
# * +:color+ the color of the new stack item. Defaults to nil
|
39
|
+
# * +:style+ the style of the new stack item. Defaults to nil
|
40
|
+
#
|
41
|
+
# ==== Raises
|
42
|
+
#
|
43
|
+
# If both an item and a color/style pair are given, raises an +ArgumentError+
|
44
|
+
# If the given item is not a +StackItem+, raises an +ArgumentError+
|
45
|
+
#
|
46
|
+
def push(item = nil, color: nil, style: nil)
|
47
|
+
unless item.nil?
|
48
|
+
unless item.is_a?(StackItem)
|
49
|
+
raise ArgumentError, 'item must be a StackItem'
|
50
|
+
end
|
51
|
+
|
52
|
+
unless color.nil? && style.nil?
|
53
|
+
raise ArgumentError, 'Must give one of item or color: and style:'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
item ||= StackItem.new(color, style)
|
58
|
+
|
59
|
+
curr = items
|
60
|
+
curr << item
|
61
|
+
|
62
|
+
serialize(curr)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Removes and returns the last stack item off the stack
|
66
|
+
def pop
|
67
|
+
curr = items
|
68
|
+
ret = curr.pop
|
69
|
+
|
70
|
+
serialize(curr)
|
71
|
+
|
72
|
+
ret.nil? ? nil : ret
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Serializes the item stack into two ENV variables.
|
78
|
+
#
|
79
|
+
# This is done to preserve backward compatibility with earlier versions of cli/ui.
|
80
|
+
# This ensures that any code that relied upon previous stack behavior should continue
|
81
|
+
# to work.
|
82
|
+
def serialize(items)
|
83
|
+
colors = []
|
84
|
+
styles = []
|
85
|
+
|
86
|
+
items.each do |item|
|
87
|
+
colors << item.color.name
|
88
|
+
styles << item.frame_style.name
|
89
|
+
end
|
90
|
+
|
91
|
+
ENV[COLOR_ENVVAR] = colors.join(':')
|
92
|
+
ENV[STYLE_ENVVAR] = styles.join(':')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'cli/ui/frame'
|
2
|
+
|
3
|
+
module CLI
|
4
|
+
module UI
|
5
|
+
module Frame
|
6
|
+
module FrameStyle
|
7
|
+
class << self
|
8
|
+
# rubocop:disable Style/ClassVars
|
9
|
+
@@loaded_styles = []
|
10
|
+
|
11
|
+
def loaded_styles
|
12
|
+
@@loaded_styles.map(&:name)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Lookup a frame style via its name
|
16
|
+
#
|
17
|
+
# ==== Attributes
|
18
|
+
#
|
19
|
+
# * +symbol+ - frame style name to lookup
|
20
|
+
def lookup(name)
|
21
|
+
@@loaded_styles
|
22
|
+
.find { |style| style.name.to_sym == name }
|
23
|
+
.tap { |style| raise InvalidFrameStyleName, name if style.nil? }
|
24
|
+
end
|
25
|
+
|
26
|
+
def extended(base)
|
27
|
+
@@loaded_styles << base
|
28
|
+
base.extend(Interface)
|
29
|
+
end
|
30
|
+
# rubocop:enable Style/ClassVars
|
31
|
+
end
|
32
|
+
|
33
|
+
class InvalidFrameStyleName < ArgumentError
|
34
|
+
def initialize(name)
|
35
|
+
super
|
36
|
+
@name = name
|
37
|
+
end
|
38
|
+
|
39
|
+
def message
|
40
|
+
keys = FrameStyle.loaded_styles.map(&:inspect).join(',')
|
41
|
+
"invalid frame style: #{@name.inspect}" \
|
42
|
+
' -- must be one of CLI::UI::Frame::FrameStyle.loaded_styles ' \
|
43
|
+
"(#{keys})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Public interface for FrameStyles
|
48
|
+
# Applied by extending FrameStyle
|
49
|
+
module Interface
|
50
|
+
def name
|
51
|
+
raise NotImplementedError
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the character(s) that should be printed at the beginning
|
55
|
+
# of lines inside this frame
|
56
|
+
def prefix
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the printing width of the prefix
|
61
|
+
def prefix_width
|
62
|
+
CLI::UI::ANSI.printing_width(prefix)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Draws the "Open" line for this frame style
|
66
|
+
#
|
67
|
+
# ==== Attributes
|
68
|
+
#
|
69
|
+
# * +text+ - (required) the text/title to output in the frame
|
70
|
+
#
|
71
|
+
# ==== Options
|
72
|
+
#
|
73
|
+
# * +:color+ - (required) The color of the frame.
|
74
|
+
#
|
75
|
+
def open(text, color:)
|
76
|
+
raise NotImplementedError
|
77
|
+
end
|
78
|
+
|
79
|
+
# Draws the "Close" line for this frame style
|
80
|
+
#
|
81
|
+
# ==== Attributes
|
82
|
+
#
|
83
|
+
# * +text+ - (required) the text/title to output in the frame
|
84
|
+
#
|
85
|
+
# ==== Options
|
86
|
+
#
|
87
|
+
# * +:color+ - (required) The color of the frame.
|
88
|
+
# * +:right_text+ - Text to print at the right of the line. Defaults to nil
|
89
|
+
#
|
90
|
+
def close(text, color:, right_text: nil)
|
91
|
+
raise NotImplementedError
|
92
|
+
end
|
93
|
+
|
94
|
+
# Draws a "divider" line for the current frame style
|
95
|
+
#
|
96
|
+
# ==== Attributes
|
97
|
+
#
|
98
|
+
# * +text+ - (required) the text/title to output in the frame
|
99
|
+
#
|
100
|
+
# ==== Options
|
101
|
+
#
|
102
|
+
# * +:color+ - (required) The color of the frame.
|
103
|
+
#
|
104
|
+
def divider(text, color: nil)
|
105
|
+
raise NotImplementedError
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def print_at_x(x, str)
|
111
|
+
CLI::UI::ANSI.cursor_horizontal_absolute(1 + x) + str
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
require 'cli/ui/frame/frame_style/box'
|
120
|
+
require 'cli/ui/frame/frame_style/bracket'
|
@@ -0,0 +1,166 @@
|
|
1
|
+
module CLI
|
2
|
+
module UI
|
3
|
+
module Frame
|
4
|
+
module FrameStyle
|
5
|
+
module Box
|
6
|
+
extend FrameStyle
|
7
|
+
|
8
|
+
VERTICAL = '┃'
|
9
|
+
HORIZONTAL = '━'
|
10
|
+
DIVIDER = '┣'
|
11
|
+
TOP_LEFT = '┏'
|
12
|
+
BOTTOM_LEFT = '┗'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def name
|
16
|
+
'box'
|
17
|
+
end
|
18
|
+
|
19
|
+
def prefix
|
20
|
+
VERTICAL
|
21
|
+
end
|
22
|
+
|
23
|
+
# Draws the "Open" line for this frame style
|
24
|
+
#
|
25
|
+
# ==== Attributes
|
26
|
+
#
|
27
|
+
# * +text+ - (required) the text/title to output in the frame
|
28
|
+
#
|
29
|
+
# ==== Options
|
30
|
+
#
|
31
|
+
# * +:color+ - (required) The color of the frame.
|
32
|
+
#
|
33
|
+
# ==== Output:
|
34
|
+
#
|
35
|
+
# ┏━━ Open ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
36
|
+
#
|
37
|
+
def open(text, color:)
|
38
|
+
edge(text, color: color, first: TOP_LEFT)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Draws a "divider" line for the current frame style
|
42
|
+
#
|
43
|
+
# ==== Attributes
|
44
|
+
#
|
45
|
+
# * +text+ - (required) the text/title to output in the frame
|
46
|
+
#
|
47
|
+
# ==== Options
|
48
|
+
#
|
49
|
+
# * +:color+ - (required) The color of the frame.
|
50
|
+
#
|
51
|
+
# ==== Output:
|
52
|
+
#
|
53
|
+
# ┣━━ Divider ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
54
|
+
#
|
55
|
+
def divider(text, color:)
|
56
|
+
edge(text, color: color, first: DIVIDER)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Draws the "Close" line for this frame style
|
60
|
+
#
|
61
|
+
# ==== Attributes
|
62
|
+
#
|
63
|
+
# * +text+ - (required) the text/title to output in the frame
|
64
|
+
#
|
65
|
+
# ==== Options
|
66
|
+
#
|
67
|
+
# * +:color+ - (required) The color of the frame.
|
68
|
+
# * +:right_text+ - Text to print at the right of the line. Defaults to nil
|
69
|
+
#
|
70
|
+
# ==== Output:
|
71
|
+
#
|
72
|
+
# ┗━━ Close ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
73
|
+
#
|
74
|
+
def close(text, color:, right_text: nil)
|
75
|
+
edge(text, color: color, right_text: right_text, first: BOTTOM_LEFT)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def edge(text, color:, first:, right_text: nil)
|
81
|
+
color = CLI::UI.resolve_color(color)
|
82
|
+
|
83
|
+
preamble = +''
|
84
|
+
|
85
|
+
preamble << color.code << first << (HORIZONTAL * 2)
|
86
|
+
|
87
|
+
text ||= ''
|
88
|
+
unless text.empty?
|
89
|
+
preamble << ' ' << CLI::UI.resolve_text("{{#{color.name}:#{text}}}") << ' '
|
90
|
+
end
|
91
|
+
|
92
|
+
termwidth = CLI::UI::Terminal.width
|
93
|
+
|
94
|
+
suffix = +''
|
95
|
+
|
96
|
+
if right_text
|
97
|
+
suffix << ' ' << right_text << ' '
|
98
|
+
end
|
99
|
+
|
100
|
+
preamble_width = CLI::UI::ANSI.printing_width(preamble)
|
101
|
+
preamble_start = Frame.prefix_width
|
102
|
+
# If prefix_width is non-zero, we need to subtract the width of
|
103
|
+
# the final space, since we're going to write over it.
|
104
|
+
preamble_start -= 1 unless preamble_start.zero?
|
105
|
+
preamble_end = preamble_start + preamble_width
|
106
|
+
|
107
|
+
suffix_width = CLI::UI::ANSI.printing_width(suffix)
|
108
|
+
suffix_end = termwidth - 2
|
109
|
+
suffix_start = suffix_end - suffix_width
|
110
|
+
|
111
|
+
if preamble_end > suffix_start
|
112
|
+
suffix = ''
|
113
|
+
# if preamble_end > termwidth
|
114
|
+
# we *could* truncate it, but let's just let it overflow to the
|
115
|
+
# next line and call it poor usage of this API.
|
116
|
+
end
|
117
|
+
|
118
|
+
o = +''
|
119
|
+
|
120
|
+
# Shopify's CI system supports terminal emulation, but not some of
|
121
|
+
# the fancier features that we normally use to draw frames
|
122
|
+
# extra-reliably, so we fall back to a less foolproof strategy. This
|
123
|
+
# is probably better in general for cases with impoverished terminal
|
124
|
+
# emulators and no active user.
|
125
|
+
unless [0, '', nil].include?(ENV['CI'])
|
126
|
+
linewidth = [0, termwidth - (preamble_end + suffix_width + 1)].max
|
127
|
+
|
128
|
+
o << color.code << preamble
|
129
|
+
o << color.code << (HORIZONTAL * linewidth)
|
130
|
+
o << color.code << suffix
|
131
|
+
o << CLI::UI::Color::RESET.code << "\n"
|
132
|
+
return o
|
133
|
+
end
|
134
|
+
|
135
|
+
# Jumping around the line can cause some unwanted flashes
|
136
|
+
o << CLI::UI::ANSI.hide_cursor
|
137
|
+
|
138
|
+
# reset to column 1 so that things like ^C don't ruin formatting
|
139
|
+
o << "\r"
|
140
|
+
|
141
|
+
# This code will print out a full line with the given preamble and
|
142
|
+
# suffix, as exemplified below.
|
143
|
+
#
|
144
|
+
# preamble_start suffix_start
|
145
|
+
# | preamble_end | suffix_end
|
146
|
+
# | | | | termwidth
|
147
|
+
# | | | | |
|
148
|
+
# V V V V V
|
149
|
+
# --- Preamble text --------------------- suffix text --
|
150
|
+
o << color.code
|
151
|
+
o << print_at_x(preamble_start, HORIZONTAL * (termwidth - preamble_start)) # draw a full line
|
152
|
+
o << print_at_x(preamble_start, preamble)
|
153
|
+
o << color.code
|
154
|
+
o << print_at_x(suffix_start, suffix)
|
155
|
+
o << CLI::UI::Color::RESET.code
|
156
|
+
o << CLI::UI::ANSI.show_cursor
|
157
|
+
o << "\n"
|
158
|
+
|
159
|
+
o
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module CLI
|
2
|
+
module UI
|
3
|
+
module Frame
|
4
|
+
module FrameStyle
|
5
|
+
module Bracket
|
6
|
+
extend FrameStyle
|
7
|
+
|
8
|
+
VERTICAL = '┃'
|
9
|
+
HORIZONTAL = '━'
|
10
|
+
DIVIDER = '┣'
|
11
|
+
TOP_LEFT = '┏'
|
12
|
+
BOTTOM_LEFT = '┗'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def name
|
16
|
+
'bracket'
|
17
|
+
end
|
18
|
+
|
19
|
+
def prefix
|
20
|
+
VERTICAL
|
21
|
+
end
|
22
|
+
|
23
|
+
# Draws the "Open" line for this frame style
|
24
|
+
#
|
25
|
+
# ==== Attributes
|
26
|
+
#
|
27
|
+
# * +text+ - (required) the text/title to output in the frame
|
28
|
+
#
|
29
|
+
# ==== Options
|
30
|
+
#
|
31
|
+
# * +:color+ - (required) The color of the frame.
|
32
|
+
#
|
33
|
+
# ==== Output
|
34
|
+
#
|
35
|
+
# ┏━━ Open
|
36
|
+
#
|
37
|
+
def open(text, color:)
|
38
|
+
edge(text, color: color, first: TOP_LEFT)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Draws a "divider" line for the current frame style
|
42
|
+
#
|
43
|
+
# ==== Attributes
|
44
|
+
#
|
45
|
+
# * +text+ - (required) the text/title to output in the frame
|
46
|
+
#
|
47
|
+
# ==== Options
|
48
|
+
#
|
49
|
+
# * +:color+ - (required) The color of the frame.
|
50
|
+
#
|
51
|
+
# ==== Output:
|
52
|
+
#
|
53
|
+
# ┣━━ Divider
|
54
|
+
#
|
55
|
+
def divider(text, color:)
|
56
|
+
edge(text, color: color, first: DIVIDER)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Draws the "Close" line for this frame style
|
60
|
+
#
|
61
|
+
# ==== Attributes
|
62
|
+
#
|
63
|
+
# * +text+ - (required) the text/title to output in the frame
|
64
|
+
#
|
65
|
+
# ==== Options
|
66
|
+
#
|
67
|
+
# * +:color+ - (required) The color of the frame.
|
68
|
+
# * +:right_text+ - Text to print at the right of the line. Defaults to nil
|
69
|
+
#
|
70
|
+
# ==== Output:
|
71
|
+
#
|
72
|
+
# ┗━━ Close
|
73
|
+
#
|
74
|
+
def close(text, color:, right_text: nil)
|
75
|
+
edge(text, color: color, right_text: right_text, first: BOTTOM_LEFT)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def edge(text, color:, first:, right_text: nil)
|
81
|
+
color = CLI::UI.resolve_color(color)
|
82
|
+
|
83
|
+
preamble = +''
|
84
|
+
|
85
|
+
preamble << color.code << first << (HORIZONTAL * 2)
|
86
|
+
|
87
|
+
text ||= ''
|
88
|
+
unless text.empty?
|
89
|
+
preamble << ' ' << CLI::UI.resolve_text("{{#{color.name}:#{text}}}") << ' '
|
90
|
+
end
|
91
|
+
|
92
|
+
suffix = +''
|
93
|
+
|
94
|
+
if right_text
|
95
|
+
suffix << ' ' << right_text << ' '
|
96
|
+
end
|
97
|
+
|
98
|
+
o = +''
|
99
|
+
|
100
|
+
# Shopify's CI system supports terminal emulation, but not some of
|
101
|
+
# the fancier features that we normally use to draw frames
|
102
|
+
# extra-reliably, so we fall back to a less foolproof strategy. This
|
103
|
+
# is probably better in general for cases with impoverished terminal
|
104
|
+
# emulators and no active user.
|
105
|
+
unless [0, '', nil].include?(ENV['CI'])
|
106
|
+
o << color.code << preamble
|
107
|
+
o << color.code << suffix
|
108
|
+
o << CLI::UI::Color::RESET.code
|
109
|
+
o << "\n"
|
110
|
+
|
111
|
+
return o
|
112
|
+
end
|
113
|
+
|
114
|
+
preamble_start = Frame.prefix_width
|
115
|
+
|
116
|
+
# If prefix_width is non-zero, we need to subtract the width of
|
117
|
+
# the final space, since we're going to write over it.
|
118
|
+
preamble_start -= 1 unless preamble_start.zero?
|
119
|
+
|
120
|
+
# Prefix_width includes the width of the terminal space, which we
|
121
|
+
# want to remove. The clamping is done to avoid a negative
|
122
|
+
# preamble start which can occur for the first frame.
|
123
|
+
o << CLI::UI::ANSI.hide_cursor
|
124
|
+
|
125
|
+
# reset to column 1 so that things like ^C don't ruin formatting
|
126
|
+
o << "\r"
|
127
|
+
o << color.code
|
128
|
+
o << print_at_x(preamble_start, preamble + color.code + suffix)
|
129
|
+
o << CLI::UI::Color::RESET.code
|
130
|
+
o << "\n"
|
131
|
+
|
132
|
+
o
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|