methadone 1.0.0.rc3 → 1.0.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
data/bin/methadone CHANGED
@@ -48,7 +48,7 @@ main do |app_name|
48
48
  " #{gem_variable}.add_development_dependency('rdoc')",
49
49
  " #{gem_variable}.add_development_dependency('aruba')",
50
50
  " #{gem_variable}.add_development_dependency('rake','~> 0.9.2')",
51
- " #{gem_variable}.add_dependency('methadone', '~>1.0.0.rc3')",
51
+ " #{gem_variable}.add_dependency('methadone', '~>1.0.0.rc4')",
52
52
  ], :before => /^end\s*$/
53
53
  end
54
54
 
@@ -69,6 +69,7 @@ arg :app_name, :required, "Name of your app, which is used for the gem name and
69
69
  version Methadone::VERSION
70
70
 
71
71
  defaults_from_env_var 'METHODONE_OPTS'
72
+ defaults_from_config_file '.methadone.rc'
72
73
 
73
74
  go!
74
75
 
@@ -1,4 +1,5 @@
1
1
  require 'optparse'
2
+ require 'yaml'
2
3
 
3
4
  begin
4
5
  Module.const_get('BasicObject')
@@ -117,8 +118,32 @@ module Methadone
117
118
  # options for your app. Omit this to disable the feature.
118
119
  def defaults_from_env_var(env_var)
119
120
  @env_var = env_var
120
- opts.separator ''
121
- opts.separator "Default values can be placed in the #{env_var} environment variable"
121
+ end
122
+
123
+ # Set the name of the file, in the user's home directory, where defaults can be configured.
124
+ # The format of this file can be either a simple string of options, like what goes
125
+ # in the environment variable (see #defaults_from_env_var), or YAML, in which case
126
+ # it should be a hash where keys are the option names, and values their defaults.
127
+ #
128
+ # filename:: name of the file, relative to the user's home directory
129
+ def defaults_from_config_file(filename,options={})
130
+ @rc_file = File.join(ENV['HOME'],filename)
131
+ end
132
+
133
+ def add_defaults_to_docs
134
+ if @env_var && @rc_file
135
+ opts.separator ''
136
+ opts.separator 'Default values can be placed in:'
137
+ opts.separator ''
138
+ opts.separator " #{@env_var} environment variable, as a String of options"
139
+ opts.separator " #{@rc_file} with contents either a String of options or a YAML-encoded Hash"
140
+ elsif @env_var
141
+ opts.separator ''
142
+ opts.separator "Default values can be placed in the #{@env_var} environment variable"
143
+ elsif @rc_file
144
+ opts.separator ''
145
+ opts.separator "Default values can be placed in #{@rc_file}"
146
+ end
122
147
  end
123
148
 
124
149
  # Start your command-line app, exiting appropriately when
@@ -135,6 +160,8 @@ module Methadone
135
160
  # 64 and a message about that missing argument.
136
161
  #
137
162
  def go!
163
+ add_defaults_to_docs
164
+ set_defaults_from_rc_file
138
165
  normalize_defaults
139
166
  opts.post_setup
140
167
  if @env_var
@@ -255,6 +282,26 @@ module Methadone
255
282
 
256
283
  private
257
284
 
285
+ def set_defaults_from_rc_file
286
+ if @rc_file && File.exists?(@rc_file)
287
+ File.open(@rc_file) do |file|
288
+ parsed = YAML::load(file)
289
+ if parsed.kind_of? String
290
+ String(parsed).split(/\s+/).each do |arg|
291
+ ::ARGV.unshift(arg)
292
+ end
293
+ elsif parsed.kind_of? Hash
294
+ parsed.each do |option,value|
295
+ options[option] = value
296
+ end
297
+ else
298
+ raise OptionParser::ParseError,
299
+ "rc file #{@rc_file} is not parseable, should be a string or YAML-encoded Hash"
300
+ end
301
+ end
302
+ end
303
+ end
304
+
258
305
  # Normalized all defaults to both string and symbol forms, so
259
306
  # the user can access them via either means just as they would for
260
307
  # non-defaulted options
@@ -1,3 +1,3 @@
1
1
  module Methadone
2
- VERSION = "1.0.0.rc3"
2
+ VERSION = "1.0.0.rc4"
3
3
  end
data/test/test_main.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'base_test'
2
2
  require 'methadone'
3
3
  require 'stringio'
4
+ require 'fileutils'
4
5
 
5
6
  class TestMain < BaseTest
6
7
  include Methadone::Main
@@ -12,6 +13,12 @@ class TestMain < BaseTest
12
13
  $stdout = StringIO.new
13
14
  @logged = StringIO.new
14
15
  @custom_logger = Logger.new(@logged)
16
+
17
+ @original_home = ENV['HOME']
18
+ fake_home = '/tmp/fake-home'
19
+ FileUtils.rm_rf(fake_home)
20
+ FileUtils.mkdir(fake_home)
21
+ ENV['HOME'] = fake_home
15
22
  end
16
23
 
17
24
  # Override the built-in logger so we can capture it
@@ -24,6 +31,7 @@ class TestMain < BaseTest
24
31
  ENV.delete('DEBUG')
25
32
  ENV.delete('APP_OPTS')
26
33
  $stdout = @old_stdout
34
+ ENV['HOME'] = @original_home
27
35
  end
28
36
 
29
37
  test_that "my main block gets called by run and has access to CLILogging" do
@@ -503,7 +511,8 @@ class TestMain < BaseTest
503
511
 
504
512
  test_that "when getting defaults from an environment variable, show it in the help output" do
