yacl 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/HISTORY.rdoc +5 -0
  2. data/LICENSE +16 -0
  3. data/Manifest.txt +48 -0
  4. data/README.rdoc +55 -0
  5. data/Rakefile +308 -0
  6. data/example/myapp-simple/bin/myapp +16 -0
  7. data/example/myapp-simple/config/database.yml +8 -0
  8. data/example/myapp-simple/config/host.yml +2 -0
  9. data/example/myapp-simple/config/pipeline.yml +1 -0
  10. data/example/myapp-simple/lib/myapp.rb +53 -0
  11. data/example/myapp/bin/myapp +17 -0
  12. data/example/myapp/bin/myapp-job +10 -0
  13. data/example/myapp/config/database.yml +8 -0
  14. data/example/myapp/config/httpserver.yml +3 -0
  15. data/example/myapp/config/pipeline.yml +1 -0
  16. data/example/myapp/lib/myapp.rb +6 -0
  17. data/example/myapp/lib/myapp/cli.rb +92 -0
  18. data/example/myapp/lib/myapp/defaults.rb +28 -0
  19. data/example/myapp/lib/myapp/job.rb +56 -0
  20. data/lib/yacl.rb +12 -0
  21. data/lib/yacl/define.rb +9 -0
  22. data/lib/yacl/define/cli.rb +7 -0
  23. data/lib/yacl/define/cli/options.rb +97 -0
  24. data/lib/yacl/define/cli/parser.rb +112 -0
  25. data/lib/yacl/define/cli/runner.rb +82 -0
  26. data/lib/yacl/define/defaults.rb +58 -0
  27. data/lib/yacl/define/plan.rb +197 -0
  28. data/lib/yacl/loader.rb +80 -0
  29. data/lib/yacl/loader/env.rb +103 -0
  30. data/lib/yacl/loader/yaml_dir.rb +137 -0
  31. data/lib/yacl/loader/yaml_file.rb +102 -0
  32. data/lib/yacl/properties.rb +144 -0
  33. data/lib/yacl/simple.rb +52 -0
  34. data/spec/data/yaml_dir/database.yml +8 -0
  35. data/spec/data/yaml_dir/httpserver.yml +3 -0
  36. data/spec/define/cli/options_spec.rb +47 -0
  37. data/spec/define/cli/parser_spec.rb +64 -0
  38. data/spec/define/cli/runner_spec.rb +57 -0
  39. data/spec/define/defaults_spec.rb +24 -0
  40. data/spec/define/plan_spec.rb +77 -0
  41. data/spec/loader/env_spec.rb +32 -0
  42. data/spec/loader/yaml_dir_spec.rb +43 -0
  43. data/spec/loader/yaml_file_spec.rb +80 -0
  44. data/spec/loader_spec.rb +16 -0
  45. data/spec/properties_spec.rb +60 -0
  46. data/spec/simple_spec.rb +85 -0
  47. data/spec/spec_helper.rb +31 -0
  48. data/spec/version_spec.rb +8 -0
  49. metadata +207 -0
