cri 2.6.0 → 2.6.1

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
  SHA1:
3
- metadata.gz: 0b5c4be8a90bd61c37d60ee1a789c51147f3d096
4
- data.tar.gz: 19f03a77cb1414c4c5ae591d47a93027642160db
3
+ metadata.gz: 42a611aea2f4ef126558c77832d3f87e4c7769ee
4
+ data.tar.gz: 4629089940c31510094b05bafef780756d72f2db
5
5
  SHA512:
6
- metadata.gz: 592d029e4b6294136592855225f57340d18f0e75511e01fed4ff1f14e2babb1f01bb8929671b96eefc2e373f4046d2aa283fe539dea65ef932a48919dea30ced
7
- data.tar.gz: 0c402294f210d83b2ed2680b59e01303be52dd097a932c65169cee955684be620a5364db00ef1fd72abfce735d7b4a1dc7ff581b4c5f159b9380e7870fa24dec
6
+ metadata.gz: 5722bead0775cc5d35b658d60318c7b530590681f751dcfb51b9bf6cfd9c0d065387237d7906b8c4163a324d4e1df288f76bcac6fa4fb37775336b8c2908feff
7
+ data.tar.gz: 67a2d794fa2206fd4487068cb4ffe6e3876c8c9c1b49951b180d7bc62ae4bc375db1a063fbebab89a5aac6bc3e314bdb6e41ced98bbca7e6838424514aa2a17d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cri (2.6.0)
4
+ cri (2.6.1)
5
5
  colored (~> 1.2)
6
6
 
7
7
  GEM
@@ -16,10 +16,10 @@ GEM
16
16
  term-ansicolor
17
17
  thor
18
18
  docile (1.1.3)
19
- mime-types (2.2)
20
- minitest (5.3.2)
21
- multi_json (1.9.2)
22
- rake (10.2.2)
19
+ mime-types (2.3)
20
+ minitest (5.3.4)
21
+ multi_json (1.10.1)
22
+ rake (10.3.2)
23
23
  rest-client (1.6.7)
24
24
  mime-types (>= 1.16)
25
25
  simplecov (0.8.2)
@@ -30,7 +30,7 @@ GEM
30
30
  term-ansicolor (1.3.0)
31
31
  tins (~> 1.0)
32
32
  thor (0.19.1)
33
- tins (1.0.1)
33
+ tins (1.3.0)
34
34
  yard (0.8.7.4)
35
35
 
36
36
  PLATFORMS
data/NEWS.md CHANGED
@@ -1,16 +1,21 @@
1
1
  Cri News
2
2
  ========
3
3
 
