trollop-subcommands 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b8f7ab781f9a6f38900f202dffce96102c844c54
4
+ data.tar.gz: 168656bcc8e533b4d54168ae6491529da80732b7
5
+ SHA512:
6
+ metadata.gz: d0f69bbb24601c9041c87eb5afa0aa454d96b9a434291a46a9bcedfbb8bc7a0642e49c88b3e2ec716b37f0cdf992a2fbc0dffef1786e050ffb2a103797b0edc7
7
+ data.tar.gz: cd41090b636ab74e92c5a7d6dd74f7050e195d0e0a18e1e1cc65bf87b4d6674979a3e2b70c2a24912e18bb52bfd51d9a0278ae63b7bbccef93ebb5409ec2e09a
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1 @@
1
+ 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 jwliechty
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jason Liechty
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,125 @@
1
+ require 'trollop'
2
+ require 'trollop/subcommands/version'
3
+
4
+ module Trollop
5
+ module Subcommands
6
+
7
+ ## Register the options block for parsing the global options. If
8
+ ## not invoked, a default options block with a bare-bones usage
9
+ ## message will be used. No need to specify `stop_on` or
10
+ ## `stop_on_unknown` as that is done automatically at the time of
11
+ ## parsing.
12
+ def register_global(&trollop_block)
13
+ parser.register_global(&trollop_block)
14
+ end
15
+
16
+ ## Register the options block for a given subcommand. If the
17
+ ## subcommand does not need options, one should still be
18
+ ## provided specifying the banner. The banner displays when
19
+ ## the when the followng arguments are given:
20
+ ## my_script my_subcommand -h
21
+ def register_subcommand(command, &trollop_block)
22
+ parser.register_subcommand(command, &trollop_block)
23
+ end
24
+
25
+ ## Where the magic happens. Once all the subcommands and optionally
26
+ ## the global options are registered, invoke this method for the
27
+ ## command line parsing to begin. The result of this method
28
+ ## invocation is a struct containing the `global_options` (hash),
29
+ ## `subcommand` (string), and `subcommand_options` (hash).
30
+ def parse!(args=ARGV)
31
+ parser.parse!(args)
32
+ end
33
+
34
+ ## @private This is simply a helper method for the other publicly
35
+ ## exposed methods.
36
+ def parser
37
+ @parser ||= Parser.new
38
+ end
39
+
40
+ ## @private Used for the specs as arguments are parsed multiple
41
+ ## times in one process. For scripts, parsing usually occurs once.
42
+ def clear
43
+ @parser = nil
44
+ end
45
+
46
+ class Parser
47
+ def initialize
48
+ @subcommand_parsers_lookup = {}
49
+ end
50
+
51
+ def register_global(&trollop_block)
52
+ @global_parser = create_parser(&trollop_block)
53
+ end
54
+
55
+ def register_subcommand(command, &trollop_block)
56
+ @subcommand_parsers_lookup[command.to_s] = trollop_block
57
+ end
58
+
59
+ def parse!(args=ARGV)
60
+ @global_parser ||= default_global_parser
61
+ @global_parser.stop_on(subcommands)
62
+ @global_parser.stop_on_unknown
63
+ Trollop::with_standard_exception_handling(@global_parser) do
64
+ global_options = @global_parser.parse(args)
65
+ cmd = parse_subcommand(args)
66
+ cmd_options = parse_subcommand_options(args, cmd)
67
+ Result.new(global_options, cmd, cmd_options)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def default_global_parser
74
+ script_name = File.basename($0)
75
+ commands = @subcommand_parsers_lookup.keys.map(&:to_s)
76
+ create_parser do
77
+ banner <<-END
78
+ Usage
79
+ #{script_name} COMMAND [options]
80
+
81
+ COMMANDS
82
+ #{commands.join("\n ")}
83
+
84
+ Additional help
85
+ #{script_name} COMMAND -h
86
+
87
+ Options
88
+ END
89
+ end
90
+ end
91
+
92
+ def create_parser(&block)
93
+ ::Trollop::Parser.new(&block)
94
+ end
95
+
96
+ def subcommands
97
+ @subcommand_parsers_lookup.keys
98
+ end
99
+
100
+ def parse_subcommand(args)
101
+ cmd = args.shift
102
+ raise ::Trollop::CommandlineError.new('No subcommand provided') unless cmd
103
+ cmd
104
+ end
105
+
106
+ def parse_subcommand_options(args, cmd)
107
+ block = @subcommand_parsers_lookup[cmd]
108
+ raise ::Trollop::CommandlineError.new("Unknown subcommand '#{cmd}'") unless block
109
+ cmd_parser = ::Trollop::Parser.new(&block)
110
+ ::Trollop::with_standard_exception_handling(cmd_parser) do
111
+ begin
112
+ result = cmd_parser.parse(args)
113
+ rescue CommandlineError => e
114
+ raise CommandlineError.new("#{e.message} for command '#{cmd}'")
115
+ end
116
+ result
117
+ end
118
+ end
119
+
120
+ Result = Struct.new(:global_options, :subcommand, :subcommand_options)
121
+ end
122
+
123
+ module_function :register_global, :register_subcommand, :parse!, :parser, :clear
124
+ end
125
+ end
@@ -0,0 +1,5 @@
1
+ module Trollop
2
+ module Subcommands
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
@@ -0,0 +1,88 @@
1
+ # Trollop::Subcommands
2
+
3
+ This gem is an extension to [Trollop]. It provides a framework for commandline
4
+ scripts that use the following subcommand pattern
5
+
6
+ ```bash
7
+ my_script [global options] command [command options]
8
+ ```
9
+
10
+ ## Usage
11
+
12
+ The framework abstracts setting up the Trollop parser to the sub command pattern
13
+ displayed above. Just provide the Trollop options blocks for the global options
14
+ and subcommands and you are good to go!
15
+
16
+ ```ruby
17
+ #!/usr/bin/env ruby
18
+ require 'trollop/subcommands'
19
+
20
+ # do not specify in the Trollop block `stop_on` or `stop_on_unknown`
21
+ # as the subcommand framework will do that for you
22
+ Trollop::Subcommands::register_global do
23
+ banner <<-END
24
+ Usage
25
+ my_script [global options] COMMAND [command options]
26
+
27
+ COMMANDS
28
+ list List stuff
29
+ create Create stuff
30
+
31
+ Additional help
32
+ my_script COMMAND -h
33
+
34
+ Options
35
+ END
36
+ opt :some_global_option, 'Some global option', type: :string, short: :none
37
+ end
38
+
39
+ Trollop::Subcommands::register_subcommand('list') do
40
+ banner <<-END
41
+ Usage
42
+ #{File.basename($0)} list [options]
43
+
44
+ This is the list command...
45
+
46
+ Options
47
+ END
48
+ opt :all, 'All the things', type: :boolean
49
+ end
50
+
51
+ Trollop::Subcommands::register_subcommand('create') do
52
+ banner <<-END
53
+ Usage
54
+ #{File.basename($0)} create [options]
55
+
56
+ This is the create command...
57
+
58
+ Options
59
+ END
60
+ opt :partial, 'blah blah', type: :boolean
61
+ opt :name, 'blah blah', type: :string
62
+ end
63
+
64
+ result = Trollop::Subcommands::parse!
65
+
66
+
67
+ puts "Command was #{result.subcommand}"
68
+ puts "Global options were #{result.global_options}"
69
+ puts "Subcommand options were #{result.subcommand_options}"
70
+ ```
71
+
72
+ The here documents for the banners can distract the code a bit. It can help to
73
+ abstract them to methods.
74
+
75
+ See the scenarios covered by the [spec].
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on GitHub at
80
+ https://github.com/jwliechty/trollop-subcommands.
81
+
82
+ ## License
83
+
84
+ The gem is available as open source under the terms of the [MIT License]
85
+
86
+ [MIT License]: http://opensource.org/licenses/MIT
87
+ [spec]: spec/trollop/subcommands_spec.rb
88
+ [Trollop]: http://trollop.rubyforge.org/
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'trollop/subcommands/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'trollop-subcommands'
8
+ spec.version = Trollop::Subcommands::VERSION
9
+ spec.authors = ['Jason Liechty']
10
+ spec.email = ['jason.liechty@indigobio.com']
11
+
12
+ spec.summary = %q{Adds a subcommand framework to the Trollop command line parsing library.}
13
+ spec.description = %q{Though Trollop has the ability to support subcommands, I find myself
14
+ implementing the same logic repeatedly. The abstraction of this logic is
15
+ now in trollop-subcommands. This provides a framework for parsing
16
+ command line options for ruby scripts that have subcommands. The format
17
+ is 'script_name [global_options] subcommand [subcommand_options]'. The
18
+ framework supports all the typical scenarios around these type of
19
+ command line scripts. All that need to be specified are the trollop
20
+ configurations for the global options and each subcommand options. See
21
+ the readme for more information.}
22
+ spec.homepage = 'https://github.com/jwliechty/trollop-subcommands'
23
+ spec.license = 'MIT'
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ['lib']
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.10'
30
+ spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'rspec', '~> 3.3'
32
+
33
+ spec.add_dependency 'trollop', '~> 2.1'
34
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trollop-subcommands
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Liechty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: trollop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
69
+ description: |-
70
+ Though Trollop has the ability to support subcommands, I find myself
71
+ implementing the same logic repeatedly. The abstraction of this logic is
72
+ now in trollop-subcommands. This provides a framework for parsing
73
+ command line options for ruby scripts that have subcommands. The format
74
+ is 'script_name [global_options] subcommand [subcommand_options]'. The
75
+ framework supports all the typical scenarios around these type of
76
+ command line scripts. All that need to be specified are the trollop
77
+ configurations for the global options and each subcommand options. See
78
+ the readme for more information.
79
+ email:
80
+ - jason.liechty@indigobio.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - ".gitignore"
86
+ - ".rspec"
87
+ - ".ruby-version"
88
+ - Gemfile
89
+ - LICENSE
90
+ - LICENSE.txt
91
+ - Rakefile
92
+ - lib/trollop/subcommands.rb
93
+ - lib/trollop/subcommands/version.rb
94
+ - readme.md
95
+ - trollop-subcommands.gemspec
96
+ homepage: https://github.com/jwliechty/trollop-subcommands
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.4.5
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Adds a subcommand framework to the Trollop command line parsing library.
120
+ test_files: []