rfix 2.0.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/exe/rfix +11 -90
  3. data/lib/rfix.rb +10 -9
  4. data/lib/rfix/branch/reference.rb +2 -2
  5. data/lib/rfix/branch/upstream.rb +2 -4
  6. data/lib/rfix/cli/command.rb +14 -1
  7. data/lib/rfix/cli/command/all.rb +21 -0
  8. data/lib/rfix/cli/command/base.rb +30 -19
  9. data/lib/rfix/cli/command/branch.rb +2 -0
  10. data/lib/rfix/cli/command/help.rb +2 -0
  11. data/lib/rfix/cli/command/info.rb +6 -1
  12. data/lib/rfix/cli/command/local.rb +2 -0
  13. data/lib/rfix/cli/command/origin.rb +2 -0
  14. data/lib/rfix/cli/command/setup.rb +2 -0
  15. data/lib/rfix/cli/command/status.rb +39 -0
  16. data/lib/rfix/collector.rb +69 -0
  17. data/lib/rfix/diff.rb +69 -0
  18. data/lib/rfix/extension/comment_config.rb +15 -0
  19. data/lib/rfix/extension/offense.rb +17 -14
  20. data/lib/rfix/extension/pastel.rb +7 -4
  21. data/lib/rfix/extension/progresbar.rb +15 -0
  22. data/lib/rfix/extension/strings.rb +10 -2
  23. data/lib/rfix/file.rb +5 -3
  24. data/lib/rfix/file/base.rb +21 -14
  25. data/lib/rfix/file/deleted.rb +2 -0
  26. data/lib/rfix/file/ignored.rb +2 -0
  27. data/lib/rfix/file/null.rb +17 -0
  28. data/lib/rfix/file/tracked.rb +39 -23
  29. data/lib/rfix/file/undefined.rb +17 -0
  30. data/lib/rfix/file/untracked.rb +3 -1
  31. data/lib/rfix/formatter.rb +67 -71
  32. data/lib/rfix/highlighter.rb +1 -3
  33. data/lib/rfix/rake/gemfile.rb +26 -23
  34. data/lib/rfix/repository.rb +59 -96
  35. data/lib/rfix/types.rb +24 -14
  36. data/lib/rfix/version.rb +1 -1
  37. data/rfix.gemspec +11 -3
  38. data/vendor/cli-ui/Gemfile +17 -0
  39. data/vendor/cli-ui/Gemfile.lock +60 -0
  40. data/vendor/cli-ui/LICENSE.txt +21 -0
  41. data/vendor/cli-ui/README.md +224 -0
  42. data/vendor/cli-ui/Rakefile +20 -0
  43. data/vendor/cli-ui/bin/console +14 -0
  44. data/vendor/cli-ui/cli-ui.gemspec +25 -0
  45. data/vendor/cli-ui/dev.yml +14 -0
  46. data/vendor/cli-ui/lib/cli/ui.rb +233 -0
  47. data/vendor/cli-ui/lib/cli/ui/ansi.rb +157 -0
  48. data/vendor/cli-ui/lib/cli/ui/color.rb +84 -0
  49. data/vendor/cli-ui/lib/cli/ui/formatter.rb +192 -0
  50. data/vendor/cli-ui/lib/cli/ui/frame.rb +269 -0
  51. data/vendor/cli-ui/lib/cli/ui/frame/frame_stack.rb +98 -0
  52. data/vendor/cli-ui/lib/cli/ui/frame/frame_style.rb +120 -0
  53. data/vendor/cli-ui/lib/cli/ui/frame/frame_style/box.rb +166 -0
  54. data/vendor/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +139 -0
  55. data/vendor/cli-ui/lib/cli/ui/glyph.rb +84 -0
  56. data/vendor/cli-ui/lib/cli/ui/os.rb +67 -0
  57. data/vendor/cli-ui/lib/cli/ui/printer.rb +59 -0
  58. data/vendor/cli-ui/lib/cli/ui/progress.rb +90 -0
  59. data/vendor/cli-ui/lib/cli/ui/prompt.rb +297 -0
  60. data/vendor/cli-ui/lib/cli/ui/prompt/interactive_options.rb +484 -0
  61. data/vendor/cli-ui/lib/cli/ui/prompt/options_handler.rb +29 -0
  62. data/vendor/cli-ui/lib/cli/ui/spinner.rb +66 -0
  63. data/vendor/cli-ui/lib/cli/ui/spinner/async.rb +40 -0
  64. data/vendor/cli-ui/lib/cli/ui/spinner/spin_group.rb +263 -0
  65. data/vendor/cli-ui/lib/cli/ui/stdout_router.rb +232 -0
  66. data/vendor/cli-ui/lib/cli/ui/terminal.rb +46 -0
  67. data/vendor/cli-ui/lib/cli/ui/truncater.rb +102 -0
  68. data/vendor/cli-ui/lib/cli/ui/version.rb +5 -0
  69. data/vendor/cli-ui/lib/cli/ui/widgets.rb +77 -0
  70. data/vendor/cli-ui/lib/cli/ui/widgets/base.rb +27 -0
  71. data/vendor/cli-ui/lib/cli/ui/widgets/status.rb +61 -0
  72. data/vendor/cli-ui/lib/cli/ui/wrap.rb +56 -0
  73. data/vendor/cli-ui/test/cli/ui/ansi_test.rb +32 -0
  74. data/vendor/cli-ui/test/cli/ui/cli_ui_test.rb +23 -0
  75. data/vendor/cli-ui/test/cli/ui/color_test.rb +40 -0
  76. data/vendor/cli-ui/test/cli/ui/formatter_test.rb +79 -0
  77. data/vendor/cli-ui/test/cli/ui/glyph_test.rb +68 -0
  78. data/vendor/cli-ui/test/cli/ui/printer_test.rb +103 -0
  79. data/vendor/cli-ui/test/cli/ui/progress_test.rb +46 -0
  80. data/vendor/cli-ui/test/cli/ui/prompt/options_handler_test.rb +39 -0
  81. data/vendor/cli-ui/test/cli/ui/prompt_test.rb +348 -0
  82. data/vendor/cli-ui/test/cli/ui/spinner/spin_group_test.rb +39 -0
  83. data/vendor/cli-ui/test/cli/ui/spinner_test.rb +141 -0
  84. data/vendor/cli-ui/test/cli/ui/stdout_router_test.rb +32 -0
  85. data/vendor/cli-ui/test/cli/ui/terminal_test.rb +26 -0
  86. data/vendor/cli-ui/test/cli/ui/truncater_test.rb +31 -0
  87. data/vendor/cli-ui/test/cli/ui/widgets/status_test.rb +49 -0
  88. data/vendor/cli-ui/test/cli/ui/widgets_test.rb +15 -0
  89. data/vendor/cli-ui/test/test_helper.rb +53 -0
  90. data/vendor/cli-ui/tmp/cache/bootsnap/compile-cache/d9/c036af0f3dc494 +0 -0
  91. data/vendor/cli-ui/tmp/cache/bootsnap/load-path-cache +0 -0
  92. data/vendor/dry-cli/lib/dry/cli/command.rb +2 -1
  93. data/vendor/dry-cli/tmp/cache/bootsnap/compile-cache/ff/a22a5daafbd74c +0 -0
  94. data/vendor/dry-cli/tmp/cache/bootsnap/load-path-cache +0 -0
  95. data/vendor/strings-ansi/tmp/cache/bootsnap/compile-cache/79/49cf49407b370e +0 -0
  96. data/vendor/strings-ansi/tmp/cache/bootsnap/load-path-cache +0 -0
  97. metadata +170 -9
  98. data/lib/rfix/extension/string.rb +0 -12
  99. 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