cli-modular_options 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b7e5cd4033fe5f65cc4058d851f2b37ecac55bf
4
- data.tar.gz: 76f08750cf87f2ffa3834bfc9b09639a6783780b
3
+ metadata.gz: 9fdfcca3fd228a169b7669cd3d1d8a9986666ee8
4
+ data.tar.gz: 6341000ce95609c8645400b39f811bba59dad387
5
5
  SHA512:
6
- metadata.gz: 79a6af03599049f0210d6156facac70150d4c07b77354795ae12c868e2e4680afb9a436abb49dc4ea00a0bac45ca62620b910a58959556202ab75114fda4cb11
7
- data.tar.gz: d05bfefea65b7bed219f580b6deaee53dd667fd1ddb6ca284eda58ba2233150fedb279d5565b22cd809e9320cd72eebc07adbae146d9166242c77ae88aa5ee1f
6
+ metadata.gz: fad47704255b557d790e4aef075f016f95dfc7f95c9eeaafff5337c397b10ffa174f55ae30a1123698686a20a82dfb755a298de5772e817459e26e38739c0287
7
+ data.tar.gz: 8ef35d3e81a23410240e673b4215d623b51155036b942b979d8b9090b23b3b94b4cfe3546ff6114a3fca98fe81442d4749184db795d4760dc8874ef35d733a7d
data/README.md CHANGED
@@ -6,7 +6,6 @@ options in the context of a class or module and consume them in the context of
6
6
  an object instance using conventional ruby inheritance semantics.
7
7
 
8
8
  ### Install:
9
-
10
9
  gem install cli-modular_options
11
10
 
12
11
  ### Example:
@@ -19,11 +18,11 @@ module DatabaseStuff
19
18
  # Your mixin methods might go here
20
19
 
21
20
  cli_options do |parser|
22
- p.separator 'Database Options:'
23
- p.on '--db-user', 'Database username' do |v|
21
+ parser.separator 'Database Options:'
22
+ parser.on '--db-user', 'Database username' do |v|
24
23
  cli_opts[:db_user] = v
25
24
  end
26
- p.on '--db-pass', 'Database password' do |v|
25
+ parser.on '--db-pass', 'Database password' do |v|
27
26
  cli_opts[:db_pass] = v
28
27
  end
29
28
  end
@@ -32,7 +31,7 @@ end
32
31
  module StandardOptions
33
32
  extend CLI::WithOptions
34
33
  cli_options do |parser|
35
- p.on_head '-h', '--help', 'Display help' do
34
+ parser.on_head '-h', '--help', 'Display help' do
36
35
  cli_opts[:show_help] = true
37
36
  cli_opts[:parser] = parser
38
37
  end
@@ -44,14 +43,17 @@ class MyApp
44
43
  include DatabaseStuff
45
44
  include StandardOptions
46
45
 
46
+ def cli_opts
47
+ @cli_opts ||= Hash.new
48
+ end
49
+
47
50
  def show_help
48
51
  puts cli_opts[:parser]
49
52
  Process.exit 0
50
53
  end
51
54
 
52
55
  def initialize( argv = ARGV.map(&:dup) )
53
- parse_options! argv
54
- # Your options are available in cli_opts
56
+ cli_opts[:positional] = new_cli_parser.parse! argv
55
57
  show_help if cli_opts[:show_help]
56
58
  end
57
59
  end
@@ -89,6 +91,9 @@ class MyQuietApp < MyVerboseApp
89
91
  end
