colsole 0.7.2 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a430d377ca6b98614b6d3127bf1f35f2dc259b2bb4378bdc61570519d5126130
4
- data.tar.gz: c2e890a8104283b070323f9916db75bc9ec692d81e49630159b2127b0b8d83f9
3
+ metadata.gz: 2fd26345db2525e6804965d0686301be91d7c27d9fe3894550a781e73e1c2f72
4
+ data.tar.gz: f44de99c02442edeae3723d405be87fe29d845c130460ee16a23bf0aab254901
5
5
  SHA512:
6
- metadata.gz: 4bc5fc5638d1cb43b0a88d487686fd7afc918626446220b2874a419443bf2d4ac2dd24ac3711fe9f13a62fea07d80d0e1cea4a15d2da398b7f18ceba819fb401
7
- data.tar.gz: 3232586c10d02fdc7fd4ca3adc517cae833c62440eeec552bf2e50bc23d1d5192718212cbc7bd6dcda7647c404c55b11ac7427b7972911a8062c9e722a2a21c5
6
+ metadata.gz: ff6fb2074275bf9479ab0ba400bec991aa1d5972488c0c21c143ab012851733452aca15549278d770f8427c05ff5bcfad077f53c2649860ceb063934ebe0cba0
7
+ data.tar.gz: 8bd0e29dc5216b94ade0bec78636122bf015bbe502061655312cf52aaecd4c3462bac97310bf4e5f35d7ad0a51ad9fe5f4093d806b36968b4597f9df3789574a
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Colsole
2
- ==================================================
1
+ # Colsole
3
2
 
4
3
  [![Gem Version](https://badge.fury.io/rb/colsole.svg)](https://badge.fury.io/rb/colsole)
5
4
  [![Build Status](https://github.com/DannyBen/colsole/workflows/Test/badge.svg)](https://github.com/DannyBen/colsole/actions?query=workflow%3ATest)
@@ -9,32 +8,30 @@ Colsole
9
8
 
10
9
  Utility functions for colorful console applications.
11
10
 
12
- ---
11
+ > **Upgrade Note**
12
+ >
13
+ > This README is for the latest version of colsole (0.8.x), which is compatible
14
+ > with older versions. Version 1.x will NOT be compatible.
15
+ >
16
+ > See [Uprading](#upgrading) below.
13
17
 
18
+ ## Install
14
19
 
15
- Install
16
- --------------------------------------------------
20
+ Add to your Gemfile:
17
21
 
18
22
  ```
19
- $ gem install colsole
23
+ $ gem 'colsole', '>= 0.6.0', '< 2.0'
20
24
  ```
21
25
 
22
- Features
23
- --------------------------------------------------
24
-
25
- - Print colored messages
26
- - Color parts of a message
27
- - Print neatly aligned status messages
28
- - Word wrap with indentation consideration
26
+ ## Examples
29
27
 
30
- See the [Examples file][1] for more.
28
+ See the [Examples file](https://github.com/DannyBen/colsole/blob/master/example.rb).
31
29
 
32
- Primary Functions
33
- --------------------------------------------------
30
+ ## Primary Functions
34
31
 
35
32
  ### `say "anything"`
36
33
 
37
- An alternative to puts.
34
+ An alternative to puts with line wrapping, colors and more.
38
35
 
39
36
  ```ruby
40
37
  say "Hello"
@@ -47,30 +44,27 @@ say "appears in "
47
44
  say "one line"
48
45
  ```
49
46
 
50
- Embed color markers in the string:
47
+ Embed [color markers](#colors) in the string:
51
48
 
52
49
  ```ruby
53
- say "!txtred!I am RED !txtgrn!I am GREEN"
50
+ say "This is r`red`, and this gu`entire phrase is green underlined`"
54
51
  ```
55
52
 
56
- ### `say_status :status, "message" [, :color]`
57
-
58
- Print a message with a colored status
53
+ Provide the `replace: true` option after a space terminated "said" string to
54
+ rewrite the line:
59
55
 
60
56
  ```ruby
61
- say_status :create, "perpetual energy"
57
+ # space terminated string to say it without a newline
58
+ say "downloading data... "
59
+ # long process here...
60
+ say "download complete.", replace: true
62
61
  ```
63
62
 
64
- You can provide a color in the regulat 6 letter code:
65
-
66
- ```ruby
67
- say_status :error, "does not compute", :txtred
68
- ```
69
63
 
70
64
  ### `word_wrap " string" [, length]`
71
65
 
72
- Wrap long lines while keeping words intact, and keeping
73
- indentation based on the leading spaces in your string:
66
+ Wrap long lines while keeping words intact, and keeping indentation based on the
67
+ leading spaces in your string:
74
68
 
75
69
  ```ruby
76
70
  say word_wrap(" one two three four five", 15)
@@ -84,37 +78,21 @@ say word_wrap(" one two three four five", 15)
84
78
  If `length` is not provided, `word_wrap` will attempt to determine it
85
79
  automatically based on the width of the terminal.
86
80
 
87
-
88
- ### `resay "anything"`
89
-
90
- Use resay after a space terminated "said" string to rewrite the line
91
-
92
- ```ruby
93
- say "downloading... "
94
- # long process here...
95
- resay "downloaded."
96
- ```
97
-
98
-
99
81
  ### `say! "anything to stderr"`
100
82
 
101
83
  Use say! to output to stderr with color markers:
102
84
 
103
85
  ```ruby
104
- say! "!txtred!Error!txtrst!: This just did not work"
86
+ # red inverted ERROR
87
+ say! "ri` ERROR ` This just did not work"
105
88
  ```
106
89
 
107
- Utility / Support Functions
108
- --------------------------------------------------
90
+ ## Utility / Support Functions
109
91
 
110
- ### `colorize "!txtred!Hello"`
92
+ ### `colorize "string"`
111
93
 
112
94
  Parses and returns a color-flagged string.
113
95
 
114
- Respects pipe and auto terminates colored strings.
115
-
116
- Call without text to see a list/demo of all available colors.
117
-
118
96
  ### `terminal?`
119
97
 
120
98
  Returns true if we are running in an interactive terminal
@@ -123,21 +101,76 @@ Returns true if we are running in an interactive terminal
123
101
 
124
102
  Checks if the provided string is a command in the path.
125
103
 
126
- ### `detect_terminal_size fallback_value`
104
+ ### `terminal_size [fallback_cols, fallback_rows]`
127
105
 
128
106
  Returns an array `[width, height]` of the terminal, or the supplied
129
- `fallback_value` if it is unable to detect.
107
+ fallback if it is unable to detect.
108
+
109
+ ### `terminal_width` / `terminal_height`
110
+
111
+ Returns only the terminal width or height. This is a shortcut to
112
+ `terminal_size[0]` / terminal_size[1].
130
113
 
131
- ### `terminal_width`
132
114
 
133
- Returns only the terminal width. This is a shortcut to
134
- `detect_terminal_size[0]`.
115
+ ## Colors
135
116
 
117
+ Strings that are surrounded by backticks, and preceded by a color code and
118
+ optional styling markers will be converted to the respective ANSI color.
119
+
120
+ ```ruby
121
+ say "this is b`blue` and ru`this is red underlined`"
122
+ ```
136
123
 
137
- Color Codes
138
- --------------------------------------------------
124
+ The one letter color code is required, followed by up to 3 style code.
139
125
 
140
- [![Color Codes](https://raw.githubusercontent.com/DannyBen/colsole/master/color-codes.png)](https://raw.githubusercontent.com/DannyBen/colsole/master/color-codes.png)
126
+ | Color Code | Color
127
+ |------------|-------
128
+ | `n` | no color
129
+ | `k` | black
130
+ | `r` | red
131
+ | `g` | green
132
+ | `y` | yellow
133
+ | `b` | blue
134
+ | `m` | magenta
135
+ | `c` | cyan
136
+ | `w` | white
141
137
 
138
+ | Style Code | Style
139
+ |------------|-------
140
+ | `b` | bold
141
+ | `u` | underlined
142
+ | `i` | inverted
143
+ | `z` | terminate
142
144
 
143
- [1]: https://github.com/DannyBen/colsole/blob/master/example.rb
145
+ ## Upgrading
146
+
147
+ Version 0.8.x changes several things, including the syntax of the color
148
+ markers. For easy transition, it is compatible with older versions.
149
+
150
+ Follow these steps to upgrade:
151
+
152
+ ```ruby
153
+
154
+ # => Require a more flexible version
155
+ # change this
156
+ gem 'colsole'
157
+ # to this (to avoid conflicts with other gems that require 0.x)
158
+ gem 'colsole', '>= 0.6.0', '< 2.0'
159
+
160
+ # => Remove 'say_status'
161
+ # It will no longer be supported in 1.0.0
162
+ say_status "text"
163
+
164
+ # => Replace 'resay'
165
+ # 'resay' is replaced with 'say replace: true'
166
+ # change this
167
+ resay "text"
168
+ # to this
169
+ say "text", replace: true
170
+
171
+ # => Change color markers syntax
172
+ # replace this
173
+ say "the !txtblu!blue"
174
+ # with this
175
+ say "the b`blue`"
176
+ ```
@@ -0,0 +1,55 @@
1
+ # This file contains methods that are called by the main Colsole module
2
+ # for compatibility with older versions of colsole.
3
+ # Do not use these methods directly.
4
+ module Colsole
5
+ def old_colorize(text)
6
+ reset = colors['txtrst']
7
+ reset_called_last = true
8
+
9
+ out = text.gsub(/!([a-z]{6})!/) do
10
+ reset_called_last = $1 == 'txtrst'
11
+ colors[$1]
12
+ end
13
+
14
+ reset_called_last or out = "#{out}#{reset}"
15
+ out
16
+ end
17
+
18
+ def old_strip_colors(text)
19
+ text.gsub(/!([a-z]{6})!/, '')
20
+ end
21
+
22
+ def resay(text)
23
+ say text, replace: true
24
+ end
25
+
26
+ def say_status(status, message = nil, color = nil)
27
+ color ||= (message ? :txtgrn : :txtblu)
28
+ say "!#{color}!#{status.to_s.rjust 12} !txtrst! #{message}".strip
29
+ end
30
+
31
+ def colors
32
+ @colors ||= begin
33
+ esc = 27.chr
34
+ pattern = "#{esc}[%{decor};%{fg}m"
35
+
36
+ decors = { txt: 0, bld: 1, und: 4, rev: 7 }
37
+ color_codes = { blk: 0, red: 1, grn: 2, ylw: 3, blu: 4, pur: 5, cyn: 6, wht: 7 }
38
+ colors = {}
39
+
40
+ decors.each do |dk, dv|
41
+ color_codes.each do |ck, cv|
42
+ key = "#{dk}#{ck}"
43
+ val = pattern % { decor: dv, fg: "3#{cv}" }
44
+ colors[key] = val
45
+ end
46
+ end
47
+
48
+ colors['txtbld'] = "#{esc}[1m"
49
+ colors['txtund'] = "#{esc}[4m"
50
+ colors['txtrev'] = "#{esc}[7m"
51
+ colors['txtrst'] = "#{esc}[0m"
52
+ colors
53
+ end
54
+ end
55
+ end
@@ -1,3 +1,3 @@
1
1
  module Colsole
2
- VERSION = "0.7.2"
3
- end
2
+ VERSION = '0.8.0'
3
+ end
data/lib/colsole.rb CHANGED
@@ -1,103 +1,91 @@
1
- require "colsole/version"
2
-
3
- # Colsole - Colorful Console Applications
4
- #
5
- # This class provides several utility functions for console application
6
- # developers.
7
- #
8
- # - #colorize string - return a colorized strings
9
- # - #say string - print a string with colors
10
- # - #say! string - print a string with colors to stderr
11
- # - #resay string - same as say, but overwrite current line
12
- # - #say_status symbol, string [, color] - print a message with status
13
- # - #word_wrap string - wrap a string and maintain indentation
14
- # - #detect_terminal_size
15
- # - #terminal_width
16
- #
17
- # Credits:
18
- # terminal width detection by Gabrial Horner https://github.com/cldwalker
1
+ require 'io/console'
2
+ require 'colsole/compat'
19
3
 
4
+ # Utility functions for colorful console applications.
20
5
  module Colsole
21
- # Prints a color-flagged string.
22
- # Use color flags (like !txtred!) to change color in the string.
23
- # Space terminated strings will leave the cursor at the same line.
24
- def say(text, force_color = false)
25
- last = text[-1, 1]
26
- if terminal? and (last == ' ' or last == '\t')
27
- print colorize(text, force_color)
6
+ ANSI_COLORS = {
7
+ 'n' => '', # no color
8
+ 'k' => "\e[30m", # black
9
+ 'r' => "\e[31m", # red
10
+ 'g' => "\e[32m", # green
11
+ 'y' => "\e[33m", # yellow
12
+ 'b' => "\e[34m", # blue
13
+ 'm' => "\e[35m", # magenta
14
+ 'c' => "\e[36m", # cyan
15
+ 'w' => "\e[37m", # white
16
+ }
17
+
18
+ ANSI_STYLES = {
19
+ 'b' => "\e[1m", # bold
20
+ 'u' => "\e[4m", # underlined
21
+ 'i' => "\e[7m", # inverted
22
+ 'z' => "\e[0m", # terminate
23
+ }
24
+
25
+ # Output a string with optional color markers to stdout.
26
+ # If text is ended with a white space, you can call again with replace: true
27
+ # to replace that line
28
+ def say(text, replace: false)
29
+ internal_say text, $stdout, replace: replace
30
+ end
31
+
32
+ # Output a string with optional color markers to stderr.
33
+ # Behaves similarly to `#say`.
34
+ def say!(text, replace: false)
35
+ internal_say text, $stderr, replace: replace
36
+ end
37
+
38
+ # Returns true if stdout/stderr are a terminal
39
+ def terminal?(stream = $stdout)
40
+ case ENV['TTY']
41
+ when 'on' then true
42
+ when 'off' then false
28
43
  else
29
- print colorize("#{text}\n", force_color)
44
+ stream.tty?
30
45
  end
31
46
  end
32
47
 
33
- # Prints a color-flagged string to STDERR
34
- # Use color flags (like !txtred!) to change color in the string.
35
- def say!(text, force_color = false)
36
- $stderr.puts colorize(text, force_color, :stderr)
37
- end
38
-
39
- # Erase the current output line, and say a new string.
40
- # This should be used after a space terminated say().
41
- def resay(text, force_color = false)
42
- text = "\033[2K\r#{text}" if terminal?
43
- say text, force_color
44
- end
45
-
46
- # Prints a line with a colored status and message.
47
- # Status can be a symbol or a string. Color is optional, defaults to
48
- # green (:txtgrn) when there is a message, and to blue (:txtblu) when
49
- # there is only a status
50
- def say_status(status, message = nil, color = nil)
51
- color ||= (message ? :txtgrn : :txtblu)
52
- say "!#{color}!#{status.to_s.rjust 12} !txtrst! #{message}".strip
53
- end
54
-
55
- # Returns true if stdout/stderr is interactive terminal
56
- def terminal?(stream = :stdout)
57
- stream == :stdout ? out_terminal? : err_terminal?
58
- end
59
-
60
- # Returns true if stdout is interactive terminal
61
- def out_terminal?
62
- ENV['TTY'] == 'on' ? true : ENV['TTY'] == 'off' ? false : $stdout.tty?
63
- end
64
-
65
- # Returns true if stderr is interactive terminal
66
- def err_terminal?
67
- ENV['TTY'] == 'on' ? true : ENV['TTY'] == 'off' ? false : $stderr.tty?
68
- end
69
-
70
- # Determines if a shell command exists.
48
+ # Returns true if the command exists in the path
71
49
  def command_exist?(command)
72
50
  ENV['PATH'].split(File::PATH_SEPARATOR).any? do |dir|
73
51
  File.exist?(File.join dir, command) or File.exist?(File.join dir, "#{command}.exe")
74
52
  end
75
53
  end
76
54
 
77
- # Returns [width, height] of terminal when detected, or a default
78
- # value otherwise.
79
- def detect_terminal_size(default = [80,30])
80
- if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
81
- result = [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
82
- elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exist?('tput')
83
- result = [`tput cols 2>&1`.to_i, `tput lines 2>&1`.to_i]
84
- elsif STDIN.tty? && command_exist?('stty')
85
- result = `stty size 2>&1`.scan(/\d+/).map { |s| s.to_i }.reverse
55
+ # Returns true if we can and should use colors in this stream
56
+ def use_colors?(stream = $stdout)
57
+ ENV['FORCE_COLOR'] || (!ENV['NO_COLOR'] && terminal?(stream))
58
+ end
59
+
60
+ # Returns the terminal size as [columns, rows].
61
+ # Environment variables can be used to cheat.
62
+ def terminal_size(default = [80, 30])
63
+ result = if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
64
+ [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
86
65
  else
66
+ safe_get_tty_size default
67
+ end
68
+
69
+ unless result[0].is_a?(Integer) && result[1].is_a?(Integer) && result[0].positive? && result[1].positive?
87
70
  result = default
88
71
  end
89
- result = default unless result[0].is_a? Integer and result[1].is_a? Integer and result[0] > 0 and result[1] > 0
72
+
90
73
  result
91
74
  end
92
75
 
93
- # Returns terminal width
76
+ # Returns the columns part of the `#terminal_size`
94
77
  def terminal_width
95
- detect_terminal_size[0]
78
+ terminal_size[0]
79
+ end
80
+
81
+ # Returns the rows part of the `#terminal_size`
82
+ def terminal_height
83
+ terminal_size[1]
96
84
  end
97
85
 
98
86
  # Converts a long string to be wrapped keeping words in tact.
99
- # If the string starts with one or more spaces, they will be
100
- # preserved in all subsequent lines (i.e., remain indented).
87
+ # If the string starts with one or more spaces, they will be preserved in
88
+ # all subsequent lines (i.e., remain indented).
101
89
  def word_wrap(text, length = nil)
102
90
  length ||= terminal_width
103
91
  lead = text[/^\s*/]
@@ -105,7 +93,7 @@ module Colsole
105
93
  length -= lead.length
106
94
  text.split("\n").collect! do |line|
107
95
  if line.length > length
108
- line.gsub!(/([^\s]{#{length}})([^\s$])/, "\\1 \\2")
96
+ line.gsub!(/([^\s]{#{length}})([^\s$])/, '\\1 \\2')
109
97
  line.gsub(/(.{1,#{length}})(\s+|$)/, "#{lead}\\1\n").rstrip
110
98
  else
111
99
  "#{lead}#{line}"
@@ -113,68 +101,50 @@ module Colsole
113
101
  end * "\n"
114
102
  end
115
103
 
116
- # Parses and returns a color-flagged string.
117
- # Respects pipe and auto terminates colored strings.
118
- # Call without text to see a list/demo of all available colors.
119
- def colorize(text = nil, force_color = false, stream = :stdout)
120
- return show_color_demo if text.nil?
121
- return strip_color_markers(text) unless terminal?(stream) || force_color
122
- colorize! text
104
+ # Convert color markers to ansi colors.
105
+ def colorize(string)
106
+ # compatibility later
107
+ compat_string = old_colorize string
108
+
109
+ process_color_markers compat_string do |color, styles, text|
110
+ "#{styles}#{color}#{text}#{ANSI_STYLES['z']}"
111
+ end
123
112
  end
124
113
 
125
- private
114
+ # Remove color markers.
115
+ def strip_colors(string)
116
+ # compatibility layer
117
+ compat_string = old_strip_colors string
126
118
 
127
- def colors
128
- @colors ||= prepare_colors
119
+ process_color_markers(compat_string) { |_color, _styles, text| text }
129
120
  end
130
121
 
131
- def colorize!(text)
132
- reset = colors['txtrst']
133
- reset_called_last = true
122
+ private
134
123
 
135
- out = text.gsub(/\!([a-z]{6})\!/) do |m|
136
- reset_called_last = $1 == "txtrst"
137
- colors[$1]
124
+ def process_color_markers(string)
125
+ string.gsub(/([rgybmcn])([ubi]{0,3})`([^`]*)`/) do
126
+ color = ANSI_COLORS[$1]
127
+ styles = $2.chars.map { |a| ANSI_STYLES[a] }.join
128
+ text = $3
129
+ yield color, styles, text
138
130
  end
139
-
140
- reset_called_last or out = "#{out}#{reset}"
141
- out
142
131
  end
143
132
 
144
- # Create a colors array with keys such as :txtgrn and :bldgrn
145
- # and values which are the escape codes for the colors.
146
- def prepare_colors
147
- esc = 27.chr
148
- pattern = "#{esc}[%{decor};%{fg}m"
149
-
150
- decors = { txt: 0, bld: 1, und: 4, rev: 7 }
151
- color_codes = { blk: 0, red: 1, grn: 2, ylw: 3, blu: 4, pur: 5, cyn: 6, wht: 7 }
152
- colors = {}
153
-
154
- decors.each do |dk, dv|
155
- color_codes.each do |ck, cv|
156
- key = "#{dk}#{ck}"
157
- val = pattern % { decor: dv, fg: "3#{cv}" }
158
- colors[key] = val
159
- end
160
- end
161
- colors['txtbld'] = "#{esc}[1m"
162
- colors['txtund'] = "#{esc}[4m"
163
- colors['txtrev'] = "#{esc}[7m"
164
- colors['txtrst'] = "#{esc}[0m"
165
- colors
166
- end
133
+ def internal_say(text, stream, replace: false)
134
+ text = "\033[2K\r#{text}" if replace && terminal?
135
+ last = text[-1, 1]
136
+ handler = use_colors?(stream) ? :colorize : :strip_colors
167
137
 
168
- def show_color_demo
169
- i = colors.count
170
- colors.keys.each do |k|
171
- puts colorize "#{k} = !#{k}! #{i} bottles of beer on the wall !txtrst!"
172
- i -= 1
138
+ if terminal? && ((last == ' ') || (last == '\t'))
139
+ stream.print send(handler, text)
140
+ else
141
+ stream.print send(handler, "#{text}\n")
173
142
  end
174
143
  end
175
144
 
176
- def strip_color_markers(text)
177
- text.gsub(/\!([a-z]{6})\!/, '')
145
+ def safe_get_tty_size(default = [80, 30])
146
+ $stdout.winsize.reverse
147
+ rescue Errno::ENOTTY
148
+ default
178
149
  end
179
-
180
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: colsole
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-31 00:00:00.000000000 Z
11
+ date: 2023-01-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Utility functions for making colorful console applications
14
14
  email: db@dannyben.com
@@ -18,11 +18,13 @@ extra_rdoc_files: []
18
18
  files:
19
19
  - README.md
20
20
  - lib/colsole.rb
21
+ - lib/colsole/compat.rb
21
22
  - lib/colsole/version.rb
22
23
  homepage: https://github.com/DannyBen/colsole
23
24
  licenses:
24
25
  - MIT
25
- metadata: {}
26
+ metadata:
27
+ rubygems_mfa_required: 'true'
26
28
  post_install_message:
27
29
  rdoc_options: []
28
30
  require_paths:
@@ -31,14 +33,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
31
33
  requirements:
32
34
  - - ">="
33
35
  - !ruby/object:Gem::Version
34
- version: 2.3.0
36
+ version: 2.6.0
35
37
  required_rubygems_version: !ruby/object:Gem::Requirement
36
38
  requirements:
37
39
  - - ">="
38
40
  - !ruby/object:Gem::Version
39
41
  version: '0'
40
42
  requirements: []
41
- rubygems_version: 3.0.3
43
+ rubygems_version: 3.4.3
42
44
  signing_key:
43
45
  specification_version: 4
44
46
  summary: Colorful Console Applications