rake-toolkit_program 0.1.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.
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright 2019 PayTrace, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # This file defines utility extensions to standard library modules.
19
+
20
+ module Rake
21
+ module ToolkitProgram
22
+ module RangeConversion
23
+ ##
24
+ # Return a Range the includes the end
25
+ #
26
+ # This method will error if the subject Range excludes the end but
27
+ # the bounds are not Integers.
28
+ #
29
+ def to_inclusive
30
+ return self unless exclude_end?
31
+ raise "only Integer Ranges can be converted" if [self.begin, self.end].any? {|v| !(Integer === v)}
32
+ return (self.begin..(self.end - 1))
33
+ end
34
+ end
35
+ Range.include RangeConversion
36
+ end
37
+
38
+ module ToolkitProgram::ShellwordsExt
39
+ def split(s, drop_comment: false)
40
+ super(s).tap do |r|
41
+ break r[0..((r.index {|i| i.start_with?('#')} || 0) - 1)] if drop_comment
42
+ end
43
+ end
44
+ class <<Shellwords
45
+ prepend ToolkitProgram::ShellwordsExt
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,10 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # This file contains no information protectable under copyright laws
5
+
6
+ module Rake
7
+ module ToolkitProgram
8
+ VERSION = "0.1.1"
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright 2019 PayTrace, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # This is the gemspec file for the rake-toolkit_program gem.
19
+
20
+ require 'pathname'
21
+ lib = File.expand_path('../lib', __FILE__)
22
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
23
+ require 'rake/toolkit_program/version'
24
+
25
+ Gem::Specification.new do |spec|
26
+ spec.name = "rake-toolkit_program"
27
+ spec.version = Rake::ToolkitProgram::VERSION
28
+ spec.authors = ["Richard Weeks"]
29
+ spec.email = ["rtweeks21@gmail.com"]
30
+ spec.license = 'Apache-2.0'
31
+
32
+ spec.summary = %q{Build powerful CLI toolkits with simple code}
33
+ spec.description = (Pathname(__FILE__).dirname / "README.md").read()
34
+ spec.homepage = "https://github.com/PayTrace/rake-toolkit_program"
35
+
36
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
37
+ f.match(%r{^(test|spec|features)/})
38
+ end
39
+ spec.bindir = "exe"
40
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
41
+ spec.require_paths = ["lib"]
42
+
43
+ spec.add_dependency "rake", ">= 10.0"
44
+ spec.add_dependency "colorize", "~> 0.8"
45
+ spec.add_dependency "dedent", "~> 1.0"
46
+
47
+ spec.add_development_dependency "bundler", ['>= 1.13', '< 3']
48
+ spec.add_development_dependency "rspec", "~> 3.9"
49
+ spec.add_development_dependency "pry"
50
+ spec.add_development_dependency "pry-coolline"
51
+ end
metadata ADDED
@@ -0,0 +1,271 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-toolkit_program
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Richard Weeks
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-12-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dedent
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '1.13'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '3'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '1.13'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '3'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.9'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.9'
89
+ - !ruby/object:Gem::Dependency
90
+ name: pry
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: pry-coolline
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: "# Rake::ToolkitProgram\n\nCreate toolkit programs easily with `Rake`
118
+ and `OptionParser` syntax. Bash completions and usage help are baked in.\n\n##
119
+ Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'rake-toolkit_program'\n```\n\nAnd
120
+ then execute:\n\n $ bundle\n\nOr install it yourself as:\n\n $ gem install
121
+ rake-toolkit_program\n\n## Quickstart\n\n* Shebang it up (in a file named `awesome_tool.rb`)\n
122
+ \ ```ruby\n #!/usr/bin/env ruby\n ```\n* Require the library\n ```ruby\n require
123
+ 'rake/toolkit_program'\n ```\n* Make your life easier\n ```ruby\n Program = Rake::ToolkitProgram\n
124
+ \ ```\n* Define your command tasks\n ```ruby\n Program.command_tasks do\n desc
125
+ \"Build it\"\n task 'build' do\n # Ruby code here\n end\n \n desc
126
+ \"Test it\"\n task 'test' => ['build'] do\n # Rake syntax ↑↑↑↑↑↑↑ for dependencies\n
127
+ \ # Ruby code here\n end\n end\n ```\n You can use `Program.args` in your
128
+ tasks to access the other arguments on the command line. For argument parsing integrated
129
+ into the help provided by the program, see the use of `Rake::Task(Rake::ToolkitProgram::TaskExt)#parse_args`
130
+ below.\n* Wire the mainline\n ```ruby\n Program.run(on_error: :exit_program!)
131
+ if $0 == __FILE__\n ```\n* In the shell, prepare to run the program (UNIX/Linux
132
+ systems only)\n ```console\n $ chmod +x awesome_tool.rb\n $ ./awesome_tool.rb
133
+ --install-completions\n Completions installed in /home/rtweeks/.bashrc\n Source
134
+ /home/rtweeks/.bash-complete/awesome_tool.rb-completions for immediate availability.\n
135
+ \ $ source /home/rtweeks/.bash-complete/awesome_tool.rb-completions\n ```\n* Ask
136
+ for help\n ```console\n $ ./awesome_tool.rb help\n \n *** ./awesome_tool.rb
137
+ Toolkit Program ***\n \n .\n .\n .\n ```\n\n## Usage\n\nLet's look
138
+ at a short sample toolkit program -- put this in `awesome.rb`:\n\n```ruby\n#!/usr/bin/env
139
+ ruby\nrequire 'rake/toolkit_program'\nrequire 'ostruct'\n\nToolkitProgram = Rake::ToolkitProgram\nToolkitProgram.title
140
+ = \"My Awesome Toolkit of Awesome\"\n\nToolkitProgram.command_tasks do\n desc <<-END_DESC.dedent\n
141
+ \ Fooing myself\n \n I'm not sure what I'm doing, but I'm definitely fooing!\n
142
+ \ END_DESC\n task :foo do\n a = ToolkitProgram.args\n puts \"I'm fooed#{'
143
+ on a ' if a.implement}#{a.implement}\"\n end.parse_args(into: OpenStruct.new) do
144
+ |parser, args|\n parser.no_positional_args!\n parser.on('-i', '--implement
145
+ IMPLEMENT', 'An implement on which to be fooed') do |val|\n args.implement
146
+ = val\n end\n end\nend\n\nif __FILE__ == $0\n ToolkitProgram.run(on_error:
147
+ :exit_program!)\nend\n```\n\nMake sure to `chmod +x awesome.rb`!\n\nWhat does this
148
+ support?\n\n $ ./awesome.rb foo\n I'm fooed\n $ ./awesome.rb --help\n \n
149
+ \ *** My Awesome Toolkit of Awesome ***\n\n Usage: ./awesome.rb COMMAND [OPTION
150
+ ...]\n\n Avaliable options vary depending on the command given. For details\n
151
+ \ of a particular command, use:\n\n ./awesome.rb help COMMAND\n\n Commands:\n
152
+ \ foo Fooing myself\n help Show a list of commands or details
153
+ of one command\n\n Use help COMMAND to get more help on a specific command.\n
154
+ \ \n $ ./awesome.rb help foo\n \n *** My Awesome Toolkit of Awesome ***\n\n
155
+ \ Usage: ./awesome.rb foo [OPTION ...]\n\n Fooing myself\n\n I'm not sure
156
+ what I'm doing, but I'm definitely fooing!\n\n Options:\n -i, --implement
157
+ IMPLEMENT An implement on which to be fooed\n \n $ ./awesome.rb --install-completions\n
158
+ \ Completions installed in /home/rtweeks/.bashrc\n Source /home/rtweeks/.bash-complete/awesome.rb-completions
159
+ for immediate availability.\n $ source /home/rtweeks/.bash-complete/awesome.rb-completions\n
160
+ \ $ ./awesome.rb <tab><tab>\n foo help\n $ ./awesome.rb f<tab>\n ↳
161
+ ./awesome.rb foo\n $ ./awesome.rb foo <tab>\n ↳ ./awesome.rb foo --\n $
162
+ ./awesome.rb foo --<tab><tab>\n --help --implement\n $ ./awesome.rb
163
+ foo --i<tab>\n ↳ ./awesome.rb foo --implement\n $ ./awesome.rb foo --implement
164
+ <tab><tab>\n --help awesome.rb\n $ ./awesome.rb foo --implement spoon\n
165
+ \ I'm fooed on a spoon\n\n### Defining Toolkit Commands\n\nJust define tasks in
166
+ the block of `Rake::ToolkitProgram.command_tasks` with `task` (i.e. `Rake::DSL#task`).
167
+ \ If `desc` is used to provide a description, the task will become visible in help
168
+ and completions.\n\nWhen a command task is initially defined, positional arguments
169
+ to the command are available as an `Array` through `Rake::ToolkitProgram.args`.\n\n###
170
+ Option Parsing\n\nThis gem extends `Rake::Task` with a `#parse_args` method that
171
+ creates a `Rake::ToolkitProgram::CommandOptionParser` (derived from the standard
172
+ library's `OptionParser`) and an argument accumulator and `yield`s them to its block.\n*
173
+ The arguments accumulated through the `Rake::ToolkitProgram::CommandOptionParser`
174
+ are available to the task in `Rake::ToolkitProgram.args`, replacing the normal `Array`
175
+ of positional arguments.\n* Use the `into:` keyword of `#parse_args` to provide
176
+ a custom argument accumulator object for the associated command. The default argument
177
+ accumulator constructor can be defined with `Rake::ToolkitProgram.default_parsed_args`.
178
+ \ Without either of these, the default accumulator is a `Hash`.\n* Options defined
179
+ using `OptionParser#on` (or any of the variants) will print in the help for the
180
+ associated command.\n\n### Positional Arguments\n\nAccessing positional arguments
181
+ given after the command name depends on whether or not `Rake::Task(Rake::ToolkitProgram::TaskExt)#parse_args`
182
+ has been called on the command task. If this method is not called, positional arguments
183
+ will be an `Array` accessible through `Rake::ToolkitProgram.args`.\n\nWhen `Rake::Task(Rake::ToolkitProgram::TaskExt)#parse_args`
184
+ is used:\n* `Rake::ToolkitProgram::CommandOptionParser#capture_positionals` can
185
+ be used to define how positional arguments are accumulated.\n * If the argument
186
+ accumulator is a `Hash`, the default (without calling this method) is to assign
187
+ the `Array` of positional arguments to the `nil` key of the `Hash`.\n * For other
188
+ types of accumulators, the positional arguments are only accessible if `Rake::ToolkitProgram::CommandOptionParser#capture_positionals`
189
+ is used to define how they are captured.\n * If a block is given to this method,
190
+ the block of the method will receive the `Array` of positional arguments. If it
191
+ is passed an argument value, that value is used as the key under which to store
192
+ the positional arguments if the argument accumulator is a `Hash`.\n* `Rake::ToolkitProgram::CommandOptionParser#expect_positional_cardinality`
193
+ can be used to set a rule for the count of positional arguments. This will affect
194
+ the _usage_ presented in the help for the associated command.\n* `Rake::ToolkitProgram::CommandOptionParser#map_positional_args`
195
+ may be used to transform (or otherwise process) positional arguments one at a time
196
+ and in the context of options and/or arguments appearing earlier on the command
197
+ line.\n\n### Convenience Methods\n\n* `Rake::Task(Rake::ToolkitProgram::TaskExt)#prohibit_args`
198
+ is a quick way, for commands that accept no options or positional arguments, to
199
+ declare this so the help and bash completions reflect this. It is equivalent to
200
+ using `#parse_args` and telling the parser `parser.expect_positional_cardinality(0)`.\n\n*
201
+ `Rake::ToolkitProgram::CommandOptionParser#no_positional_args!` is a shortcut for
202
+ calling `#expect_positional_cardinality(0)` on the same object.\n\n* `Rake::Task(Rake::ToolkitProgram::TaskExt)#invalid_args!`
203
+ and `Rake::ToolkitProgram::CommandOptionParser#invalid_args!` are convenient ways
204
+ to raise `Rake::ToolkitProgram::InvalidCommandLine` with a message.\n\n## OptionParser
205
+ in Rubies Before and After v2.4\n\nThe `OptionParser` class was extended in Ruby
206
+ 2.4 to simplify capturing options into a `Hash` or other container implementing
207
+ `#[]=` in a similar way. This gem supports that, but it means that behavior varies
208
+ somewhat between the pre-2.4 era and the 2.4+ era. To have consistent behavior
209
+ across that version change, the recommendation is to use a `Struct`, `OpenStruct`,
210
+ or custom class to hold program options rather than `Hash`.\n\n## Development\n\nAfter
211
+ checking out the repo, run `bin/setup` to install dependencies. You can also run
212
+ `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo
213
+ install this gem onto your local machine, run `bundle exec rake install`. To release
214
+ a new version, update the version number in `version.rb`, and then run `bundle exec
215
+ rake release`, which will create a git tag for the version, push git commits and
216
+ tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\nTo run
217
+ the tests, use `rake`, `rake test`, or `rspec spec`. Tests can only be run on systems
218
+ that support `Kernel#fork`, as this is used to present a pristine and isolated environment
219
+ for setting up the tool. If run using Ruby 2.3 or earlier, some tests will be pending
220
+ because functionality expects Ruby 2.4's `OptionParser`.\n\n## Contributing\n\nBug
221
+ reports and pull requests are welcome on GitHub at https://github.com/PayTrace/rake-toolkit_program.
222
+ \ For further details on contributing, see [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n"
223
+ email:
224
+ - rtweeks21@gmail.com
225
+ executables: []
226
+ extensions: []
227
+ extra_rdoc_files: []
228
+ files:
229
+ - ".gitignore"
230
+ - CONTRIBUTING.md
231
+ - Gemfile
232
+ - LICENSE
233
+ - README.md
234
+ - Rakefile
235
+ - bin/console
236
+ - bin/setup
237
+ - lib/program_exit_from_error.rb
238
+ - lib/rake/toolkit_program.rb
239
+ - lib/rake/toolkit_program/command_option_parser.rb
240
+ - lib/rake/toolkit_program/completion.rb
241
+ - lib/rake/toolkit_program/errors.rb
242
+ - lib/rake/toolkit_program/help.rb
243
+ - lib/rake/toolkit_program/help_styling.rb
244
+ - lib/rake/toolkit_program/task_ext.rb
245
+ - lib/rake/toolkit_program/utils.rb
246
+ - lib/rake/toolkit_program/version.rb
247
+ - rake-toolkit_program.gemspec
248
+ homepage: https://github.com/PayTrace/rake-toolkit_program
249
+ licenses:
250
+ - Apache-2.0
251
+ metadata: {}
252
+ post_install_message:
253
+ rdoc_options: []
254
+ require_paths:
255
+ - lib
256
+ required_ruby_version: !ruby/object:Gem::Requirement
257
+ requirements:
258
+ - - ">="
259
+ - !ruby/object:Gem::Version
260
+ version: '0'
261
+ required_rubygems_version: !ruby/object:Gem::Requirement
262
+ requirements:
263
+ - - ">="
264
+ - !ruby/object:Gem::Version
265
+ version: '0'
266
+ requirements: []
267
+ rubygems_version: 3.0.3
268
+ signing_key:
269
+ specification_version: 4
270
+ summary: Build powerful CLI toolkits with simple code
271
+ test_files: []