@@ -0,0 +1,5 @@
1
+ = YACL Changlog
2
+ == Version 1.0.0
3
+
4
+ * Initial Release - Yeah!
5
+
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ ISC LICENSE - http://opensource.org/licenses/isc-license.txt
2
+
3
+ Copyright (c) 2012 Jeremy Hinegardner
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+
@@ -0,0 +1,48 @@
1
+ HISTORY.rdoc
2
+ LICENSE
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ example/myapp-simple/bin/myapp
7
+ example/myapp-simple/config/database.yml
8
+ example/myapp-simple/config/host.yml
9
+ example/myapp-simple/config/pipeline.yml
10
+ example/myapp-simple/lib/myapp.rb
11
+ example/myapp/bin/myapp
12
+ example/myapp/bin/myapp-job
13
+ example/myapp/config/database.yml
14
+ example/myapp/config/httpserver.yml
15
+ example/myapp/config/pipeline.yml
16
+ example/myapp/lib/myapp.rb
17
+ example/myapp/lib/myapp/cli.rb
18
+ example/myapp/lib/myapp/defaults.rb
19
+ example/myapp/lib/myapp/job.rb
20
+ lib/yacl.rb
21
+ lib/yacl/define.rb
22
+ lib/yacl/define/cli.rb
23
+ lib/yacl/define/cli/options.rb
24
+ lib/yacl/define/cli/parser.rb
25
+ lib/yacl/define/cli/runner.rb
26
+ lib/yacl/define/defaults.rb
27
+ lib/yacl/define/plan.rb
28
+ lib/yacl/loader.rb
29
+ lib/yacl/loader/env.rb
30
+ lib/yacl/loader/yaml_dir.rb
31
+ lib/yacl/loader/yaml_file.rb
32
+ lib/yacl/properties.rb
33
+ lib/yacl/simple.rb
34
+ spec/data/yaml_dir/database.yml
35
+ spec/data/yaml_dir/httpserver.yml
36
+ spec/define/cli/options_spec.rb
37
+ spec/define/cli/parser_spec.rb
38
+ spec/define/cli/runner_spec.rb
39
+ spec/define/defaults_spec.rb
40
+ spec/define/plan_spec.rb
41
+ spec/loader/env_spec.rb
42
+ spec/loader/yaml_dir_spec.rb
43
+ spec/loader/yaml_file_spec.rb
44
+ spec/loader_spec.rb
45
+ spec/properties_spec.rb
46
+ spec/simple_spec.rb
47
+ spec/spec_helper.rb
48
+ spec/version_spec.rb
@@ -0,0 +1,55 @@
1
+ == YACL
2
+
3
+ * Homepage[https://github.com/copiousfreetime/yacl/]
4
+ * {Github Project}[https://github.com/copiousfreetime/yacl]
5
+ * email jeremy at hinegardner dot org
6
+
7
+ == DESCRIPTION
8
+
9
+ YACL is your application configuration library.
10
+
11
+ == FEATURES
12
+
13
+ Yacl is a full featured commandline and application configuration library. It
14
+ pulls together the different components of a system that provide application
15
+ configuration properties:
16
+
17
+ * Commandline options
18
+ * Environment Variables
19
+ * Configuration directory
20
+ * Configuration files
21
+ * Global Defaults
22
+
23
+ It allows you to define the order and priority of the various contributors to
24
+ the configuration in a fairly easy way.
25
+
26
+ == Examples
27
+
28
+ There are two full examples in the examples directory:
29
+
30
+ myapp-simple:: This uses the Yacl::Simple library to quickly define
31
+ commandline options, global defaults, configuration directory and
32
+ environment parsing all in short amout of code using a dsl.
33
+ myapp:: This is a more full featured approach that you may want to look
34
+ at should you have more complex application configuration needs.
35
+ Functionally it is very similar to myapp-simple
36
+
37
+ == ISC LICENSE
38
+
39
+ http://opensource.org/licenses/isc-license.txt
40
+
41
+ Copyright (c) 2012 Jeremy Hinegardner
42
+
43
+ Permission to use, copy, modify, and/or distribute this software for any
44
+ purpose with or without fee is hereby granted, provided that the above
45
+ copyright notice
46
+ and this permission notice appear in all copies.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
49
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
50
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
51
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
52
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
53
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
54
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55
+
@@ -0,0 +1,308 @@
1
+ # vim: syntax=ruby
2
+
3
+ This.name = "yacl"
4
+ This.author = "Jeremy Hinegardner"
5
+ This.email = "jeremy@copiousfreetime.org"
6
+ This.homepage = "http://github.com/copiousfreetime/#{ This.name }"
7
+ This.version = Util.version
8
+
9
+ #------------------------------------------------------------------------------
10
+ # If you want to Develop on this project just run 'rake develop' and you'll
11
+ # have all you need to get going. If you want to use bundler for development,
12
+ # then run 'rake develop:using_bundler'
13
+ #------------------------------------------------------------------------------
14
+ namespace :develop do
15
+
16
+ # Install all the development and runtime dependencies of this gem using the
17
+ # gemspec.
18
+ task :default do
19
+ require 'rubygems/dependency_installer'
20
+ installer = Gem::DependencyInstaller.new
21
+
22
+ # list these here instead of gem dependencies since there is not a way to
23
+ # specify ruby version specific dependencies
24
+ if RUBY_VERSION < "1.9.2"
25
+ Util.platform_gemspec.add_development_dependency( 'rcov', '~> 0.9.11' )
26
+ else
27
+ Util.platform_gemspec.add_development_dependency( 'simplecov', '~> 0.6.4' )
28
+ end
29
+
30
+ puts "Installing gem depedencies needed for development"
31
+ Util.platform_gemspec.dependencies.each do |dep|
32
+ if dep.matching_specs.empty? then
33
+ puts "Installing : #{dep}"
34
+ installer.install dep
35
+ else
36
+ puts "Skipping : #{dep} -> already installed #{dep.matching_specs.first.full_name}"
37
+ end
38
+ end
39
+ puts "\n\nNow run 'rake test'"
40
+ end
41
+
42
+ # Create a Gemfile that just references the gemspec
43
+ file 'Gemfile' => :gemspec do
44
+ File.open( "Gemfile", "w+" ) do |f|
45
+ f.puts 'source :rubygems'
46
+ f.puts 'gemspec'
47
+ end
48
+ end
49
+
50
+ desc "Create a bundler Gemfile"
51
+ task :using_bundler => 'Gemfile' do
52
+ puts "Now you can 'bundle'"
53
+ end
54
+
55
+ # Gemfiles are build artifacts
56
+ CLOBBER << FileList['Gemfile*']
57
+ end
58
+ desc "Boostrap development"
59
+ task :develop => "develop:default"
60
+
61
+ #------------------------------------------------------------------------------
62
+ # Minitest - standard TestTask
63
+ #------------------------------------------------------------------------------
64
+ begin
65
+ require 'rake/testtask'
66
+ Rake::TestTask.new( :test ) do |t|
67
+ t.ruby_opts = %w[ -w -rubygems ]
68
+ t.libs = %w[ lib spec ]
69
+ t.pattern = "spec/**/*_spec.rb"
70
+ end
71
+ task :default => :test
72
+ rescue LoadError
73
+ Util.task_warning( 'test' )
74
+ end
75
+
76
+ #------------------------------------------------------------------------------
77
+ # RDoc - standard rdoc rake task, although we must make sure to use a more
78
+ # recent version of rdoc since it is the one that has 'tomdoc' markup
79
+ #------------------------------------------------------------------------------
80
+ begin
81
+ gem 'rdoc' # otherwise we get the wrong task from stdlib
82
+ require 'rdoc/task'
83
+ RDoc::Task.new do |t|
84
+ t.markup = 'tomdoc'
85
+ t.rdoc_dir = 'doc'
86
+ t.main = 'README.rdoc'
87
+ t.title = "#{This.name} #{This.version}"
88
+ t.rdoc_files.include( '*.rdoc', 'lib/**/*.rb' )
89
+ end
90
+ rescue LoadError => le
91
+ Util.task_warning( 'rdoc' )
92
+ end
93
+
94
+ #------------------------------------------------------------------------------
95
+ # Coverage - optional code coverage, rcov for 1.8 and simplecov for 1.9, so
96
+ # for the moment only rcov is listed.
97
+ #------------------------------------------------------------------------------
98
+ if RUBY_VERSION <= "1.9.2"
99
+ begin
100
+ require 'rcov/rcovtask'
101
+ Rcov::RcovTask.new( 'coverage' ) do |t|
102
+ t.libs << 'spec'
103
+ t.pattern = 'spec/**/*_spec.rb'
104
+ t.verbose = true
105
+ t.rcov_opts << "-x ^/" # remove all the global files
106
+ t.rcov_opts << "--sort coverage" # so we see the worst files at the top
107
+ end
108
+ rescue LoadError
109
+ Util.task_warning( 'rcov' )
110
+ end
111
+ else
112
+ begin
113
+ require 'simplecov'
114
+ desc 'Run tests with code coverage'
115
+ task :coverage do
116
+ ENV['COVERAGE'] = 'true'
117
+ Rake::Task[:test].execute
118
+ end
119
+ CLOBBER << FileList["coverage"]
120
+ rescue LoadError
121
+ Util.task_warning( 'simplecov' )
122
+ end
123
+ end
124
+ #------------------------------------------------------------------------------
125
+ # Manifest - We want an explicit list of thos files that are to be packaged in
126
+ # the gem. Most of this is from Hoe.
127
+ #------------------------------------------------------------------------------
128
+ namespace 'manifest' do
129
+ desc "Check the manifest"
130
+ task :check => :clean do
131
+ files = FileList["**/*", ".*"].exclude( This.exclude_from_manifest ).to_a.sort
132
+ files = files.select{ |f| File.file?( f ) }
133
+
134
+ tmp = "Manifest.tmp"
135
+ File.open( tmp, 'w' ) do |f|
136
+ f.puts files.join("\n")
137
+ end
138
+
139
+ begin
140
+ sh "diff -du Manifest.txt #{tmp}"
141
+ ensure
142
+ rm tmp
143
+ end
144
+ puts "Manifest looks good"
145
+ end
146
+
147
+ desc "Generate the manifest"
148
+ task :generate => :clean do
149
+ files = %x[ git ls-files ].split("\n").sort
150
+ files.reject! { |f| f =~ This.exclude_from_manifest }
151
+ File.open( "Manifest.txt", "w" ) do |f|
152
+ f.puts files.join("\n")
153
+ end
154
+ end
155
+ end
156
+
157
+ #------------------------------------------------------------------------------
158
+ # Gem Specification
159
+ #------------------------------------------------------------------------------
160
+ This.gemspec = Hash.new
161
+ This.gemspec['ruby'] = Gem::Specification.new do |spec|
162
+ spec.name = This.name
163
+ spec.version = This.version
164
+ spec.author = This.author
165
+ spec.email = This.email
166
+ spec.homepage = This.homepage
167
+
168
+ spec.summary = This.summary
169
+ spec.description = This.description
170
+
171
+ spec.files = This.manifest
172
+ spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
173
+ spec.test_files = spec.files.grep(/^spec/)
174
+
175
+ spec.extra_rdoc_files += spec.files.grep(/(txt|rdoc)$/)
176
+ spec.rdoc_options = [ "--main" , 'README.rdoc', ]
177
+
178
+ # The Runtime Dependencies
179
+ spec.add_dependency( 'map', '~> 6.2.0')
180
+ spec.add_dependency( 'trollop', '~> 1.16' )
181
+
182
+ # The Development Dependencies
183
+ spec.add_development_dependency( 'rake' , '~> 0.9.2.2')
184
+ spec.add_development_dependency( 'minitest' , '~> 3.3.0' )
185
+ spec.add_development_dependency( 'rdoc' , '~> 3.12' )
186
+ end
187
+
188
+
189
+ # The name of the gemspec file on disk
190
+ This.gemspec_file = "#{This.name}.gemspec"
191
+
192
+ # Really this is only here to support those who use bundler
193
+ desc "Build the #{This.name}.gemspec file"
194
+ task :gemspec do
195
+ File.open( This.gemspec_file, "wb+" ) do |f|
196
+ f.write Util.platform_gemspec.to_ruby
197
+ end
198
+ end
199
+
200
+ # the gemspec is also a dev artifact and should not be kept around.
201
+ CLOBBER << This.gemspec_file
202
+
203
+ # The standard gem packaging task, everyone has it.
204
+ require 'rubygems/package_task'
205
+ Gem::PackageTask.new( Util.platform_gemspec ) do
206
+ # nothing
207
+ end
208
+
209
+ #------------------------------------------------------------------------------
210
+ # Release - the steps we go through to do a final release, this is pulled from
211
+ # a compbination of mojombo's rakegem, hoe and hoe-git
212
+ #
213
+ # 1) make sure we are on the master branch
214
+ # 2) make sure there are no uncommitted items
215
+ # 3) check the manifest and make sure all looks good
216
+ # 4) build the gem
217
+ # 5) do an empty commit to have the commit message of the version
218
+ # 6) tag that commit as the version
219
+ # 7) push master
220
+ # 8) push the tag
221
+ # 7) pus the gem
222
+ #------------------------------------------------------------------------------
223
+ task :release_check do
224
+ unless `git branch` =~ /^\* master$/
225
+ abort "You must be on the master branch to release!"
226
+ end
227
+ unless `git status` =~ /^nothing to commit/m
228
+ abort "Nope, sorry, you have unfinished business"
229
+ end
230
+ end
231
+
232
+ desc "Create tag v#{This.version}, build and push #{Util.platform_gemspec.full_name} to rubygems.org"
233
+ task :release => [ :release_check, 'manifest:check', :gem ] do
234
+ sh "git commit --allow-empty -a -m 'Release #{This.version}'"
235
+ sh "git tag -a -m 'v#{This.version}' v#{This.version}"
236
+ sh "git push origin master"
237
+ sh "git push origin v#{This.version}"
238
+ sh "gem push pkg/#{Util.platform_gemspec.full_name}.gem"
239
+ end
240
+
241
+ #------------------------------------------------------------------------------
242
+ # Rakefile Support - This is all the guts and utility methods that are
243
+ # necessary to support the above tasks.
244
+ #
245
+ # Lots of Credit for this Rakefile goes to:
246
+ #
247
+ # Ara T. Howard - see the Rakefile in all of his projects -
248
+ # https://github.com/ahoward/
249
+ # Tom Preston Werner - his Rakegem project https://github.com/mojombo/rakegem
250
+ # Seattle.rb - Hoe - cuz it has relly good stuff in there
251
+ #------------------------------------------------------------------------------
252
+ BEGIN {
253
+
254
+ require 'ostruct'
255
+ require 'rake/clean'
256
+ require 'rubygems' unless defined? Gem
257
+
258
+ module Util
259
+ def self.version
260
+ [ "lib/#{ This.name }.rb", "lib/#{ This.name }/version.rb" ].each do |v|
261
+ line = File.read( v )[/^\s*VERSION\s*=\s*.*/]
262
+ if line then
263
+ return line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
264
+ end
265
+ end
266
+ end
267
+
268
+ # Partition an rdoc file into sections and return the text of the section
269
+ # as an array of paragraphs
270
+ def self.section_of( file, section_name )
271
+ re = /^=+ (.*)$/
272
+ parts = File.read( file ).split( re )[1..-1]
273
+ parts.map! { |p| p.strip }
274
+
275
+ sections = Hash.new
276
+ Hash[*parts].each do |k,v|
277
+ sections[k] = v.split("\n\n")
278
+ end
279
+ return sections[section_name]
280
+ end
281
+
282
+ def self.task_warning( task )
283
+ warn "WARNING: '#{task}' tasks are not defined. Please run 'rake develop'"
284
+ end
285
+
286
+ def self.read_manifest
287
+ abort "You need a Manifest.txt" unless File.readable?( "Manifest.txt" )
288
+ File.readlines( "Manifest.txt" ).map { |l| l.strip }
289
+ end
290
+
291
+ def self.platform_gemspec
292
+ This.gemspec[This.platform]
293
+ end
294
+ end
295
+
296
+ # Hold all the metadata about this project
297
+ This = OpenStruct.new
298
+ This.platform = (RUBY_PLATFORM == "java") ? 'java' : Gem::Platform::RUBY
299
+
300
+ desc = Util.section_of( 'README.rdoc', 'DESCRIPTION')
301
+ This.summary = desc.first
302
+ This.description = desc.join(" ").tr("\n", ' ').gsub(/[{}]/,'').gsub(/\[[^\]]+\]/,'') # strip rdoc
303
+
304
+
305
+ This.exclude_from_manifest = %r/tmp$|\.(git|DS_Store)|^(doc|coverage|pkg)|\.gemspec$|\.swp$|\.jar|\.rvmrc$|~$/
306
+ This.manifest = Util.read_manifest
307
+
308
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # load path munging so the example works from a git checkout, do not do this
4
+ # in your program
5
+ $: << File.expand_path( "../../../../lib", __FILE__ ) # yacl library
6
+ $: << File.expand_path( "../../lib", __FILE__ ) # lib dir of this sample app
7
+ require 'rubygems'
8
+
9
+ #------------------------------------------------------------------------------
10
+ # This would be the top level commandline entry point for your program. Feel
11
+ # free to have multiple of them if that is what your situation requires.
12
+ #------------------------------------------------------------------------------
13
+
14
+ require 'myapp'
15
+
16
+ MyApp::Application.go( ARGV, ENV )