tty-option 0.0.0 → 0.1.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/README.md +1653 -1
  4. data/lib/tty/option.rb +63 -4
  5. data/lib/tty/option/aggregate_errors.rb +95 -0
  6. data/lib/tty/option/conversions.rb +126 -0
  7. data/lib/tty/option/converter.rb +63 -0
  8. data/lib/tty/option/deep_dup.rb +48 -0
  9. data/lib/tty/option/dsl.rb +105 -0
  10. data/lib/tty/option/dsl/arity.rb +49 -0
  11. data/lib/tty/option/dsl/conversion.rb +17 -0
  12. data/lib/tty/option/error_aggregator.rb +35 -0
  13. data/lib/tty/option/errors.rb +144 -0
  14. data/lib/tty/option/formatter.rb +389 -0
  15. data/lib/tty/option/inflection.rb +50 -0
  16. data/lib/tty/option/param_conversion.rb +34 -0
  17. data/lib/tty/option/param_permitted.rb +30 -0
  18. data/lib/tty/option/param_validation.rb +48 -0
  19. data/lib/tty/option/parameter.rb +310 -0
  20. data/lib/tty/option/parameter/argument.rb +18 -0
  21. data/lib/tty/option/parameter/environment.rb +20 -0
  22. data/lib/tty/option/parameter/keyword.rb +15 -0
  23. data/lib/tty/option/parameter/option.rb +99 -0
  24. data/lib/tty/option/parameters.rb +157 -0
  25. data/lib/tty/option/params.rb +122 -0
  26. data/lib/tty/option/parser.rb +57 -3
  27. data/lib/tty/option/parser/arguments.rb +166 -0
  28. data/lib/tty/option/parser/arity_check.rb +34 -0
  29. data/lib/tty/option/parser/environments.rb +169 -0
  30. data/lib/tty/option/parser/keywords.rb +158 -0
  31. data/lib/tty/option/parser/options.rb +273 -0
  32. data/lib/tty/option/parser/param_types.rb +51 -0
  33. data/lib/tty/option/parser/required_check.rb +36 -0
  34. data/lib/tty/option/pipeline.rb +38 -0
  35. data/lib/tty/option/result.rb +46 -0
  36. data/lib/tty/option/section.rb +26 -0
  37. data/lib/tty/option/sections.rb +56 -0
  38. data/lib/tty/option/usage.rb +166 -0
  39. data/lib/tty/option/usage_wrapper.rb +58 -0
  40. data/lib/tty/option/version.rb +3 -3
  41. metadata +37 -3
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ module Option
5
+ class Section
6
+ attr_accessor :name, :content
7
+
8
+ def initialize(name, content = [])
9
+ @name = name
10
+ @content = content
11
+ end
12
+
13
+ def to_a
14
+ [name, content]
15
+ end
16
+
17
+ def empty?
18
+ content.empty?
19
+ end
20
+
21
+ def to_s
22
+ content
23
+ end
24
+ end # Section
25
+ end # Option
26
+ end # TTY
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ require_relative "section"
6
+
7
+ module TTY
8
+ module Option
9
+ class Sections
10
+ include Enumerable
11
+ extend Forwardable
12
+
13
+ def_delegators :@sections, :size, :to_a
14
+
15
+ def initialize
16
+ @sections = []
17
+ end
18
+
19
+ def [](name)
20
+ @sections.find { |s| s.name == name }
21
+ end
22
+
23
+ def add(name, content)
24
+ @sections << Section.new(name, content)
25
+ end
26
+
27
+ def add_before(name, sect_name, sect_content)
28
+ @sections.insert(find_index(name), Section.new(sect_name, sect_content))
29
+ end
30
+
31
+ def add_after(name, sect_name, sect_content)
32
+ @sections.insert(find_index(name) + 1, Section.new(sect_name, sect_content))
33
+ end
34
+
35
+ def replace(name, content)
36
+ self[name].content = content
37
+ end
38
+
39
+ def delete(*names)
40
+ @sections.delete_if { |s| names.include?(s.name) }
41
+ end
42
+
43
+ def each(&block)
44
+ @sections.each(&block)
45
+ end
46
+
47
+ private
48
+
49
+ def find_index(name)
50
+ index = @sections.index { |sect| sect.name == name }
51
+ return index if index
52
+ raise ArgumentError, "There is no section named: #{name.inspect}"
53
+ end
54
+ end # Section
55
+ end # Option
56
+ end # TTY
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "deep_dup"
4
+
5
+ module TTY
6
+ module Option
7
+ class Usage
8
+ # Create an usage
9
+ #
10
+ # @api public
11
+ def self.create(**properties, &block)
12
+ new(**properties, &block)
13
+ end
14
+
15
+ # Create an usage
16
+ #
17
+ # @api public
18
+ def initialize(**properties, &block)
19
+ @properties = {}
20
+ properties.each do |key, val|
21
+ case key.to_sym
22
+ when :desc, :description
23
+ key, val = :desc, [Array(val)]
24
+ when :header, :footer
25
+ val = [Array(val)]
26
+ when :example, :examples
27
+ key, val = :example, [Array(val)]
28
+ end
29
+ @properties[key.to_sym] = val
30
+ end
31
+
32
+ instance_eval(&block) if block_given?
33
+ end
34
+
35
+ # Program name for display in help and error messages
36
+ #
37
+ # @api public
38
+ def program(name = (not_set = true), &block)
39
+ if not_set
40
+ @properties.fetch(:program) { ::File.basename($0, ".*") }
41
+ else
42
+ @properties[:program] = name
43
+ end
44
+ end
45
+
46
+ # Action name for display in help and error messages
47
+ #
48
+ # @api public
49
+ def command(*values)
50
+ if values.empty?
51
+ @properties.fetch(:command) { [] }
52
+ else
53
+ @properties[:command] = []
54
+ values.each { |val| @properties[:command] << val }
55
+ end
56
+ end
57
+ alias commands command
58
+
59
+ # Remove default commands
60
+ #
61
+ # @api public
62
+ def no_command
63
+ @properties[:command] = []
64
+ end
65
+
66
+ def command?
67
+ @properties.key?(:command) && !@properties[:command].empty?
68
+ end
69
+
70
+ # Display info before anything else in the usage help
71
+ #
72
+ # @api public
73
+ def header(*values)
74
+ if values.empty?
75
+ @properties.fetch(:header) { [] }
76
+ else
77
+ (@properties[:header] ||= []) << values
78
+ end
79
+ end
80
+
81
+ def header?
82
+ @properties.key?(:header) && !@properties[:header].empty?
83
+ end
84
+
85
+ # Main way to show how all parameters can be used
86
+ #
87
+ # @api public
88
+ def banner(value = (not_set = true))
89
+ if not_set
90
+ @properties[:banner]
91
+ else
92
+ @properties[:banner] = value
93
+ end
94
+ end
95
+
96
+ def banner?
97
+ @properties.key?(:banner) && !@properties[:banner].nil?
98
+ end
99
+
100
+ # Description
101
+ #
102
+ # @api public
103
+ def desc(*values)
104
+ if values.empty?
105
+ @properties.fetch(:desc) { [] }
106
+ else
107
+ (@properties[:desc] ||= []) << values
108
+ end
109
+ end
110
+ alias description desc
111
+
112
+ def desc?
113
+ @properties.key?(:desc) && !@properties[:desc].empty?
114
+ end
115
+ alias description? desc?
116
+
117
+ # Collects usage examples
118
+ #
119
+ # @api public
120
+ def example(*values)
121
+ if values.empty?
122
+ @properties.fetch(:example) { [] }
123
+ else
124
+ (@properties[:example] ||= []) << values
125
+ end
126
+ end
127
+ alias examples example
128
+
129
+ def example?
130
+ @properties.key?(:example) && !@properties[:example].empty?
131
+ end
132
+ alias examples? example?
133
+
134
+ # Display info after everyting else in the usage help
135
+ #
136
+ # @api public
137
+ def footer(*values)
138
+ if values.empty?
139
+ @properties.fetch(:footer) { [] }
140
+ else
141
+ (@properties[:footer] ||= []) << values
142
+ end
143
+ end
144
+
145
+ def footer?
146
+ @properties.key?(:footer) && !@properties[:footer].empty?
147
+ end
148
+
149
+ # Return a hash of this usage properties
150
+ #
151
+ # @return [Hash] the names and values of this usage
152
+ #
153
+ # @api public
154
+ def to_h(&block)
155
+ if block_given?
156
+ @properties.each_with_object({}) do |(key, val), acc|
157
+ k, v = *block.(key, val)
158
+ acc[k] = v
159
+ end
160
+ else
161
+ DeepDup.deep_dup(@properties)
162
+ end
163
+ end
164
+ end # Usage
165
+ end # Option
166
+ end # TTY
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ module Option
5
+ module UsageWrapper
6
+ # Wrap a string to a maximum width with indentation
7
+ #
8
+ # @param [String] text
9
+ # @param [Integer] width
10
+ # @param [Integer] indent
11
+ # @param [Boolean] indent_first
12
+ #
13
+ # @api public
14
+ def wrap(text, width: 80, indent: 2, indent_first: false)
15
+ wrap = width - indent
16
+ lines = []
17
+
18
+ line, rest = *next_line(text, wrap: wrap)
19
+ lines << (indent_first ? " " * indent : "") + line
20
+
21
+ while !rest.nil?
22
+ line, rest = *next_line(rest, wrap: wrap)
23
+ lines << " " * indent + line.strip
24
+ end
25
+
26
+ lines.join("\n")
27
+ end
28
+ module_function :wrap
29
+
30
+ # Extract a line from a string and return remainder
31
+ #
32
+ # @param [String] str
33
+ # @param [Integer] wrap
34
+ #
35
+ # @return [Array<String, String>]
36
+ #
37
+ # @api private
38
+ def next_line(text, wrap: nil)
39
+ line = text[0, wrap + 1] # account for word boundary
40
+ index = line.index("\n", 1)
41
+
42
+ # line without newlines and can be broken
43
+ if (index.nil? || index.zero?) && wrap < line.length
44
+ index = line.rindex(/\s/)
45
+ end
46
+
47
+ # line without any whitespace
48
+ if index.nil? || index.zero?
49
+ index = wrap
50
+ end
51
+
52
+ [text[0...index], text[index..-1]]
53
+ end
54
+ module_function :next_line
55
+ private_class_method :next_line
56
+ end # StringsHelper
57
+ end # Option
58
+ end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  module Option
5
- VERSION = "0.0.0"
6
- end
7
- end
5
+ VERSION = "0.1.0"
6
+ end # Option
7
+ end # TTY
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-option
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-23 00:00:00.000000000 Z
11
+ date: 2020-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.0'
41
- description: Parser for command line arguments, keywords, options and environment
41
+ description: Parser for command line arguments, keywords, flags, options and environment
42
42
  variables.