505
513
  Given app_to_use_environment
506
- When {
514
+ When run_go_safely
515
+ And {
507
516
  @help_string = opts.to_s
508
517
  }
509
518
  Then {
@@ -547,8 +556,104 @@ class TestMain < BaseTest
547
556
  }
548
557
  end
549
558
 
559
+ test_that "we can get defaults from a config file if it's specified" do
560
+ Given app_to_use_rc_file
561
+ And {
562
+ @flag_value = any_string
563
+ rc_file = File.join(ENV['HOME'],'.my_app.rc')
564
+ File.open(rc_file,'w') do |file|
565
+ file.puts ({
566
+ 'switch' => true,
567
+ 'flag' => @flag_value,
568
+ }.to_yaml)
569
+ end
570
+ }
571
+ When {
572
+ @code = lambda { go! }
573
+ }
574
+ Then {
575
+ assert_exits(0,&@code)
576
+ @switch.should == true
577
+ @flag.should == @flag_value
578
+ }
579
+
580
+ end
581
+
582
+ test_that "we can specify an rc file even if it doesn't exist" do
583
+ Given app_to_use_rc_file
584
+ And {
585
+ @flag_value = any_string
586
+ rc_file = File.join(ENV['HOME'],'.my_app.rc')
587
+ raise "Something's wrong, expection rc file not to exist" if File.exists?(rc_file)
588
+ }
589
+ When {
590
+ @code = lambda { go! }
591
+ }
592
+ Then {
593
+ assert_exits(0,&@code)
594
+ @switch.should == nil
595
+ @flag.should == nil
596
+ }
597
+ end
598
+
599
+ test_that "we can use a different format for the rc file" do
600
+ Given app_to_use_rc_file
601
+ And {
602
+ @flag_value = any_string
603
+ rc_file = File.join(ENV['HOME'],'.my_app.rc')
604
+ File.open(rc_file,'w') do |file|
605
+ file.puts "--switch --flag=#{@flag_value}"
606
+ end
607
+ }
608
+ When {
609
+ @code = lambda { go! }
610
+ }
611
+ Then {
612
+ assert_exits(0,&@code)
613
+ @switch.should == true
614
+ @flag.should == @flag_value
615
+ }
616
+
617
+ end
618
+
619
+ test_that "with an ill-formed rc file, we get a reasonable error message" do
620
+ Given app_to_use_rc_file
621
+ And {
622
+ @flag_value = any_string
623
+ rc_file = File.join(ENV['HOME'],'.my_app.rc')
624
+ File.open(rc_file,'w') do |file|
625
+ file.puts OpenStruct.new(:foo => :bar).to_yaml
626
+ end
627
+ }
628
+ When {
629
+ @code = lambda { go! }
630
+ }
631
+ Then {
632
+ assert_exits(64,&@code)
633
+ }
634
+
635
+ end
636
+
550
637
  private
551
638
 
639
+ def app_to_use_rc_file
640
+ lambda {
641
+ @switch = nil
642
+ @flag = nil
643
+ @args = nil
644
+ main do |*args|
645
+ @switch = options[:switch]
646
+ @flag = options[:flag]
647
+ @args = args
648
+ end
649
+
650
+ defaults_from_config_file '.my_app.rc'
651
+
652
+ on('--switch','Some Switch')
653
+ on('--flag FOO','Some Flag')
654
+ }
655
+ end
656
+
552
657
  def main_that_exits(exit_status)
553
658
  proc { main { exit_status } }
554
659
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: methadone
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc3
4
+ version: 1.0.0.rc4
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-19 00:00:00.000000000Z
12
+ date: 2012-02-21 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
- requirement: &70353456288360 !ruby/object:Gem::Requirement
16
+ requirement: &70117187014260 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70353456288360
24
+ version_requirements: *70117187014260
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-expectations
27
- requirement: &70353456287680 !ruby/object:Gem::Requirement
27
+ requirement: &70117187013540 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.6'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70353456287680
35
+ version_requirements: *70117187013540
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70353456287180 !ruby/object:Gem::Requirement
38
+ requirement: &70117187012900 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70353456287180
46
+ version_requirements: *70117187012900
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rdoc
49
- requirement: &70353456286640 !ruby/object:Gem::Requirement
49
+ requirement: &70117187012080 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.9'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70353456286640
57
+ version_requirements: *70117187012080
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: cucumber
60
- requirement: &70353456285980 !ruby/object:Gem::Requirement
60
+ requirement: &70117187011340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.1.1
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70353456285980
68
+ version_requirements: *70117187011340
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: aruba
71
- requirement: &70353456285520 !ruby/object:Gem::Requirement
71
+ requirement: &70117187010760 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70353456285520
79
+ version_requirements: *70117187010760
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov
82
- requirement: &70353456284800 !ruby/object:Gem::Requirement
82
+ requirement: &70117187010060 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0.5'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70353456284800
90
+ version_requirements: *70117187010060
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: clean_test
93
- requirement: &70353456284200 !ruby/object:Gem::Requirement
93
+ requirement: &70117187009160 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0.10'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70353456284200
101
+ version_requirements: *70117187009160
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: mocha
104
- requirement: &70353456283600 !ruby/object:Gem::Requirement
104
+ requirement: &70117187008340 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70353456283600
112
+ version_requirements: *70117187008340
113
113
  description: Methadone provides a lot of small but useful features for developing
114
114
  a command-line app, including an opinionated bootstrapping process, some helpful
115
115
  cucumber steps, and some classes to bridge logging and output into a simple, unified,