command_kit 0.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +29 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +283 -0
- data/Rakefile +23 -0
- data/command_kit.gemspec +60 -0
- data/gemspec.yml +14 -0
- data/lib/command_kit.rb +1 -0
- data/lib/command_kit/arguments.rb +161 -0
- data/lib/command_kit/arguments/argument.rb +111 -0
- data/lib/command_kit/arguments/argument_value.rb +81 -0
- data/lib/command_kit/arguments/usage.rb +6 -0
- data/lib/command_kit/colors.rb +355 -0
- data/lib/command_kit/command.rb +42 -0
- data/lib/command_kit/command_name.rb +95 -0
- data/lib/command_kit/commands.rb +299 -0
- data/lib/command_kit/commands/auto_load.rb +153 -0
- data/lib/command_kit/commands/auto_load/subcommand.rb +90 -0
- data/lib/command_kit/commands/auto_require.rb +138 -0
- data/lib/command_kit/commands/command.rb +12 -0
- data/lib/command_kit/commands/help.rb +43 -0
- data/lib/command_kit/commands/parent_command.rb +21 -0
- data/lib/command_kit/commands/subcommand.rb +51 -0
- data/lib/command_kit/console.rb +141 -0
- data/lib/command_kit/description.rb +89 -0
- data/lib/command_kit/env.rb +43 -0
- data/lib/command_kit/env/home.rb +71 -0
- data/lib/command_kit/env/path.rb +71 -0
- data/lib/command_kit/examples.rb +99 -0
- data/lib/command_kit/exception_handler.rb +55 -0
- data/lib/command_kit/help.rb +62 -0
- data/lib/command_kit/help/man.rb +125 -0
- data/lib/command_kit/inflector.rb +84 -0
- data/lib/command_kit/main.rb +103 -0
- data/lib/command_kit/options.rb +179 -0
- data/lib/command_kit/options/option.rb +171 -0
- data/lib/command_kit/options/option_value.rb +90 -0
- data/lib/command_kit/options/parser.rb +227 -0
- data/lib/command_kit/options/quiet.rb +53 -0
- data/lib/command_kit/options/usage.rb +6 -0
- data/lib/command_kit/options/verbose.rb +55 -0
- data/lib/command_kit/options/version.rb +62 -0
- data/lib/command_kit/os.rb +47 -0
- data/lib/command_kit/pager.rb +115 -0
- data/lib/command_kit/printing.rb +32 -0
- data/lib/command_kit/printing/indent.rb +78 -0
- data/lib/command_kit/program_name.rb +57 -0
- data/lib/command_kit/stdio.rb +138 -0
- data/lib/command_kit/usage.rb +102 -0
- data/lib/command_kit/version.rb +4 -0
- data/lib/command_kit/xdg.rb +138 -0
- data/spec/arguments/argument_spec.rb +169 -0
- data/spec/arguments/argument_value_spec.rb +126 -0
- data/spec/arguments_spec.rb +213 -0
- data/spec/colors_spec.rb +470 -0
- data/spec/command_kit_spec.rb +8 -0
- data/spec/command_name_spec.rb +130 -0
- data/spec/command_spec.rb +49 -0
- data/spec/commands/auto_load/subcommand_spec.rb +82 -0
- data/spec/commands/auto_load_spec.rb +128 -0
- data/spec/commands/auto_require_spec.rb +142 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +10 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +10 -0
- data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +10 -0
- data/spec/commands/help_spec.rb +66 -0
- data/spec/commands/parent_command_spec.rb +40 -0
- data/spec/commands/subcommand_spec.rb +99 -0
- data/spec/commands_spec.rb +767 -0
- data/spec/console_spec.rb +201 -0
- data/spec/description_spec.rb +203 -0
- data/spec/env/home_spec.rb +46 -0
- data/spec/env/path_spec.rb +78 -0
- data/spec/env_spec.rb +123 -0
- data/spec/examples_spec.rb +235 -0
- data/spec/exception_handler_spec.rb +103 -0
- data/spec/help_spec.rb +119 -0
- data/spec/inflector_spec.rb +104 -0
- data/spec/main_spec.rb +179 -0
- data/spec/options/option_spec.rb +258 -0
- data/spec/options/option_value_spec.rb +67 -0
- data/spec/options/parser_spec.rb +265 -0
- data/spec/options_spec.rb +137 -0
- data/spec/os_spec.rb +46 -0
- data/spec/pager_spec.rb +154 -0
- data/spec/printing/indent_spec.rb +130 -0
- data/spec/printing_spec.rb +76 -0
- data/spec/program_name_spec.rb +62 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stdio_spec.rb +264 -0
- data/spec/usage_spec.rb +237 -0
- data/spec/xdg_spec.rb +191 -0
- metadata +156 -0
data/gemspec.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
name: command_kit
|
2
|
+
summary: A toolkit for building Ruby CLI commands
|
3
|
+
description:
|
4
|
+
A Ruby toolkit for building clean, correct, and robust CLI commands as
|
5
|
+
Ruby classes.
|
6
|
+
license: MIT
|
7
|
+
authors: Postmodern
|
8
|
+
email: postmodern.mod3@gmail.com
|
9
|
+
homepage: https://github.com/postmodern/command_kit#readme
|
10
|
+
|
11
|
+
required_ruby_version: ">= 2.7.0"
|
12
|
+
|
13
|
+
development_dependencies:
|
14
|
+
bundler: ~> 2.0
|
data/lib/command_kit.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'command_kit/version'
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'command_kit/help'
|
2
|
+
require 'command_kit/arguments/argument'
|
3
|
+
|
4
|
+
module CommandKit
|
5
|
+
#
|
6
|
+
# Provides a thin DSL for defining arguments as attributes.
|
7
|
+
#
|
8
|
+
# ## Examples
|
9
|
+
#
|
10
|
+
# include CommandKit::Arguments
|
11
|
+
#
|
12
|
+
# argument :output, type: String,
|
13
|
+
# desc: 'The output file'
|
14
|
+
#
|
15
|
+
# argument :input, type: Array,
|
16
|
+
# desc: 'The input file(s)'
|
17
|
+
#
|
18
|
+
module Arguments
|
19
|
+
include Help
|
20
|
+
|
21
|
+
module ModuleMethods
|
22
|
+
#
|
23
|
+
# Extends {ClassMethods} or {ModuleMethods}, depending on whether
|
24
|
+
# {Arguments} is being included into a class or module.
|
25
|
+
#
|
26
|
+
# @param [Class, Module] context
|
27
|
+
# The class or module which is including {Arguments}.
|
28
|
+
#
|
29
|
+
def included(context)
|
30
|
+
super(context)
|
31
|
+
|
32
|
+
if context.class == Module
|
33
|
+
context.extend ModuleMethods
|
34
|
+
else
|
35
|
+
context.extend ClassMethods
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
extend ModuleMethods
|
41
|
+
|
42
|
+
#
|
43
|
+
# Defines class-level methods.
|
44
|
+
#
|
45
|
+
module ClassMethods
|
46
|
+
#
|
47
|
+
# All defined arguments for the class.
|
48
|
+
#
|
49
|
+
# @return [Hash{Symbol => Argument}]
|
50
|
+
# The defined argument for the class and it's superclass.
|
51
|
+
#
|
52
|
+
def arguments
|
53
|
+
@arguments ||= if superclass.kind_of?(ClassMethods)
|
54
|
+
superclass.arguments.dup
|
55
|
+
else
|
56
|
+
{}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Defines an argument for the class.
|
62
|
+
#
|
63
|
+
# @param [Symbol] name
|
64
|
+
# The argument name.
|
65
|
+
#
|
66
|
+
# @yield [(arg)]
|
67
|
+
# If a block is given, it will be passed the parsed argument.
|
68
|
+
#
|
69
|
+
# @yieldparam [Object, nil] arg
|
70
|
+
# The parsed argument.
|
71
|
+
#
|
72
|
+
# @return [Argument]
|
73
|
+
# The newly defined argument.
|
74
|
+
#
|
75
|
+
# @example Define an argument:
|
76
|
+
# argument :bar, desc: "Bar argument"
|
77
|
+
#
|
78
|
+
# @example With a custom usage string:
|
79
|
+
# option :bar, usage: 'BAR',
|
80
|
+
# desc: "Bar argument"
|
81
|
+
#
|
82
|
+
# @example With a custom block:
|
83
|
+
# argument :bar, desc: "Bar argument" do |bar|
|
84
|
+
# # ...
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# @example With a custom type:
|
88
|
+
# argument :bar, type: Integer,
|
89
|
+
# desc: "Bar argument"
|
90
|
+
#
|
91
|
+
# @example With a default value:
|
92
|
+
# argument :bar, default: "bar.txt",
|
93
|
+
# desc: "Bar argument"
|
94
|
+
#
|
95
|
+
# @example An optional argument:
|
96
|
+
# argument :bar, required: true,
|
97
|
+
# desc: "Bar argument"
|
98
|
+
#
|
99
|
+
# @example A repeating argument:
|
100
|
+
# argument :bar, repeats: true,
|
101
|
+
# desc: "Bar argument"
|
102
|
+
#
|
103
|
+
def argument(name,**kwargs,&block)
|
104
|
+
arguments[name] = Argument.new(name,**kwargs,&block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Checks the minimum/maximum number of arguments, then calls the
|
110
|
+
# superclass'es `#main`.
|
111
|
+
#
|
112
|
+
# @param [Array<String>] argv
|
113
|
+
# The arguments passed to the program.
|
114
|
+
#
|
115
|
+
# @return [Integer]
|
116
|
+
# The exit status code. If too few or too many arguments are given, then
|
117
|
+
# an error message is printed and `1` is returned.
|
118
|
+
#
|
119
|
+
def main(argv=[])
|
120
|
+
required_args = self.class.arguments.each_value.count(&:required?)
|
121
|
+
optional_args = self.class.arguments.each_value.count(&:optional?)
|
122
|
+
has_repeats_arg = self.class.arguments.each_value.any?(&:repeats?)
|
123
|
+
|
124
|
+
if argv.length < required_args
|
125
|
+
print_error("insufficient number of arguments.")
|
126
|
+
help_usage
|
127
|
+
return 1
|
128
|
+
elsif argv.length > (required_args + optional_args) && !has_repeats_arg
|
129
|
+
print_error("too many arguments given")
|
130
|
+
help_usage
|
131
|
+
return 1
|
132
|
+
end
|
133
|
+
|
134
|
+
super(argv)
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Prints any defined arguments, along with the usual `--help` information.
|
139
|
+
#
|
140
|
+
def help_arguments
|
141
|
+
unless (arguments = self.class.arguments).empty?
|
142
|
+
puts
|
143
|
+
puts 'Arguments:'
|
144
|
+
|
145
|
+
self.class.arguments.each_value do |arg|
|
146
|
+
puts " #{arg.usage.ljust(33)}#{arg.desc}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Calls the superclass'es `#help` method, if it's defined, then calls
|
153
|
+
# {#help_arguments}.
|
154
|
+
#
|
155
|
+
def help
|
156
|
+
super if defined?(super)
|
157
|
+
|
158
|
+
help_arguments
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'command_kit/arguments/argument_value'
|
2
|
+
|
3
|
+
module CommandKit
|
4
|
+
module Arguments
|
5
|
+
#
|
6
|
+
# Represents a defined argument.
|
7
|
+
#
|
8
|
+
class Argument < ArgumentValue
|
9
|
+
|
10
|
+
# @return [Symbol]
|
11
|
+
attr_reader :name
|
12
|
+
|
13
|
+
# @return [Boolean]
|
14
|
+
attr_reader :repeats
|
15
|
+
|
16
|
+
# @return [String, nil]
|
17
|
+
attr_reader :desc
|
18
|
+
|
19
|
+
# @return [Regexp, nil]
|
20
|
+
attr_reader :pattern
|
21
|
+
|
22
|
+
# @return [Proc, nil]
|
23
|
+
attr_reader :parser
|
24
|
+
|
25
|
+
# @return [Proc, nil]
|
26
|
+
attr_reader :block
|
27
|
+
|
28
|
+
#
|
29
|
+
# Initializes the argument.
|
30
|
+
#
|
31
|
+
# @param [Symbol] name
|
32
|
+
#
|
33
|
+
# @param [Class, Hash, Array, Regexp] type
|
34
|
+
#
|
35
|
+
# @param [String, nil] usage
|
36
|
+
#
|
37
|
+
# @param [Object, Proc, nil] default
|
38
|
+
#
|
39
|
+
# @param [Boolean] required
|
40
|
+
#
|
41
|
+
# @param [Boolean] repeats
|
42
|
+
#
|
43
|
+
# @param [String] desc
|
44
|
+
#
|
45
|
+
# @note `usage` will be assigned a default value based on `type` and
|
46
|
+
# `name`.
|
47
|
+
#
|
48
|
+
# @yield [(value)]
|
49
|
+
#
|
50
|
+
# @yieldparam [Object, nil] value
|
51
|
+
#
|
52
|
+
def initialize(name, type: String,
|
53
|
+
usage: name.to_s.upcase,
|
54
|
+
default: nil,
|
55
|
+
required: true,
|
56
|
+
repeats: false,
|
57
|
+
desc: ,
|
58
|
+
&block)
|
59
|
+
super(
|
60
|
+
type: type,
|
61
|
+
usage: usage,
|
62
|
+
default: default,
|
63
|
+
required: required
|
64
|
+
)
|
65
|
+
|
66
|
+
@name = name
|
67
|
+
@repeats = repeats
|
68
|
+
@desc = desc
|
69
|
+
|
70
|
+
@pattern, @parser = self.class.parser(@type)
|
71
|
+
|
72
|
+
@block = block
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Looks up the option parser for the given `OptionParser` type.
|
77
|
+
#
|
78
|
+
# @param [Class] type
|
79
|
+
# The `OptionParser` type class.
|
80
|
+
#
|
81
|
+
# @return [(Regexp, Proc), nil]
|
82
|
+
# The matching pattern and converter proc.
|
83
|
+
#
|
84
|
+
def self.parser(type)
|
85
|
+
OptionParser::DefaultList.search(:atype,type)
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Specifies whether the argument can be repeated repeat times.
|
90
|
+
#
|
91
|
+
# @return [Boolean]
|
92
|
+
#
|
93
|
+
def repeats?
|
94
|
+
@repeats
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# The usage string for the argument.
|
99
|
+
#
|
100
|
+
# @return [String]
|
101
|
+
#
|
102
|
+
def usage
|
103
|
+
string = @usage
|
104
|
+
string = "#{string} ..." if repeats?
|
105
|
+
string = "[#{string}]" if optional?
|
106
|
+
string
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module CommandKit
|
2
|
+
module Arguments
|
3
|
+
#
|
4
|
+
# Represents an individual argument value.
|
5
|
+
#
|
6
|
+
class ArgumentValue
|
7
|
+
|
8
|
+
# The desired type of the argument value.
|
9
|
+
#
|
10
|
+
# @return [Class, Hash, Array, Regexp, nil]
|
11
|
+
attr_reader :type
|
12
|
+
|
13
|
+
# The default parsed value for the argument value.
|
14
|
+
#
|
15
|
+
# @return [Object, Proc, nil]
|
16
|
+
attr_reader :default
|
17
|
+
|
18
|
+
# Specifies whether the argument value is required or optional.
|
19
|
+
#
|
20
|
+
# @return [Boolean]
|
21
|
+
attr_reader :required
|
22
|
+
|
23
|
+
# The usage string to describe the argument value.
|
24
|
+
#
|
25
|
+
# @return [String]
|
26
|
+
attr_reader :usage
|
27
|
+
|
28
|
+
#
|
29
|
+
# Initializes the argument value.
|
30
|
+
#
|
31
|
+
# @param [Class, Hash, Array, Regexp] type
|
32
|
+
# The type of the argument value.
|
33
|
+
#
|
34
|
+
# @param [Boolean] required
|
35
|
+
# Specifies whether the argument value is required or optional.
|
36
|
+
#
|
37
|
+
# @param [String] usage
|
38
|
+
# The usage string to represent the argument value.
|
39
|
+
#
|
40
|
+
# @param [Object, Proc, nil] default
|
41
|
+
# The default parsed value for the argument value.
|
42
|
+
#
|
43
|
+
def initialize(type: nil, required: true, default: nil, usage: )
|
44
|
+
@type = type
|
45
|
+
@required = required
|
46
|
+
@default = default
|
47
|
+
@usage = usage
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Determines if the argument is required or not.
|
52
|
+
#
|
53
|
+
# @return [Boolean]
|
54
|
+
#
|
55
|
+
def required?
|
56
|
+
@required
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Determines whether the argument can be omitted.
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
#
|
64
|
+
def optional?
|
65
|
+
!@required
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Returns a new default value.
|
70
|
+
#
|
71
|
+
# @return [Object]
|
72
|
+
#
|
73
|
+
def default_value
|
74
|
+
if @default.respond_to?(:call) then @default.call
|
75
|
+
else @default.dup
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,355 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'command_kit/stdio'
|
4
|
+
require 'command_kit/env'
|
5
|
+
|
6
|
+
module CommandKit
|
7
|
+
#
|
8
|
+
# Defines ANSI color codes.
|
9
|
+
#
|
10
|
+
# ## Examples
|
11
|
+
#
|
12
|
+
# include CommandKit::Colors
|
13
|
+
#
|
14
|
+
# def run
|
15
|
+
# puts colors.green("hello world")
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# ### Printing color error messages
|
19
|
+
#
|
20
|
+
# stderr.puts colors(stderr).red("error!")
|
21
|
+
#
|
22
|
+
# ## Environment Variables
|
23
|
+
#
|
24
|
+
# * `TERM` - Specifies the type of terminal. When set to `DUMB`, it will
|
25
|
+
# disable color output.
|
26
|
+
#
|
27
|
+
# ## Alternatives
|
28
|
+
#
|
29
|
+
# * [ansi](http://rubyworks.github.io/ansi/)
|
30
|
+
# * [colorize](https://github.com/fazibear/colorize#readme)
|
31
|
+
#
|
32
|
+
# @see https://en.wikipedia.org/wiki/ANSI_escape_code
|
33
|
+
#
|
34
|
+
module Colors
|
35
|
+
|
36
|
+
include Stdio
|
37
|
+
include Env
|
38
|
+
|
39
|
+
#
|
40
|
+
# Applies ANSI formatting to text.
|
41
|
+
#
|
42
|
+
module ANSI
|
43
|
+
# ANSI reset code
|
44
|
+
RESET = "\e[0m"
|
45
|
+
|
46
|
+
# @see RESET
|
47
|
+
CLEAR = RESET
|
48
|
+
|
49
|
+
# ANSI code for bold text
|
50
|
+
BOLD = "\e[1m"
|
51
|
+
|
52
|
+
# ANSI code to disable boldness
|
53
|
+
RESET_INTENSITY = "\e[22m"
|
54
|
+
|
55
|
+
# ANSI color code for black
|
56
|
+
BLACK = "\e[30m"
|
57
|
+
|
58
|
+
# ANSI color code for red
|
59
|
+
RED = "\e[31m"
|
60
|
+
|
61
|
+
# ANSI color code for green
|
62
|
+
GREEN = "\e[32m"
|
63
|
+
|
64
|
+
# ANSI color code for yellow
|
65
|
+
YELLOW = "\e[33m"
|
66
|
+
|
67
|
+
# ANSI color code for blue
|
68
|
+
BLUE = "\e[34m"
|
69
|
+
|
70
|
+
# ANSI color code for megenta
|
71
|
+
MAGENTA = "\e[35m"
|
72
|
+
|
73
|
+
# ANSI color code for cyan
|
74
|
+
CYAN = "\e[36m"
|
75
|
+
|
76
|
+
# ANSI color code for white
|
77
|
+
WHITE = "\e[37m"
|
78
|
+
|
79
|
+
# ANSI color for the default foreground color
|
80
|
+
RESET_COLOR = "\e[39m"
|
81
|
+
|
82
|
+
module_function
|
83
|
+
|
84
|
+
#
|
85
|
+
# Resets text formatting.
|
86
|
+
#
|
87
|
+
# @return [RESET]
|
88
|
+
#
|
89
|
+
# @see RESET
|
90
|
+
#
|
91
|
+
def reset
|
92
|
+
RESET
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# @see reset
|
97
|
+
#
|
98
|
+
def clear
|
99
|
+
reset
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Bolds the text.
|
104
|
+
#
|
105
|
+
# @param [String, nil] string
|
106
|
+
# An optional string.
|
107
|
+
#
|
108
|
+
# @return [String, BOLD]
|
109
|
+
# The bolded string or just {BOLD} if no arguments were given.
|
110
|
+
#
|
111
|
+
# @see BOLD
|
112
|
+
#
|
113
|
+
def bold(string=nil)
|
114
|
+
if string then "#{BOLD}#{string}#{RESET_INTENSITY}"
|
115
|
+
else BOLD
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# Sets the text color to black.
|
121
|
+
#
|
122
|
+
# @param [String, nil] string
|
123
|
+
# An optional string.
|
124
|
+
#
|
125
|
+
# @return [String, BLACK]
|
126
|
+
# The colorized string or just {BLACK} if no arguments were given.
|
127
|
+
#
|
128
|
+
# @see BLACK
|
129
|
+
#
|
130
|
+
def black(string=nil)
|
131
|
+
if string then "#{BLACK}#{string}#{RESET_COLOR}"
|
132
|
+
else BLACK
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Sets the text color to red.
|
138
|
+
#
|
139
|
+
# @param [String, nil] string
|
140
|
+
# An optional string.
|
141
|
+
#
|
142
|
+
# @return [String, RED]
|
143
|
+
# The colorized string or just {RED} if no arguments were given.
|
144
|
+
#
|
145
|
+
# @see RED
|
146
|
+
#
|
147
|
+
def red(string=nil)
|
148
|
+
if string then "#{RED}#{string}#{RESET_COLOR}"
|
149
|
+
else RED
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Sets the text color to green.
|
155
|
+
#
|
156
|
+
# @param [String, nil] string
|
157
|
+
# An optional string.
|
158
|
+
#
|
159
|
+
# @return [String, GREEN]
|
160
|
+
# The colorized string or just {GREEN} if no arguments were given.
|
161
|
+
#
|
162
|
+
# @see GREEN
|
163
|
+
#
|
164
|
+
def green(string=nil)
|
165
|
+
if string then "#{GREEN}#{string}#{RESET_COLOR}"
|
166
|
+
else GREEN
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# Sets the text color to yellow.
|
172
|
+
#
|
173
|
+
# @param [String, nil] string
|
174
|
+
# An optional string.
|
175
|
+
#
|
176
|
+
# @return [String, YELLOW]
|
177
|
+
# The colorized string or just {YELLOW} if no arguments were given.
|
178
|
+
#
|
179
|
+
# @see YELLOW
|
180
|
+
#
|
181
|
+
def yellow(string=nil)
|
182
|
+
if string then "#{YELLOW}#{string}#{RESET_COLOR}"
|
183
|
+
else YELLOW
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
#
|
188
|
+
# Sets the text color to blue.
|
189
|
+
#
|
190
|
+
# @param [String, nil] string
|
191
|
+
# An optional string.
|
192
|
+
#
|
193
|
+
# @return [String, BLUE]
|
194
|
+
# The colorized string or just {BLUE} if no arguments were given.
|
195
|
+
#
|
196
|
+
# @see BLUE
|
197
|
+
#
|
198
|
+
def blue(string=nil)
|
199
|
+
if string then "#{BLUE}#{string}#{RESET_COLOR}"
|
200
|
+
else BLUE
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
#
|
205
|
+
# Sets the text color to magenta.
|
206
|
+
#
|
207
|
+
# @param [String, nil] string
|
208
|
+
# An optional string.
|
209
|
+
#
|
210
|
+
# @return [String, MAGENTA]
|
211
|
+
# The colorized string or just {MAGENTA} if no arguments were given.
|
212
|
+
#
|
213
|
+
# @see MAGENTA
|
214
|
+
#
|
215
|
+
def magenta(string=nil)
|
216
|
+
if string then "#{MAGENTA}#{string}#{RESET_COLOR}"
|
217
|
+
else MAGENTA
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
#
|
222
|
+
# Sets the text color to cyan.
|
223
|
+
#
|
224
|
+
# @param [String, nil] string
|
225
|
+
# An optional string.
|
226
|
+
#
|
227
|
+
# @return [String, CYAN]
|
228
|
+
# The colorized string or just {CYAN} if no arguments were given.
|
229
|
+
#
|
230
|
+
# @see CYAN
|
231
|
+
#
|
232
|
+
def cyan(string=nil)
|
233
|
+
if string then "#{CYAN}#{string}#{RESET_COLOR}"
|
234
|
+
else CYAN
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
#
|
239
|
+
# Sets the text color to white.
|
240
|
+
#
|
241
|
+
# @param [String, nil] string
|
242
|
+
# An optional string.
|
243
|
+
#
|
244
|
+
# @return [String, WHITE]
|
245
|
+
# The colorized string or just {WHITE} if no arguments were given.
|
246
|
+
#
|
247
|
+
# @see WHITE
|
248
|
+
#
|
249
|
+
def white(string=nil)
|
250
|
+
if string then "#{WHITE}#{string}#{RESET_COLOR}"
|
251
|
+
else WHITE
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
#
|
257
|
+
# Dummy module with the same interface as {ANSI}, but for when ANSI is not
|
258
|
+
# supported.
|
259
|
+
#
|
260
|
+
module PlainText
|
261
|
+
RESET = \
|
262
|
+
CLEAR = \
|
263
|
+
BOLD = \
|
264
|
+
RESET_INTENSITY = \
|
265
|
+
BLACK = \
|
266
|
+
RED = \
|
267
|
+
GREEN = \
|
268
|
+
YELLOW = \
|
269
|
+
BLUE = \
|
270
|
+
MAGENTA = \
|
271
|
+
CYAN = \
|
272
|
+
WHITE = \
|
273
|
+
RESET_COLOR = ''
|
274
|
+
|
275
|
+
module_function
|
276
|
+
|
277
|
+
def reset
|
278
|
+
RESET
|
279
|
+
end
|
280
|
+
|
281
|
+
def clear
|
282
|
+
reset
|
283
|
+
end
|
284
|
+
|
285
|
+
def bold(string=nil)
|
286
|
+
string || ''
|
287
|
+
end
|
288
|
+
|
289
|
+
def black(string=nil)
|
290
|
+
string || ''
|
291
|
+
end
|
292
|
+
|
293
|
+
def red(string=nil)
|
294
|
+
string || ''
|
295
|
+
end
|
296
|
+
|
297
|
+
def green(string=nil)
|
298
|
+
string || ''
|
299
|
+
end
|
300
|
+
|
301
|
+
def yellow(string=nil)
|
302
|
+
string || ''
|
303
|
+
end
|
304
|
+
|
305
|
+
def blue(string=nil)
|
306
|
+
string || ''
|
307
|
+
end
|
308
|
+
|
309
|
+
def magenta(string=nil)
|
310
|
+
string || ''
|
311
|
+
end
|
312
|
+
|
313
|
+
def cyan(string=nil)
|
314
|
+
string || ''
|
315
|
+
end
|
316
|
+
|
317
|
+
def white(string=nil)
|
318
|
+
string || ''
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Checks if the stream supports ANSI output.
|
324
|
+
#
|
325
|
+
# @param [IO] stream
|
326
|
+
#
|
327
|
+
# @return [Boolean]
|
328
|
+
#
|
329
|
+
# @note
|
330
|
+
# When the env variable `TERM` is set to `dumb`, it will disable color
|
331
|
+
# output. Color output will also be disabled if the given stream is not
|
332
|
+
# a TTY.
|
333
|
+
#
|
334
|
+
def ansi?(stream=stdout)
|
335
|
+
env['TERM'] != 'dumb' && stream.tty?
|
336
|
+
end
|
337
|
+
|
338
|
+
#
|
339
|
+
# Returns the colors available for the given stream.
|
340
|
+
#
|
341
|
+
# @param [IO] stream
|
342
|
+
#
|
343
|
+
# @return [ANSI, PlainText]
|
344
|
+
# The ANSI module or PlainText dummy module.
|
345
|
+
#
|
346
|
+
def colors(stream=stdout)
|
347
|
+
color = if ansi?(stream) then ANSI
|
348
|
+
else PlainText
|
349
|
+
end
|
350
|
+
|
351
|
+
yield color if block_given?
|
352
|
+
return color
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|