cli-modular_options 0.0.0 → 0.0.2

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: 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