4
+ 2.6.1
5
+ -----
6
+
7
+ * Disable ANSI color codes when not supported (#31, #32)
8
+
4
9
  2.6.0
5
10
  -----
6
11
 
7
- * Added support for multi-valued options [Toon Willems]
12
+ * Added support for multi-valued options (#29) [Toon Willems]
8
13
 
9
14
  2.5.0
10
15
  -----
11
16
 
12
- * Made the default help command handle subcommands
13
- * Added `#raw` method to argument arrays, returning all arguments including `--`
17
+ * Made the default help command handle subcommands (#27)
18
+ * Added `#raw` method to argument arrays, returning all arguments including `--` (#22)
14
19
 
15
20
  2.4.1
16
21
  -----
@@ -21,14 +26,14 @@ Cri News
21
26
  2.4.0
22
27
  -----
23
28
 
24
- * Allowed either short or long option to be, eh, optional [Ken Coar]
25
- * Fixed wrap-and-indent behavior [Ken Coar]
29
+ * Allowed either short or long option to be, eh, optional (#9, #10) [Ken Coar]
30
+ * Fixed wrap-and-indent behavior (#12) [Ken Coar]
26
31
  * Moved version information into `cri/version`
27
32
 
28
33
  2.3.0
29
34
  -----
30
35
 
31
- * Added colors
36
+ * Added colors (#1)
32
37
  * Added support for marking commands as hidden
33
38
 
34
39
  2.2.1
@@ -4,7 +4,7 @@ link:http://rubygems.org/gems/cri[image:http://img.shields.io/gem/v/cri.svg[]]
4
4
  link:https://travis-ci.org/ddfreyne/cri[image:http://img.shields.io/travis/ddfreyne/cri.svg[]]
5
5
  link:https://coveralls.io/r/ddfreyne/cri[image:http://img.shields.io/coveralls/ddfreyne/cri.svg[]]
6
6
  link:https://codeclimate.com/github/ddfreyne/cri[image:http://img.shields.io/codeclimate/github/ddfreyne/cri.svg[]]
7
- link:http://inch-pages.github.io/github/ddfreyne/cri/[image:http://inch-pages.github.io/github/ddfreyne/cri.png[]]
7
+ link:http://inch-pages.github.io/github/ddfreyne/cri/[image:http://inch-pages.github.io/github/ddfreyne/cri.svg[]]
8
8
 
9
9
  Cri is a library for building easy-to-use commandline tools with support for
10
10
  nested commands.
data/lib/cri.rb CHANGED
@@ -21,10 +21,12 @@ module Cri
21
21
  end
22
22
 
23
23
  autoload 'Command', 'cri/command'
24
+ autoload 'StringFormatter', 'cri/string_formatter'
24
25
  autoload 'CommandDSL', 'cri/command_dsl'
25
26
  autoload 'CommandRunner', 'cri/command_runner'
26
27
  autoload 'HelpRenderer', 'cri/help_renderer'
27
28
  autoload 'OptionParser', 'cri/option_parser'
29
+ autoload 'Platform', 'cri/platform'
28
30
 
29
31
  end
30
32
 
@@ -302,6 +302,9 @@ module Cri
302
302
  #
303
303
  # @option params [Boolean] :verbose true if the help output should be
304
304
  # verbose, false otherwise.
305
+ #
306
+ # @option params [IO] :io ($stdout) the IO the help text is intended for.
307
+ # This influences the decision to enable/disable colored output.
305
308
  def help(params={})
306
309
  HelpRenderer.new(self, params).render
307
310
  end
@@ -23,5 +23,5 @@ run do |opts, args, cmd|
23
23
  resolved_cmd = args.inject(cmd.supercommand) do |acc, name|
24
24
  acc.command_named(name)
25
25
  end
26
- puts resolved_cmd.help(:verbose => is_verbose)
26
+ puts resolved_cmd.help(:verbose => is_verbose, :io => $stdout)
27
27
  end
@@ -4,81 +4,32 @@ require 'colored'
4
4
 
5
5
  module Cri::CoreExtensions
6
6
 
7
+ # @deprecated
7
8
  module String
8
9
 
9
- # Extracts individual paragraphs (separated by two newlines).
10
- #
11
- # @return [Array<String>] A list of paragraphs in the string
10
+ # @see Cri::StringFormatter#to_paragraphs
12
11
  def to_paragraphs
13
- lines = self.scan(/([^\n]+\n|[^\n]*$)/).map { |s| s[0].strip }
14
-
15
- paragraphs = [ [] ]
16
- lines.each do |line|
17
- if line.empty?
18
- paragraphs << []
19
- else
20
- paragraphs.last << line
21
- end
22
- end
23
-
24
- paragraphs.reject { |p| p.empty? }.map { |p| p.join(' ') }
12
+ Cri::StringFormatter.new.to_paragraphs(self)
25
13
  end
26
14
 
27
- # Word-wraps and indents the string.
28
- #
29
- # @param [Number] width The maximal width of each line. This also includes
30
- # indentation, i.e. the actual maximal width of the text is
31
- # `width`-`indentation`.
32
- #
33
- # @param [Number] indentation The number of spaces to indent each line.
34
- #
35
- # @return [String] The word-wrapped and indented string
15
+ # @see Cri::StringFormatter#to_paragraphs
36
16
  def wrap_and_indent(width, indentation)
37
- indented_width = width - indentation
38
- indent = ' ' * indentation
39
- # Split into paragraphs
40
- paragraphs = self.to_paragraphs
41
-
42
- # Wrap and indent each paragraph
43
- paragraphs.map do |paragraph|
44
- # Initialize
45
- lines = []
46
- line = ''
47
-
48
- # Split into words
49
- paragraph.split(/\s/).each do |word|
50
- # Begin new line if it's too long
51
- if (line + ' ' + word).length >= indented_width
52
- lines << line
53
- line = ''
54
- end
55
-
56
- # Add word to line
57
- line += (line == '' ? '' : ' ' ) + word
58
- end
59
- lines << line
60
-
61
- # Join lines
62
- lines.map { |l| indent + l }.join("\n")
63
- end.join("\n\n")
17
+ Cri::StringFormatter.new.wrap_and_indent(self, width, indentation)
64
18
  end
65
19
 
66
- # @return [String] The string, formatted to be used as a title in a section
67
- # in the help
20
+ # @see Cri::StringFormatter#format_as_title
68
21
  def formatted_as_title
69
- self.upcase.red.bold
22
+ Cri::StringFormatter.new.format_as_title(self)
70
23
  end
71
24
 
72
- # @return [String] The string, formatted to be used as the name of a command
73
- # in the help
25
+ # @see Cri::StringFormatter#format_as_command
74
26
  def formatted_as_command
75
- self.green
27
+ Cri::StringFormatter.new.format_as_command(self)
76
28
  end
77
29
 
78
- # @return [String] The string, formatted to be used as an option definition
79
- # of a command in the help
30
+ # @see Cri::StringFormatter#format_as_option
80
31
  def formatted_as_option
81
- self.yellow
32
+ Cri::StringFormatter.new.format_as_option(self)
82
33
  end
83
34
 
84
35
  end
@@ -15,6 +15,7 @@ module Cri
15
15
  def initialize(cmd, params={})
16
16
  @cmd = cmd
17
17
  @is_verbose = params.fetch(:verbose, false)
18
+ @io = params.fetch(:io, $stdout)
18
19
  end
19
20
 
20
21
  # @return [String] The help text for this command
@@ -32,13 +33,17 @@ module Cri
32
33
 
33
34
  private
34
35
 
36
+ def fmt
37
+ @_formatter ||= Cri::StringFormatter.new
38
+ end
39
+
35
40
  def append_summary(text)
36
41
  return if @cmd.summary.nil?
37
42
 
38
- text << "name".formatted_as_title << "\n"
39
- text << " #{@cmd.name.formatted_as_command} - #{@cmd.summary}" << "\n"
43
+ text << fmt.format_as_title("name", @io) << "\n"
44
+ text << " #{fmt.format_as_command(@cmd.name, @io)} - #{@cmd.summary}" << "\n"
40
45
  unless @cmd.aliases.empty?
41
- text << " aliases: " << @cmd.aliases.map { |a| a.formatted_as_command }.join(' ') << "\n"
46
+ text << " aliases: " << @cmd.aliases.map { |a| fmt.format_as_command(a, @io) }.join(' ') << "\n"
42
47
  end
43
48
  end
44
49
 
@@ -47,36 +52,36 @@ module Cri
47
52
 
48
53
  path = [ @cmd.supercommand ]
49
54
  path.unshift(path[0].supercommand) until path[0].nil?
50
- formatted_usage = @cmd.usage.gsub(/^([^\s]+)/) { |m| m.formatted_as_command }
51
- full_usage = path[1..-1].map { |c| c.name.formatted_as_command + ' ' }.join + formatted_usage
55
+ formatted_usage = @cmd.usage.gsub(/^([^\s]+)/) { |m| fmt.format_as_command(m, @io) }
56
+ full_usage = path[1..-1].map { |c| fmt.format_as_command(c.name, @io) + ' ' }.join + formatted_usage
52
57
 
53
58
  text << "\n"
54
- text << "usage".formatted_as_title << "\n"
55
- text << full_usage.wrap_and_indent(78, 4) << "\n"
59
+ text << fmt.format_as_title("usage", @io) << "\n"
60
+ text << fmt.wrap_and_indent(full_usage, 78, 4) << "\n"
56
61
  end
57
62
 
58
63
  def append_description(text)
59
64
  return if @cmd.description.nil?
60
65
 
61
66
  text << "\n"
62
- text << "description".formatted_as_title << "\n"
63
- text << @cmd.description.wrap_and_indent(78, 4) + "\n"
67
+ text << fmt.format_as_title("description", @io) << "\n"
68
+ text << fmt.wrap_and_indent(@cmd.description, 78, 4) + "\n"
64
69
  end
65
70
 
66
71
  def append_subcommands(text)
67
72
  return if @cmd.subcommands.empty?
68
73
 
69
74
  text << "\n"
70
- text << (@cmd.supercommand ? 'subcommands' : 'commands').formatted_as_title
75
+ text << fmt.format_as_title(@cmd.supercommand ? 'subcommands' : 'commands', @io)
71
76
  text << "\n"
72
77
 
73
78
  shown_subcommands = @cmd.subcommands.select { |c| !c.hidden? || @is_verbose }
74
- length = shown_subcommands.map { |c| c.name.formatted_as_command.size }.max
79
+ length = shown_subcommands.map { |c| fmt.format_as_command(c.name, @io).size }.max
75
80
 
76
81
  # Command
77
82
  shown_subcommands.sort_by { |cmd| cmd.name }.each do |cmd|
78
83
  text << sprintf(" %-#{length+4}s %s\n",
79
- cmd.name.formatted_as_command,
84
+ fmt.format_as_command(cmd.name, @io),
80
85
  cmd.summary)
81
86
  end
82
87
 
@@ -109,7 +114,7 @@ module Cri
109
114
  return if defs.empty?
110
115
 
111
116
  text << "\n"
112
- text << "#{name}".formatted_as_title
117
+ text << fmt.format_as_title("#{name}", @io)
113
118
  text << "\n"
114
119
 
115
120
  ordered_defs = defs.sort_by { |x| x[:short] || x[:long] }
@@ -124,7 +129,7 @@ module Cri
124
129
  " %-2s %-#{length+6}s",
125
130
  opt_def[:short] ? ('-' + opt_def[:short]) : '',
126
131
  opt_def[:long] ? ('--' + opt_def[:long]) : '')
127
- opt_text.formatted_as_option
132
+ fmt.format_as_option(opt_text, @io)
128
133
  end
129
134
 
130
135
  end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ module Cri
4
+
5
+ module Platform
6
+
7
+ # @return [Boolean] true if the current platform is Windows, false
8
+ # otherwise.
9
+ def self.windows?
10
+ !!(RUBY_PLATFORM =~ /windows|bccwin|cygwin|djgpp|mingw|mswin|wince/i)
11
+ end
12
+
13
+ # Checks whether colors can be enabled. For colors to be enabled, the given
14
+ # IO should be a TTY, and, when on Windows, ::Win32::Console::ANSI needs to
15
+ # be defined.
16
+ #
17
+ # @return [Boolean] True if colors should be enabled, false otherwise.
18
+ def self.color?(io)
19
+ if !io.tty?
20
+ false
21
+ elsif windows?
22
+ defined?(::Win32::Console::ANSI)
23
+ else
24
+ true
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+
3
+ require 'colored'
4
+
5
+ module Cri
6
+
7
+ class StringFormatter
8
+
9
+ # Extracts individual paragraphs (separated by two newlines).
10
+ #
11
+ # @param [String] s The string to format
12
+ #
13
+ # @return [Array<String>] A list of paragraphs in the string
14
+ def to_paragraphs(s)
15
+ lines = s.scan(/([^\n]+\n|[^\n]*$)/).map { |s| s[0].strip }
16
+
17
+ paragraphs = [ [] ]
18
+ lines.each do |line|
19
+ if line.empty?
20
+ paragraphs << []
21
+ else
22
+ paragraphs.last << line
23
+ end
24
+ end
25
+
26
+ paragraphs.reject { |p| p.empty? }.map { |p| p.join(' ') }
27
+ end
28
+
29
+ # Word-wraps and indents the string.
30
+ #
31
+ # @param [String] s The string to format
32
+ #
33
+ # @param [Number] width The maximal width of each line. This also includes
34
+ # indentation, i.e. the actual maximal width of the text is
35
+ # `width`-`indentation`.
36
+ #
37
+ # @param [Number] indentation The number of spaces to indent each line.
38
+ #
39
+ # @return [String] The word-wrapped and indented string
40
+ def wrap_and_indent(s, width, indentation)
41
+ indented_width = width - indentation
42
+ indent = ' ' * indentation
43
+ # Split into paragraphs
44
+ paragraphs = to_paragraphs(s)
45
+
46
+ # Wrap and indent each paragraph
47
+ paragraphs.map do |paragraph|
48
+ # Initialize
49
+ lines = []
50
+ line = ''
51
+
52
+ # Split into words
53
+ paragraph.split(/\s/).each do |word|
54
+ # Begin new line if it's too long
55
+ if (line + ' ' + word).length >= indented_width
56
+ lines << line
57
+ line = ''
58
+ end
59
+
60
+ # Add word to line
61
+ line += (line == '' ? '' : ' ' ) + word
62
+ end
63
+ lines << line
64
+
65
+ # Join lines
66
+ lines.map { |l| indent + l }.join("\n")
67
+ end.join("\n\n")
68
+ end
69
+
70
+ # @param [String] s The string to format
71
+ #
72
+ # @return [String] The string, formatted to be used as a title in a section
73
+ # in the help
74
+ def format_as_title(s, io)
75
+ if Cri::Platform.color?(io)
76
+ s.upcase.red.bold
77
+ else
78
+ s.upcase
79
+ end
80
+ end
81
+
82
+ # @param [String] s The string to format
83
+ #
84
+ # @return [String] The string, formatted to be used as the name of a command
85
+ # in the help
86
+ def format_as_command(s, io)
87
+ if Cri::Platform.color?(io)
88
+ s.green
89
+ else
90
+ s
91
+ end
92
+ end
93
+
94
+ # @param [String] s The string to format
95
+ #
96
+ # @return [String] The string, formatted to be used as an option definition
97
+ # of a command in the help
98
+ def format_as_option(s, io)
99
+ if Cri::Platform.color?(io)
100
+ s.yellow
101
+ else
102
+ s
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ end
@@ -3,6 +3,6 @@
3
3
  module Cri
4
4
 
5
5
  # The current Cri version.
6
- VERSION = '2.6.0'
6
+ VERSION = '2.6.1'
7
7
 
8
8
  end
@@ -253,16 +253,30 @@ class Cri::CommandTestCase < Cri::TestCase
253
253
  end
254
254
 
255
255
  def test_help_nested
256
+ def $stdout.tty? ; true ; end
257
+
256
258
  help = nested_cmd.subcommands.find { |cmd| cmd.name == 'sub' }.help
257
259
 
258
260
  assert help.include?("USAGE\e[0m\e[0m\n \e[32msuper\e[0m \e[32msub\e[0m [options]\n")
259
261
  end
260
262
 
263
+ def test_help_with_and_without_colors
264
+ def $stdout.tty? ; true ; end
265
+ help_on_tty = simple_cmd.help
266
+ def $stdout.tty? ; false ; end
267
+ help_not_on_tty = simple_cmd.help
268
+
269
+ assert_includes help_on_tty, "\e[31mUSAGE\e[0m\e[0m\n \e[32mmoo"
270
+ assert_includes help_not_on_tty, "USAGE\n moo"
271
+ end
272
+
261
273
  def test_help_for_bare_cmd
262
274
  bare_cmd.help
263
275
  end
264
276
 
265
277
  def test_help_with_optional_options
278
+ def $stdout.tty? ; true ; end
279
+
266
280
  cmd = Cri::Command.define do
267
281
  name 'build'
268
282
  flag :s, nil, 'short'
@@ -2,6 +2,10 @@
2
2
 
3
3
  class Cri::CoreExtTestCase < Cri::TestCase
4
4
 
5
+ def formatter
6
+ Cri::StringFormatter.new
7
+ end
8
+
5
9
  def test_string_to_paragraphs
6
10
  original = "Lorem ipsum dolor sit amet,\nconsectetur adipisicing.\n\n" +
7
11
  "Sed do eiusmod\ntempor incididunt ut labore."
@@ -9,7 +13,7 @@ class Cri::CoreExtTestCase < Cri::TestCase
9
13
  expected = [ "Lorem ipsum dolor sit amet, consectetur adipisicing.",
10
14
  "Sed do eiusmod tempor incididunt ut labore." ]
11
15
 
12
- actual = original.to_paragraphs
16
+ actual = formatter.to_paragraphs(original)
13
17
  assert_equal expected, actual
14
18
  end
15
19
 
@@ -23,7 +27,7 @@ class Cri::CoreExtTestCase < Cri::TestCase
23
27
  "incididunt ut labore et dolore magna\n" +
24
28
  "aliqua."
25
29
 
26
- actual = original.wrap_and_indent(40, 0)
30
+ actual = formatter.wrap_and_indent(original, 40, 0)
27
31
  assert_equal expected, actual
28
32
  end
29
33
 
@@ -38,7 +42,7 @@ class Cri::CoreExtTestCase < Cri::TestCase
38
42
  " incididunt ut labore et dolore\n" +
39
43
  " magna aliqua."
40
44
 
41
- actual = original.wrap_and_indent(36, 4)
45
+ actual = formatter.wrap_and_indent(original, 36, 4)
42
46
  assert_equal expected, actual
43
47
  end
44
48
 
@@ -60,7 +64,7 @@ class Cri::CoreExtTestCase < Cri::TestCase
60
64
  " dolore magna\n" +
61
65
  " aliqua."
62
66
 
63
- actual = original.wrap_and_indent(44, 30)
67
+ actual = formatter.wrap_and_indent(original, 44, 30)
64
68
  assert_equal expected, actual
65
69
  end
66
70
 
@@ -75,7 +79,7 @@ class Cri::CoreExtTestCase < Cri::TestCase
75
79
  " incididunt ut labore et dolore\n" +
76
80
  " magna aliqua."
77
81
 
78
- actual = original.wrap_and_indent(36, 4)
82
+ actual = formatter.wrap_and_indent(original, 36, 4)
79
83
  assert_equal expected, actual
80
84
  end
81
85
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-05 00:00:00.000000000 Z
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored
@@ -66,6 +66,8 @@ files:
66
66
  - lib/cri/core_ext/string.rb
67
67
  - lib/cri/help_renderer.rb
68
68
  - lib/cri/option_parser.rb
69
+ - lib/cri/platform.rb
70
+ - lib/cri/string_formatter.rb
69
71
  - lib/cri/version.rb
70
72
  - test/helper.rb
71
73
  - test/test_argument_array.rb
@@ -75,8 +77,8 @@ files:
75
77
  - test/test_command.rb
76
78
  - test/test_command_dsl.rb
77
79
  - test/test_command_runner.rb
78
- - test/test_core_ext.rb
79
80
  - test/test_option_parser.rb
81
+ - test/test_string_formatter.rb
80
82
  homepage: http://stoneship.org/software/cri/
81
83
  licenses:
82
84
  - MIT
@@ -99,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
101
  version: '0'
100
102
  requirements: []
101
103
  rubyforge_project:
102
- rubygems_version: 2.2.0
104
+ rubygems_version: 2.2.2
103
105
  signing_key:
104
106
  specification_version: 4
105
107
  summary: a library for building easy-to-use commandline tools