43
43
  email:
44
44
  - piotr@piotrmurach.com
@@ -54,7 +54,41 @@ files:
54
54
  - README.md
55
55
  - lib/tty-option.rb
56
56
  - lib/tty/option.rb
57
+ - lib/tty/option/aggregate_errors.rb
58
+ - lib/tty/option/conversions.rb
59
+ - lib/tty/option/converter.rb
60
+ - lib/tty/option/deep_dup.rb
61
+ - lib/tty/option/dsl.rb
62
+ - lib/tty/option/dsl/arity.rb
63
+ - lib/tty/option/dsl/conversion.rb
64
+ - lib/tty/option/error_aggregator.rb
65
+ - lib/tty/option/errors.rb
66
+ - lib/tty/option/formatter.rb
67
+ - lib/tty/option/inflection.rb
68
+ - lib/tty/option/param_conversion.rb
69
+ - lib/tty/option/param_permitted.rb
70
+ - lib/tty/option/param_validation.rb
71
+ - lib/tty/option/parameter.rb
72
+ - lib/tty/option/parameter/argument.rb
73
+ - lib/tty/option/parameter/environment.rb
74
+ - lib/tty/option/parameter/keyword.rb
75
+ - lib/tty/option/parameter/option.rb
76
+ - lib/tty/option/parameters.rb
77
+ - lib/tty/option/params.rb
57
78
  - lib/tty/option/parser.rb
79
+ - lib/tty/option/parser/arguments.rb
80
+ - lib/tty/option/parser/arity_check.rb
81
+ - lib/tty/option/parser/environments.rb
82
+ - lib/tty/option/parser/keywords.rb
83
+ - lib/tty/option/parser/options.rb
84
+ - lib/tty/option/parser/param_types.rb
85
+ - lib/tty/option/parser/required_check.rb
86
+ - lib/tty/option/pipeline.rb
87
+ - lib/tty/option/result.rb
88
+ - lib/tty/option/section.rb
89
+ - lib/tty/option/sections.rb
90
+ - lib/tty/option/usage.rb
91
+ - lib/tty/option/usage_wrapper.rb
58
92
  - lib/tty/option/version.rb
59
93
  homepage: https://ttytoolkit.org
60
94
  licenses: