configliere 0.4.10 → 0.4.11

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.10
1
+ 0.4.11
data/configliere.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "configliere"
8
- s.version = "0.4.10"
8
+ s.version = "0.4.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["infochimps", "mrflip"]
12
- s.date = "2012-06-30"
12
+ s.date = "2012-08-07"
13
13
  s.description = " You've got a script. It's got some settings. Some settings are for this module, some are for that module. Most of them don't change. Except on your laptop, where the paths are different. Or when you're in production mode. Or when you're testing from the command line.\n\n \"\" So, Consigliere of mine, I think you should tell your Don what everyone knows. \"\" -- Don Corleone\n\nConfigliere manage settings from many sources: static constants, simple config files, environment variables, commandline options, straight ruby. You don't have to predefine anything, but you can ask configliere to type-convert, require, document or password-obscure any of its fields. Modules can define config settings independently of each other and the main program.\n"
14
14
  s.email = "coders@infochimps.org"
15
15
  s.extra_rdoc_files = [
@@ -56,6 +56,7 @@ Gem::Specification.new do |s|
56
56
  "lib/configliere/env_var.rb",
57
57
  "lib/configliere/param.rb",
58
58
  "lib/configliere/prompt.rb",
59
+ "lib/configliere/vayacondios.rb",
59
60
  "spec/configliere/commandline_spec.rb",
60
61
  "spec/configliere/commands_spec.rb",
61
62
  "spec/configliere/config_block_spec.rb",
@@ -74,7 +75,7 @@ Gem::Specification.new do |s|
74
75
  s.homepage = "http://infochimps.com/tools"
75
76
  s.licenses = ["Apache"]
76
77
  s.require_paths = ["lib"]
77
- s.rubygems_version = "1.8.11"
78
+ s.rubygems_version = "1.8.15"
78
79
  s.summary = "Wise, discreet configuration management"
79
80
 
80
81
  if s.respond_to? :specification_version then
data/examples/joke.rb CHANGED
@@ -14,7 +14,7 @@ Settings.define_command :a2, :description => "The second joke (answer -- PG-13,
14
14
  end
15
15
  Settings.define_command :a3, :description => "The third joke (answer -- R, strong language)" do |cmd|
16
16
  cmd.define :age_limit, :type => Integer, :default => 17, :description => "minimum age to be able to enjoy joke 3"
17
- cmd.define :bleep, :type => :boolean, :default => false, :description => "if enabled, solecisms will be bowlerized"
17
+ cmd.define :bleep, :type => :boolean, :default => false, :description => "if enabled, solecisms will be bowdlerized"
18
18
  end
19
19
 
20
20
  Settings.define :debug, :type => :boolean, :default => false, :description => "show verbose progress", :internal => true
@@ -1,6 +1,10 @@
1
1
  module Configliere
2
- # Where to load params given a bare filename
3
- DEFAULT_CONFIG_DIR = ENV['HOME'].to_s+'/.configliere' unless defined?(DEFAULT_CONFIG_DIR)
2
+ # Default locations where config files live
3
+ DEFAULT_CONFIG_LOCATION = {
4
+ machine: ->(scope){ Pathname('/etc').join(scope) },
5
+ user: ->(scope){ Pathname(ENV['HOME'] || '/').join(".#{scope}") },
6
+ app: ->(scope){ app_dir = nil ; Pathname(Dir.pwd).ascend{ |path| app_dir = path.join('config') if path.join('config').exist? } ; app_dir }
7
+ } unless defined?(DEFAULT_CONFIG_LOCATION)
4
8
 
5
9
  #
6
10
  # ConfigFile -- load configuration from a simple YAML file
@@ -35,7 +39,7 @@ module Configliere
35
39
  when 'yaml' then read_yaml(File.open(filename), options)
36
40
  else read_yaml(File.open(filename), options)
37
41
  end
38
- rescue Errno::ENOENT => e
42
+ rescue Errno::ENOENT
39
43
  warn "Loading empty configliere settings file #{filename}"
40
44
  end
41
45
  self
@@ -76,6 +80,26 @@ module Configliere
76
80
  File.open(filename, 'w'){|f| f << YAML.dump(hsh) }
77
81
  end
78
82
 
83
+ def determine_conf_location(level, scope)
84
+ lookup_conf_dir(level, scope).join("#{scope}.yaml").to_s
85
+ end
86
+
87
+ def default_conf_dir
88
+ lookup_conf_dir(:user, 'configliere')
89
+ end
90
+
91
+ def lookup_conf_dir(level, scope)
92
+ Configliere::DEFAULT_CONFIG_LOCATION[level].call(scope)
93
+ end
94
+
95
+ def load_configuration_in_order!(scope = 'configliere')
96
+ [ :machine, :user, :app ].each do |level|
97
+ conf = determine_conf_location(level, scope)
98
+ read(conf) if Pathname(conf).exist?
99
+ end
100
+ resolve!
101
+ end
102
+
79
103
  protected
80
104
 
81
105
  def filetype filename
@@ -87,7 +111,7 @@ module Configliere
87
111
  if filename.to_s.include?('/')
88
112
  File.expand_path(filename)
89
113
  else
90
- File.expand_path(File.join(Configliere::DEFAULT_CONFIG_DIR, filename))
114
+ default_conf_dir.join(filename).to_s
91
115
  end
92
116
  end
93
117
  end
@@ -0,0 +1 @@
1
+ require 'vayacondios/configliere'
@@ -1,99 +1,98 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
+ require 'configliere/commands'
2
3
 
3
- describe "Configliere::Commands" do
4
- before do
5
- @config = Configliere::Param.new
6
- @config.use :commands
7
- end
4
+ describe Configliere::Commands do
5
+
6
+ subject{ Configliere::Param.new.use(:commands) }
8
7
 
9
- after do
10
- ::ARGV.replace []
11
- end
8
+ after{ ::ARGV.replace [] }
12
9
 
13
- describe "when no commands are defined" do
14
- it "should know that no commands are defined" do
15
- @config.commands.should be_empty
16
- end
10
+ context 'when no commands are defined' do
11
+
12
+ its(:commands){ should be_empty }
17
13
 
18
- it "should not shift the ARGV when resolving" do
19
- ::ARGV.replace ['not_command_but_arg', 'another_arg']
20
- @config.resolve!
21
- @config.rest.should == ['not_command_but_arg', 'another_arg']
22
- @config.command_name.should be_nil
23
- @config.command_info.should be_nil
14
+ let(:args) { %w[ not_command_but_arg another_arg ] }
15
+
16
+ it 'does not shift the ARGV when resolving' do
17
+ ::ARGV.replace args
18
+ subject.resolve!
19
+ subject.rest.should == args
20
+ subject.command_name.should be_nil
21
+ subject.command_info.should be_nil
24
22
  end
25
23
 
26
- it "should still recognize a git-style-binary command" do
27
- ::ARGV.replace ['not_command_but_arg', 'another_arg']
24
+ it 'still recognize a git-style-binary command' do
25
+ ::ARGV.replace args
28
26
  File.should_receive(:basename).and_return('prog-subcommand')
29
- @config.resolve!
30
- @config.rest.should == ['not_command_but_arg', 'another_arg']
31
- @config.command_name.should == :subcommand
32
- @config.command_info.should be_nil
27
+ subject.resolve!
28
+ subject.rest.should == args
29
+ subject.command_name.should == :subcommand
30
+ subject.command_info.should be_nil
33
31
  end
34
32
  end
35
33
 
36
- describe "a simple command" do
34
+ context 'a simple command' do
35
+ let(:args) { %w[ the_command --fuzziness=wuzzy extra_arg ] }
36
+
37
37
  before do
38
- @config.defaults :fuzziness => 'smooth'
39
- @config.define_command :the_command, :description => "foobar"
38
+ subject.defaults(fuzziness: 'smooth')
39
+ subject.define_command(:the_command, description: 'foobar')
40
40
  end
41
41
 
42
42
  it "should continue to parse flags when the command is given" do
43
- ::ARGV.replace ['the_command', '--fuzziness=wuzzy', 'an_arg']
44
- @config.resolve!
45
- @config.should == { :fuzziness => 'wuzzy' }
43
+ ::ARGV.replace args
44
+ subject.resolve!
45
+ subject.should == { fuzziness: 'wuzzy' }
46
46
  end
47
47
 
48
48
  it "should continue to set args when the command is given" do
49
- ::ARGV.replace ['the_command', '--fuzziness=wuzzy', 'an_arg']
50
- @config.resolve!
51
- @config.rest.should == ['an_arg']
49
+ ::ARGV.replace args
50
+ subject.resolve!
51
+ subject.rest.should == ['extra_arg']
52
52
  end
53
53
 
54
54
  it "should recognize the command when given" do
55
- ::ARGV.replace ['the_command', '--fuzziness=wuzzy', 'an_arg']
56
- @config.resolve!
57
- @config.command_name.should == :the_command
58
- @config.command_info.should == { :description => "foobar", :config => { :fuzziness => 'wuzzy' } }
55
+ ::ARGV.replace args
56
+ subject.resolve!
57
+ subject.command_name.should == :the_command
58
+ subject.command_info.should == { :description => "foobar", :config => { :fuzziness => 'wuzzy' } }
59
59
  end
60
60
 
61
61
  it "should recognize when the command is not given" do
62
62
  ::ARGV.replace ['bogus_command', '--fuzziness=wuzzy', 'an_arg']
63
- @config.resolve!
64
- @config.rest.should == ['bogus_command', 'an_arg']
65
- @config.command_name.should be_nil
63
+ subject.resolve!
64
+ subject.rest.should == ['bogus_command', 'an_arg']
65
+ subject.command_name.should be_nil
66
66
  end
67
67
  end
68
68
 
69
69
  describe "a complex command" do
70
70
  before do
71
- @config.defaults :outer => 'val 1'
72
- @config.define_command "the_command", :description => "the command" do |cmd|
71
+ subject.defaults :outer => 'val 1'
72
+ subject.define_command "the_command", :description => "the command" do |cmd|
73
73
  cmd.define :inner, :description => "inside"
74
74
  end
75
75
  end
76
76
 
77
77
  it "should still recognize the outer param and the args" do
78
78
  ::ARGV.replace ['the_command', '--outer=wuzzy', 'an_arg', '--inner=buzz']
79
- @config.resolve!
80
- @config.rest.should == ['an_arg']
81
- @config.command_name.should == :the_command
82
- @config[:outer].should == 'wuzzy'
79
+ subject.resolve!
80
+ subject.rest.should == ['an_arg']
81
+ subject.command_name.should == :the_command
82
+ subject[:outer].should == 'wuzzy'
83
83
  end
84
84
 
85
85
  it "should recognize the inner param" do
86
86
  ::ARGV.replace ['the_command', '--outer=wuzzy', 'an_arg', '--inner=buzz']
87
- @config.resolve!
88
- @config[:inner].should == 'buzz'
89
- @config.command_info[:config][:inner].should == 'buzz'
87
+ subject.resolve!
88
+ subject[:inner].should == 'buzz'
89
+ subject.command_info[:config][:inner].should == 'buzz'
90
90
  end
91
91
  end
92
92
 
93
-
94
93
  def capture_help_message
95
94
  stderr_output = ''
96
- @config.should_receive(:warn){|str| stderr_output << str }
95
+ subject.should_receive(:warn){|str| stderr_output << str }
97
96
  begin
98
97
  yield
99
98
  fail('should exit via system exit')
@@ -105,20 +104,20 @@ describe "Configliere::Commands" do
105
104
 
106
105
  describe "the help message" do
107
106
  before do
108
- @config.define_command :run, :description => "forrest"
109
- @config.define_command :stop, :description => "hammertime"
110
- @config.define :reel, :type => Integer
107
+ subject.define_command :run, :description => "forrest"
108
+ subject.define_command :stop, :description => "hammertime"
109
+ subject.define :reel, :type => Integer
111
110
  end
112
111
 
113
112
  it "displays a modified usage" do
114
113
  ::ARGV.replace ['--help']
115
- stderr_output = capture_help_message{ @config.resolve! }
114
+ stderr_output = capture_help_message{ subject.resolve! }
116
115
  stderr_output.should =~ %r{usage:.*\[command\]}m
117
116
  end
118
117
 
119
118
  it "displays the commands and their descriptions" do
120
119
  ::ARGV.replace ['--help']
121
- stderr_output = capture_help_message{ @config.resolve! }
120
+ stderr_output = capture_help_message{ subject.resolve! }
122
121
  stderr_output.should =~ %r{Available commands:\s+run\s*forrest\s+stop\s+hammertime}m
123
122
  stderr_output.should =~ %r{Params:.*--reel=Integer\s+reel}m
124
123
  end
@@ -127,8 +126,8 @@ describe "Configliere::Commands" do
127
126
  describe '#resolve!' do
128
127
  it 'calls super and returns self' do
129
128
  Configliere::ParamParent.class_eval do def resolve!() dummy ; end ; end
130
- @config.should_receive(:dummy)
131
- @config.resolve!.should equal(@config)
129
+ subject.should_receive(:dummy)
130
+ subject.resolve!.should equal(subject)
132
131
  Configliere::ParamParent.class_eval do def resolve!() self ; end ; end
133
132
  end
134
133
  end
@@ -136,8 +135,8 @@ describe "Configliere::Commands" do
136
135
  describe '#validate!' do
137
136
  it 'calls super and returns self' do
138
137
  Configliere::ParamParent.class_eval do def validate!() dummy ; end ; end
139
- @config.should_receive(:dummy)
140
- @config.validate!.should equal(@config)
138
+ subject.should_receive(:dummy)
139
+ subject.validate!.should equal(subject)
141
140
  Configliere::ParamParent.class_eval do def validate!() self ; end ; end
142
141
  end
143
142
  end
@@ -1,171 +1,192 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe Configliere::ConfigFile do
4
- before do
5
- @config = Configliere::Param.new :my_param => 'default_val', :also_a_param => true
6
- FileUtils.stub! :mkdir_p
7
- end
4
+ let(:default_params) { { my_param: 'default_val', also_a_param: true } }
5
+
6
+ subject{ Configliere::Param.new default_params }
8
7
 
9
- it 'is used by default' do
10
- @config.should respond_to(:read)
8
+ it 'is included by default' do
9
+ subject.class.included_modules.should include(described_class)
11
10
  end
12
11
 
13
- describe 'loading a yaml config file' do
14
- before do
15
- @fake_file = "---\nmy_param: val_from_file"
16
- end
17
-
18
- describe 'successfully' do
19
- it 'with an absolute pathname uses it directly' do
20
- File.should_receive(:open).with(%r{/fake/path.yaml}).and_return(@fake_file)
21
- @config.read '/fake/path.yaml'
22
- end
23
- it 'with a simple filename, references it to the default config dir' do
24
- File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.yaml')).and_return(@fake_file)
25
- @config.read 'file.yaml'
26
- end
27
- it 'returns the config object for chaining' do
28
- File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.yaml')).and_return(@fake_file)
29
- @config.defaults :also_a_param => true
30
- @config.read('file.yaml').should == { :my_param => 'val_from_file', :also_a_param => true }
31
- end
32
- after do
33
- @config[:my_param].should == 'val_from_file'
12
+ context '#read' do
13
+ let(:file_params) { { my_param: 'val_from_file' } }
14
+ let(:file_string) { file_params.to_yaml }
15
+ let(:file_path) { '/absolute/path.yaml' }
16
+
17
+ before{ File.stub(:open).and_return(file_string) }
18
+
19
+ it 'returns the config object for chaining' do
20
+ subject.read(file_path).should == subject
21
+ end
22
+
23
+ context 'a yaml file' do
24
+ let(:file_path) { '/absolute/path.yaml' }
25
+
26
+ it 'reads successfully' do
27
+ subject.should_receive(:read_yaml).with(file_string, {})
28
+ subject.read file_path
29
+ end
30
+
31
+ it 'merges the data' do
32
+ subject.read(file_path).should == default_params.merge(file_params)
33
+ end
34
+ end
35
+
36
+ context 'a json file' do
37
+ let(:file_path) { '/absolute/path.json' }
38
+ let(:file_string) { file_params.to_json }
39
+
40
+ it 'reads successfully' do
41
+ subject.should_receive(:read_json).with(file_string, {})
42
+ subject.read file_path
43
+ end
44
+
45
+ it 'merges the data' do
46
+ subject.read(file_path).should == default_params.merge(file_params)
34
47
  end
35
48
  end
49
+
50
+ context 'given a symbol' do
51
+ let(:file_path) { :my_settings }
36
52
 
37
- it 'no longer provides a default config file' do
38
- lambda{ @config.read(:my_settings) }.should raise_error(Configliere::DeprecatedError)
39
- defined?(Configliere::DEFAULT_CONFIG_FILE).should_not be_true
40
- end
41
-
42
- it 'warns but does not fail if the file is missing' do
43
- @config = Configliere::Param.new
44
- File.stub(:open).and_raise(Errno::ENOENT)
45
- @config.should_receive(:warn).with("Loading empty configliere settings file #{Configliere::DEFAULT_CONFIG_DIR}/nonexistent_file.yaml")
46
- @config.read('nonexistent_file.yaml').should == {}
47
- end
48
- end
49
-
50
- describe 'loading a json config file' do
51
- before do
52
- require 'json'
53
- @fake_file = '{"my_param":"val_from_file"}'
54
- end
55
-
56
- describe 'successfully' do
57
- it 'with an absolute pathname uses it directly' do
58
- File.should_receive(:open).with(%r{/fake/path.json}).and_return(@fake_file)
59
- @config.read '/fake/path.json'
60
- end
61
- it 'with a simple filename, references it to the default config dir' do
62
- File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.json')).and_return(@fake_file)
63
- @config.read 'file.json'
64
- end
65
- it 'returns the config object for chaining' do
66
- File.should_receive(:open).with(File.join(Configliere::DEFAULT_CONFIG_DIR, 'file.json')).and_return(@fake_file)
67
- @config.defaults :also_a_param => true
68
- @config.read('file.json').should == { :my_param => 'val_from_file', :also_a_param => true }
69
- end
70
- after do
71
- @config[:my_param].should == 'val_from_file'
53
+ it 'no longer provides a default config file' do
54
+ expect{ subject.read(file_path) }.to raise_error(Configliere::DeprecatedError)
55
+ defined?(Configliere::DEFAULT_CONFIG_FILE).should_not be_true
72
56
  end
73
57
  end
74
-
75
- it 'no longer provides a default config file' do
76
- lambda{ @config.read(:my_settings) }.should raise_error(Configliere::DeprecatedError)
77
- defined?(Configliere::DEFAULT_CONFIG_FILE).should_not be_true
78
- end
79
-
80
- it 'warns but does not fail if the file is missing' do
81
- @config = Configliere::Param.new
82
- File.stub(:open).and_raise(Errno::ENOENT)
83
- @config.should_receive(:warn).with("Loading empty configliere settings file #{Configliere::DEFAULT_CONFIG_DIR}/nonexistent_file.json")
84
- @config.read('nonexistent_file.json').should == {}
85
- end
86
- end
87
-
88
- describe '#read_yaml' do
89
- before do
90
- @config.merge! :reload => :whatever
91
- @simple_yaml = { :my_param => 'override_val', 'also_a_param' => true, 'strkey' => 'val', :falsekey => false, :nilkey => nil }.to_yaml
92
- @yaml_with_subenvs = { :development => { :reload => true }, :production => { :reload => false }}.to_yaml
93
- end
94
-
95
- it 'loads yaml' do
96
- @config.read_yaml(@simple_yaml)
97
- @config.should == { :reload => :whatever, :my_param => 'override_val', :also_a_param => true, :strkey => 'val', :falsekey => false, :nilkey => nil }
98
- @config.should_not == { :reload => :whatever, :my_param => 'override_val', 'also_a_param' => true, 'strkey' => 'val', :falsekey => false, :nilkey => nil }
58
+
59
+ context 'given a nonexistent file' do
60
+ let(:file_path) { 'nonexistent.conf' }
61
+
62
+ it 'warns but does not fail if the file is missing' do
63
+ File.stub(:open).and_raise(Errno::ENOENT)
64
+ subject.should_receive(:warn).with("Loading empty configliere settings file #{subject.default_conf_dir}/#{file_path}")
65
+ subject.read(file_path).should == subject
66
+ end
99
67
  end
100
68
 
101
- describe 'with an environment scope' do
102
- it 'slices out a subhash given by :env' do
103
- @config.read_yaml(@yaml_with_subenvs, :env => :development)
104
- @config.should == { :reload => true, :my_param => 'default_val', :also_a_param => true }
69
+ context 'given an absolute path' do
70
+ let(:file_path) { '/absolute/path.yaml' }
71
+
72
+ it 'uses it directly' do
73
+ File.should_receive(:open).with(file_path).and_return(file_string)
74
+ subject.read file_path
75
+ end
76
+ end
77
+
78
+ context 'given a simple filename' do
79
+ let(:file_path) { 'simple_path.yaml' }
80
+
81
+ it 'references it to the default config dir' do
82
+ File.should_receive(:open).with(File.join(subject.default_conf_dir, file_path)).and_return(file_string)
83
+ subject.read file_path
84
+ end
85
+ end
86
+
87
+ context 'with options' do
88
+ let(:file_params) { { development: { reload: true }, production: { reload: false } } }
89
+
90
+ before{ subject.merge!(reload: 'whatever') }
91
+
92
+ context ':env key' do
93
+ context 'valid :env' do
94
+ let(:opts) { { env: :development } }
95
+
96
+ it 'slices out a subhash given by :env' do
97
+ subject.read(file_path, opts)
98
+ subject.should == default_params.merge(reload: true)
99
+ end
100
+ end
101
+
102
+ context 'invalid :env' do
103
+ let(:opts) { { env: :not_there } }
104
+
105
+ it 'has no effect if the key given by :env option is absent' do
106
+ subject.read(file_path, opts)
107
+ subject.should == default_params.merge(reload: 'whatever')
108
+ end
109
+ end
105
110
  end
111
+
112
+ context 'no :env key' do
113
+ let(:opts) { Hash.new }
114
+
115
+ it 'does no slicing without the :env option' do
116
+ subject.read(file_path, opts)
117
+ subject.should == default_params.merge(reload: 'whatever').merge(file_params)
118
+ end
119
+ end
120
+ end
121
+ end
106
122
 
107
- it 'slices out a different subhash with a different :env' do
108
- @config.read_yaml(@yaml_with_subenvs, :env => :production)
109
- @config.should == { :reload => false, :my_param => 'default_val', :also_a_param => true }
110
- end
123
+ context '#save!' do
124
+ let(:fake_file) { StringIO.new('', 'w') }
111
125
 
112
- it 'does no slicing without the :env option' do
113
- @config.read_yaml(@yaml_with_subenvs)
114
- @config.should == { :development => { :reload => true }, :production => { :reload => false }, :reload => :whatever, :my_param => 'default_val', :also_a_param => true }
126
+ context 'given an absolute pathname' do
127
+ let(:file_path) { '/absolute/path.yaml' }
128
+
129
+ it 'saves the filename as given' do
130
+ File.should_receive(:open).with(file_path, 'w').and_yield(fake_file)
131
+ fake_file.should_receive(:<<).with(default_params.to_yaml)
132
+ subject.save! file_path
115
133
  end
116
-
117
- it 'has no effect if the key given by :env option is absent' do
118
- @config.read_yaml(@yaml_with_subenvs, :env => :foobar)
119
- @config.should == { :reload => :whatever, :my_param => 'default_val', :also_a_param => true }
134
+ end
135
+
136
+ context 'given a simple pathname' do
137
+ let(:file_path) { 'simple_path.yaml' }
138
+
139
+ it 'saves the filename in the default config dir' do
140
+ File.should_receive(:open).with(File.join(subject.default_conf_dir, file_path), 'w').and_yield(fake_file)
141
+ fake_file.should_receive(:<<).with(default_params.to_yaml)
142
+ subject.save! file_path
120
143
  end
121
-
122
- it 'lets you use a string if the loading hash has a string' do
123
- yaml_with_string_subenv = { 'john_woo' => { :reload => :sideways }}.to_yaml
124
- @config.read_yaml(yaml_with_string_subenv, :env => 'john_woo')
125
- @config.should == { :reload => :sideways, :my_param => 'default_val', :also_a_param => true }
144
+
145
+ it 'ensures the directory exists' do
146
+ File.should_receive(:open).with(File.join(subject.default_conf_dir, file_path), 'w').and_yield(fake_file)
147
+ FileUtils.should_receive(:mkdir_p).with(subject.default_conf_dir.to_s)
148
+ subject.save! file_path
126
149
  end
127
150
  end
128
151
  end
129
-
130
- describe 'saves to a config file' do
131
- it 'with an absolute pathname, as given' do
132
- fake_file = StringIO.new('', 'w')
133
- File.should_receive(:open).with(%r{/fake/path.yaml}, 'w').and_yield(fake_file)
134
- fake_file.should_receive(:<<).with({ :my_param => 'default_val', :also_a_param => true }.to_yaml)
135
- @config.save! '/fake/path.yaml'
136
- end
137
-
138
- it 'with a simple pathname, in the default config dir' do
139
- fake_file = StringIO.new('', 'w')
140
- File.should_receive(:open).with(Configliere::DEFAULT_CONFIG_DIR + '/file.yaml', 'w').and_yield(fake_file)
141
- fake_file.should_receive(:<<).with({ :my_param => 'default_val', :also_a_param => true }.to_yaml)
142
- @config.save! 'file.yaml'
143
- end
144
-
145
- it 'and ensures the directory exists' do
146
- fake_file = StringIO.new('', 'w')
147
- File.stub!(:open).with(%r{/fake/path.yaml}, 'w').and_yield(fake_file)
148
- FileUtils.should_receive(:mkdir_p).with(%r{/fake})
149
- @config.save! '/fake/path.yaml'
150
- end
151
- end
152
-
153
- describe '#resolve!' do
152
+
153
+ context '#resolve!' do
154
+ around do |example|
155
+ Configliere::ParamParent.class_eval{ def resolve!() parent_method ; end }
156
+ example.run
157
+ Configliere::ParamParent.class_eval{ def resolve!() self ; end }
158
+ end
159
+
154
160
  it 'calls super and returns self' do
155
- Configliere::ParamParent.class_eval do def resolve!() dummy ; end ; end
156
- @config.should_receive(:dummy)
157
- @config.resolve!.should equal(@config)
158
- Configliere::ParamParent.class_eval do def resolve!() self ; end ; end
161
+ subject.should_receive(:parent_method)
162
+ subject.resolve!.should equal(subject)
159
163
  end
160
164
  end
161
-
165
+
162
166
  describe '#validate!' do
167
+ around do |example|
168
+ Configliere::ParamParent.class_eval{ def validate!() parent_method ; end }
169
+ example.run
170
+ Configliere::ParamParent.class_eval{ def validate!() self ; end }
171
+ end
172
+
163
173
  it 'calls super and returns self' do
164
- Configliere::ParamParent.class_eval do def validate!() dummy ; end ; end
165
- @config.should_receive(:dummy)
166
- @config.validate!.should equal(@config)
167
- Configliere::ParamParent.class_eval do def validate!() self ; end ; end
174
+ subject.should_receive(:parent_method)
175
+ subject.validate!.should equal(subject)
168
176
  end
169
177
  end
170
178
 
179
+ context '#load_configuration_in_order!' do
180
+ let(:scope) { 'test' }
181
+
182
+ before{ subject.stub(:determine_conf_location).and_return('conf_dir') }
183
+
184
+ it 'resolves configuration in order' do
185
+ subject.should_receive(:determine_conf_location).with(:machine, scope).ordered
186
+ subject.should_receive(:determine_conf_location).with(:user, scope).ordered
187
+ subject.should_receive(:determine_conf_location).with(:app, scope).ordered
188
+ subject.should_receive(:resolve!).ordered
189
+ subject.load_configuration_in_order!(scope)
190
+ end
191
+ end
171
192
  end
data/spec/spec_helper.rb CHANGED
@@ -6,3 +6,5 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
6
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
7
 
8
8
  require 'configliere'
9
+ require 'json'
10
+ require 'yaml'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configliere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.10
4
+ version: 0.4.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-30 00:00:00.000000000 Z
13
+ date: 2012-08-07 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: multi_json
17
- requirement: &70312657570540 !ruby/object:Gem::Requirement
17
+ requirement: &2161847760 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '1.1'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70312657570540
25
+ version_requirements: *2161847760
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: oj
28
- requirement: &70312657570060 !ruby/object:Gem::Requirement
28
+ requirement: &2161846860 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '1.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70312657570060
36
+ version_requirements: *2161846860
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: json
39
- requirement: &70312657569580 !ruby/object:Gem::Requirement
39
+ requirement: &2161827640 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70312657569580
47
+ version_requirements: *2161827640
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: highline
50
- requirement: &70312657569100 !ruby/object:Gem::Requirement
50
+ requirement: &2161826540 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.5.2
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70312657569100
58
+ version_requirements: *2161826540
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: bundler
61
- requirement: &70312657584980 !ruby/object:Gem::Requirement
61
+ requirement: &2161825840 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ~>
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '1.1'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *70312657584980
69
+ version_requirements: *2161825840
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rake
72
- requirement: &70312657584500 !ruby/object:Gem::Requirement
72
+ requirement: &2161825100 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '0'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *70312657584500
80
+ version_requirements: *2161825100
81
81
  description: ! " You've got a script. It's got some settings. Some settings are for
82
82
  this module, some are for that module. Most of them don't change. Except on your
83
83
  laptop, where the paths are different. Or when you're in production mode. Or when
@@ -134,6 +134,7 @@ files:
134
134
  - lib/configliere/env_var.rb
135
135
  - lib/configliere/param.rb
136
136
  - lib/configliere/prompt.rb
137
+ - lib/configliere/vayacondios.rb
137
138
  - spec/configliere/commandline_spec.rb
138
139
  - spec/configliere/commands_spec.rb
139
140
  - spec/configliere/config_block_spec.rb
@@ -163,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
164
  version: '0'
164
165
  segments:
165
166
  - 0
166
- hash: -1763180514100081494
167
+ hash: -1692998738984216950
167
168
  required_rubygems_version: !ruby/object:Gem::Requirement
168
169
  none: false
169
170
  requirements:
@@ -172,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
173
  version: '0'
173
174
  requirements: []
174
175
  rubyforge_project:
175
- rubygems_version: 1.8.11
176
+ rubygems_version: 1.8.15
176
177
  signing_key:
177
178
  specification_version: 3
178
179
  summary: Wise, discreet configuration management