90
92
  ```
91
93
 
94
+ ### Development:
95
+ https://github.com/IronSavior/cli-modular_options
96
+
92
97
  ### Copyrights
93
98
  Copyright (C) 2014 Erik Elmore <erik@erikelmore.com>
94
99
 
@@ -2,43 +2,59 @@ require 'optparse'
2
2
 
3
3
  module CLI
4
4
 
5
+ # Use 'extend CLI::WithOptions' to declare OptionParser configuration blocks in your module.
5
6
  module WithOptions
7
+ # Used to declare a proc that can be used to configure an instance of OptionParser with a
8
+ # class or module.
6
9
  def cli_options( &block )
7
10
  raise ArgumentError, 'Block required but not given' unless block_given?
8
- const_set :CLI_OPTS_HOOKS, Array.new unless const_defined? :CLI_OPTS_HOOKS, false
9
- const_get(:CLI_OPTS_HOOKS) << block
11
+ (@cli_options_hooks ||= Array.new) << block
10
12
  end
11
13
  end # WithOptions
12
14
 
15
+ # Use 'include CLI::ModularOptions' in a class whose instances will consume procs declared
16
+ # using CLI::WithOptions#cli_options to configure instances of OptionParser.
13
17
  module ModularOptions
14
- def cli_opts
15
- @cli_opts ||= Hash.new
16
- end
17
-
18
- def new_options_parser
18
+ # Constructs a new instance of OptionParser and configures it using the cli_options blocks
19
+ # declared in modules found in the inheritance chain of a class or module. If a class or
20
+ # module is not specified, the class of self is assumed.
21
+ #
22
+ # @param mod [Class, Module] Optional, take cli_options from a different class
23
+ # @return [OptionParser] configured parser instance
24
+ def new_cli_parser( mod = self.class )
19
25
  OptionParser.new do |p|
20
- self.class.cli_hooks.each{ |b| instance_exec p, cli_opts, &b }
26
+ configure_cli_parser p, CLI::ModularOptions.ancestral_hooks(mod)
21
27
  end
22
28
  end
23
29
 
24
- def parse_options!( argv )
25
- cli_opts[:positional] = new_options_parser.parse! argv
30
+ # Configures a given parser by passing it to the given hook procs, which are called in the
31
+ # context of self
32
+ #
33
+ # @param parser [OptionParser] the parser to be configured
34
+ # @param hooks [Array<Proc>] parser configuration procs declared with cli_options
35
+ def configure_cli_parser( parser, hooks )
36
+ hooks.each do |b|
37
+ instance_exec parser, &b
38
+ end
26
39
  end
27
40
 
28
- def self.included( base )
29
- base.extend ClassMethods
30
- super
41
+ # Get parser configuration procs belonging to the specified modules. Inheritance is not considered.
42
+ #
43
+ # @param modules list of classes and modules that may or may not have cli_options procs
44
+ # @return [Array<Proc>] all cli_options procs belonging to specified modules
45
+ def self.hooks_from( *modules )
46
+ modules.map{ |m|
47
+ m.instance_variable_get :@cli_options_hooks if m.instance_variable_defined? :@cli_options_hooks
48
+ }.flatten.compact
31
49
  end
32
50
 
33
- module ClassMethods
34
- def ancestors_with_cli_hooks
35
- ancestors.select{ |m| m.const_defined? :CLI_OPTS_HOOKS, false }
36
- end
37
-
38
- def cli_hooks
39
- ancestors_with_cli_hooks.map{ |m| m::CLI_OPTS_HOOKS }.reverse.flatten
40
- end
41
- end # ClassMethods
51
+ # Get parser configuration procs belonging to or inherited by the specified class or module.
52
+ #
53
+ # @param mod [Class, Module]
54
+ # @return [Array<Proc>]
55
+ def self.ancestral_hooks( mod )
56
+ hooks_from(*mod.ancestors.uniq.reverse)
57
+ end
42
58
  end # ModularOptions
43
59
 
44
60
  end # CLI
@@ -4,7 +4,7 @@ module TestModel
4
4
  def self.new_cli_hook( mod, name )
5
5
  k = name.to_s.downcase.to_sym
6
6
  mod.instance_eval do
7
- cli_options do |p, cfg|
7
+ cli_options do |p|
8
8
  cfg[:context] << self.class
9
9
  cfg[:call_order] << name.to_s
10
10
  cfg[k] = false
@@ -38,10 +38,19 @@ module TestModel
38
38
  Class.new args[:base] {
39
39
  if args[:modular_options]
40
40
  include CLI::ModularOptions
41
+
42
+ define_method :inherit_options_from do
43
+ args[:inherit_options_from] || self.class
44
+ end
45
+
46
+ def cfg
47
+ @cfg ||= Hash.new
48
+ end
49
+
41
50
  def initialize( argv = [] )
42
- cli_opts[:context] = Array.new
43
- cli_opts[:call_order] = Array.new
44
- parse_options! argv
51
+ cfg[:context] = Array.new
52
+ cfg[:call_order] = Array.new
53
+ cfg[:positional] = new_cli_parser(inherit_options_from).parse! argv
45
54
  end
46
55
  end
47
56
 
@@ -3,16 +3,12 @@ require 'helpers/test_model'
3
3
 
4
4
  describe CLI::ModularOptions do
5
5
  shared_examples_for TestModel do
6
- it 'Inherits included cli_hooks' do
7
- expect(klass.cli_hooks.size).to be call_order.size
8
- end
9
-
10
6
  it 'Invokes cli_hooks in the context of self' do
11
- expect(klass.new.cli_opts[:context]).to all be(klass)
7
+ expect(klass.new.cfg[:context]).to all be(klass)
12
8
  end
13
9
 
14
10
  it 'Invokes cli_hooks in the correct order' do
15
- expect(klass.new.cli_opts[:call_order]).to eq call_order
11
+ expect(klass.new.cfg[:call_order]).to eq call_order
16
12
  end
17
13
  end
18
14
 
@@ -244,5 +240,15 @@ describe CLI::ModularOptions do
244
240
  ]}
245
241
  it_behaves_like TestModel
246
242
  end
243
+
244
+ context 'When using options from non-ancestor modules' do
245
+ let(:klass){ TestModel.new_class(
246
+ :modular_options => true,
247
+ :inherit_options_from => TestModel.new_module(:name => 'Other'),
248
+ :feature_modules => ['One', 'Two', 'Three']
249
+ )}
250
+ let(:call_order){ ['Other'] }
251
+ it_behaves_like TestModel
252
+ end
247
253
 
248
254
  end
@@ -4,8 +4,8 @@ require 'helpers/test_model'
4
4
  describe CLI::WithOptions do
5
5
  let(:mod){ TestModel.new_module :add_options => false }
6
6
 
7
- it "Doesn't create CLI_OPTS_HOOKS until necessary" do
8
- expect(mod.const_defined? :CLI_OPTS_HOOKS).to eq false
7
+ it "Doesn't create @cli_options_hooks until necessary" do
8
+ expect(mod.instance_variable_defined? :@cli_options_hooks).to eq false
9
9
  end
10
10
 
11
11
  it 'Requires a block to be given with cli_options' do
@@ -14,11 +14,11 @@ describe CLI::WithOptions do
14
14
 
15
15
  it 'Adds hooks to modules' do
16
16
  mod.cli_options do; end
17
- expect(mod::CLI_OPTS_HOOKS).to be_an Array
17
+ expect(mod.instance_variable_get :@cli_options_hooks).to be_an Array
18
18
  end
19
19
 
20
20
  it 'Adds more hooks to modules' do
21
21
  5.times{ mod.cli_options do; end }
22
- expect(mod::CLI_OPTS_HOOKS.size).to be 5
22
+ expect(mod.instance_variable_get(:@cli_options_hooks).size).to be 5
23
23
  end
24
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli-modular_options
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Elmore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-13 00:00:00.000000000 Z
11
+ date: 2014-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -39,7 +39,7 @@ files:
39
39
  - spec/modular_options_spec.rb
40
40
  - spec/spec_helper.rb
41
41
  - spec/with_options_spec.rb
42
- homepage: https://github.com/IronSavior/ModularOptions
42
+ homepage: https://github.com/IronSavior/cli-modular_options
43
43
  licenses:
44
44
  - MIT
45
45
  metadata: {}
@@ -64,7 +64,7 @@ signing_key:
64
64
  specification_version: 4
65
65
  summary: Modular Command-Line Options
66
66
  test_files:
67
- - spec/spec_helper.rb
68
- - spec/modular_options_spec.rb
69
67
  - spec/helpers/test_model.rb
68
+ - spec/modular_options_spec.rb
69
+ - spec/spec_helper.rb
70
70
  - spec/with_options_spec.rb