confection 0.1.0 → 0.2.0

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.
data/.ruby CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  source:
3
- - profile
3
+ - var
4
4
  authors:
5
5
  - name: Trans
6
6
  email: transfire@gmail.com
@@ -8,10 +8,14 @@ copyrights:
8
8
  - holder: Rubyworks
9
9
  year: '2011'
10
10
  license: BSD-2-Clause
11
- replacements: []
12
- alternatives: []
13
11
  requirements:
12
+ - name: finder
13
+ - name: facets
14
14
  - name: blankslate
15
+ groups:
16
+ - optional
17
+ - test
18
+ development: true
15
19
  - name: detroit
16
20
  groups:
17
21
  - build
@@ -20,7 +24,12 @@ requirements:
20
24
  groups:
21
25
  - test
22
26
  development: true
27
+ - name: ae
28
+ groups:
29
+ - test
30
+ development: true
23
31
  dependencies: []
32
+ alternatives: []
24
33
  conflicts: []
25
34
  repositories:
26
35
  - uri: git://github.com/rubyworks/confection.git
@@ -38,8 +47,8 @@ revision: 0
38
47
  created: '2011-11-06'
39
48
  summary: Multi-tenant configuration for Ruby
40
49
  title: Confection
41
- version: 0.1.0
50
+ version: 0.2.0
42
51
  name: confection
43
52
  description: Confection is a multi-tenant configuration system for Ruby projects.
44
53
  organization: Rubyworks
45
- date: '2011-11-17'
54
+ date: '2012-03-11'
@@ -1,6 +1,21 @@
1
- = RELEASE HISTORY
1
+ # RELEASE HISTORY
2
2
 
3
- == 0.1.0 | 2011-11-17
3
+ ## 0.2.0 | 2012-03-11
4
+
5
+ The API has changed and no longer uses #method_missing magic.
6
+ Instead the `config` method is used to define a configuration.
7
+ In addition Confection now supports profiles via either a
8
+ block clause or via a second argument, as well as the ability
9
+ to import configurations from other projects.
10
+
11
+ Changes:
12
+
13
+ * Use #config method instead of method_missing trick.
14
+ * Add support for configuration profiles.
15
+ * Add #confect method to automatically handle typical configuration.
16
+
17
+
18
+ ## 0.1.0 | 2011-11-17
4
19
 
5
20
  This major release, probably the first truly usable release,
6
21
  adds support for multiple configration files by storing them
@@ -17,7 +32,7 @@ Changes:
17
32
  support multiple configurations at once.
18
33
 
19
34
 
20
- == 0.0.2 | 2011-11-07
35
+ ## 0.0.2 | 2011-11-07
21
36
 
22
37
  You can now use $CONFIG_FILE to change the default config file.
23
38
  Just set the variable prior to using confection. Confection
@@ -30,7 +45,7 @@ Changes:
30
45
  * Add $CONFIG_FILE to allow default config file to be adjusted.
31
46
 
32
47
 
33
- == 0.0.1 | 2011-11-06
48
+ ## 0.0.1 | 2011-11-06
34
49
 
35
50
  This is the initial release of Confection.
36
51
 
data/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ Confection (http://rubyworks.github.com/confection)
2
+
3
+ Copyright (c) 2011 Rubyworks. All rights reserved.
4
+
5
+ License (spdx) BSD-2-Clause
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20
+ COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
data/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # Confection
2
+
3
+ [Homepage](http://rubyworks.github.com/confection) |
4
+ [Source Code](http://github.com/rubyworks/confection) |
5
+ [Report Issue](http://github.com/rubyworks/confection/issues) |
6
+ [Mailing List](http://googlegroups.com/group/rubyworks-mailinglist) |
7
+ [IRC Channel](http://chat.us.freenode.net/rubyworks)
8
+
9
+ [![Build Status](https://secure.travis-ci.org/rubyworks/confection.png)](http://travis-ci.org/rubyworks/confection)
10
+
11
+
12
+ ## Description
13
+
14
+ Confection is multi-tenant configuration system for Ruby projects. If was
15
+ designed to facilitate Ruby-based configuration for multiple tools in a
16
+ single file. It is extremely simple, which makes it easy to understand
17
+ and flexible in use.
18
+
19
+
20
+ ## Instruction
21
+
22
+ To get started, create a file in you project called `Confile`. The file can
23
+ have any name that matches the glob `{.,}confile{.rb,}` case insensitive. In
24
+ this file add configuration blocks by name. For example, let's demonstrate
25
+ how we could use this to configure Rake tasks.
26
+
27
+ $ cat Confile
28
+ config :rake do
29
+ desc 'generate yard docs'
30
+ task :yard do
31
+ sh 'yard'
32
+ end
33
+ end
34
+
35
+ In our Rakefile:
36
+
37
+ $ cat Rakefile
38
+ require 'confection'
39
+ confection(:rake, '*').load
40
+
41
+ Now you might wonder why the heck you would do this. That's where the *multi-tenancy*
42
+ comes into play. Let's add another configuration, and this time for a tool that has
43
+ native support for Confection.
44
+
45
+ $ cat Confile
46
+ title = "MyApp"
47
+
48
+ config :rake do
49
+ desc 'generate yard docs'
50
+ task :yard do
51
+ sh "yard doc --title #{title}"
52
+ end
53
+ end
54
+
55
+ config :qedoc do |doc|
56
+ doc.title = "#{title} Demonstrandum"
57
+ end
58
+
59
+ Now we have configuration for both the rake tool and the qedoc tool in
60
+ a single file. Thus we gain the advantage of reducing the file count of our
61
+ project while pulling our tool configurations together into one place.
62
+ Moreover, these configurations can potentially share settings as demonstrated
63
+ here via the `title` variable.
64
+
65
+ Confection also supports profiles, either via a `profile` block or via a
66
+ second config argument.
67
+
68
+ config :qed, :cov do
69
+ require 'simplecov'
70
+ ...
71
+ end
72
+
73
+ Or,
74
+
75
+ profile :cov
76
+ config :qed do
77
+ require 'simplecov'
78
+ ...
79
+ end
80
+ end
81
+
82
+ Using Confection in your libraries is very simple, as can be seen from our
83
+ Rakefile example. The `#confection` method (alias `#config`) is used to get
84
+ a handle on a named configuration. With it you have a few options, `#call`,
85
+ `#exec` or `#load`, `#to_s` or `#to_h`.
86
+
87
+ The `#call` method evaluates a config's block in a separate per-configuration
88
+ file context in which it was defined. This is recommended. The `#exec` method,
89
+ on the other hand, will evaluate the block in the context of the caller. Where
90
+ as the `#load` method evaluates the block in the toplevel context.
91
+
92
+ For instance, QED uses `#exec` to import user configuration directly into
93
+ its Settings instance.
94
+
95
+ confection(:qed, profile_name).exec
96
+
97
+ The last two methods, `#to_s` and `#to_h` are used for text-based or hash-based
98
+ configurations. The `qedoc` configuration above is a good example of the later.
99
+ It can be converted directly into a Hash.
100
+
101
+ confection(:qedoc, :cov).to_h #=> {:title => "MyApp Demonstration"}
102
+
103
+ Lastly, there is the `#confect` method (alias `#configure`). This is just like the
104
+ `#confection` method, but automatically invokes `configure(self)` on each
105
+ selected configuration. In most cases that's exactly what is needed, so it
106
+ saves having to make the additional invocation on the return value of `#confection`.
107
+
108
+
109
+ ## Dependencies
110
+
111
+ ### Libraries
112
+
113
+ Confection depends on the [Finder](http://rubyworks.github.com/finder) library
114
+ to provide reliable load path and Gem searching. This is used when importing
115
+ configurations from external projects.
116
+
117
+ Confection also depends on [Ruby Facets](http://rubyworks.github.com/facets)
118
+ for just a few very useful core extensions.
119
+
120
+ To use Confection on Ruby 1.8 series, the `BlankSlate` library is also needed
121
+ in order to emulate Ruby's BasicObject. (This may change to the `Backports`
122
+ project in a future version.)
123
+
124
+ ### Core Extensions
125
+
126
+ Confection uses two core extensions, `#to_h`, which applies a few different
127
+ classes, `String#tabto`. These come from Ruby Facets to ensure a high standard
128
+ of interoperability.
129
+
130
+ Both of these methods have been suggested for inclusion in Ruby proper.
131
+ Please head over to Ruby Issue Tracker and add your support.
132
+
133
+ * http://bugs.ruby-lang.org/issues/749
134
+ * http://bugs.ruby-lang.org/issues/6056
135
+
136
+
137
+ ## Release Notes
138
+
139
+ Please see HISTORY.rdoc file.
140
+
141
+
142
+ ## Copyrights
143
+
144
+ Copyright (c) 2011 Rubyworks
145
+
146
+ Confection is distributable in accordance with the **BSD-2-Clause** license.
147
+
148
+ See LICENSE.txt file for details.
149
+
@@ -1,3 +1,5 @@
1
+ # TODO: Maybe use `backports` for future version.
2
+
1
3
  unless Object.const_defined?(:BasicObject)
2
4
  require 'blankslate'
3
5
  Object::BasicObject = Object::BlankSlate
@@ -0,0 +1,170 @@
1
+ module Confection
2
+
3
+ # Config encapsulates a single configuration entry as defined
4
+ # in a project's configuration file.
5
+ #
6
+ class Config
7
+
8
+ #
9
+ # Initialize Config instance. Config instances are per-configuration,
10
+ # which means they are associated with one and only one config entry.
11
+ #
12
+ def initialize(tool, profile, context, value, &block)
13
+ self.tool = tool
14
+ self.profile = profile
15
+ self.value = value
16
+ self.block = block if block
17
+
18
+ @context = context
19
+ end
20
+
21
+ #
22
+ # The name of tool being configured.
23
+ #
24
+ attr :tool
25
+
26
+ #
27
+ # Change the tool name. Note, this will rarely be used since,
28
+ # generally speaking, configurations tend to be very tool
29
+ # specific.
30
+ #
31
+ def tool=(name)
32
+ @tool = name.to_sym
33
+ end
34
+
35
+ #
36
+ # The name of the profile to which this configuration belongs.
37
+ #
38
+ attr :profile
39
+
40
+ #
41
+ # Change the profile name.
42
+ #
43
+ def profile=(name)
44
+ @profile = name.to_sym if name
45
+ end
46
+
47
+ #
48
+ # Some configuration are simple values. In those cases
49
+ # the `@value` attributes holds the object, otherwise it
50
+ # is `nil`.
51
+ #
52
+ def value
53
+ @value
54
+ end
55
+
56
+ #
57
+ # Set the configuration value.
58
+ #
59
+ # @param [Object] value
60
+ # The configuration value.
61
+ #
62
+ def value=(value)
63
+ @block = nil
64
+ @value = value
65
+ end
66
+
67
+ #
68
+ # Most configuration are scripted. In thos cases the
69
+ # `@block` attributes holds the Proc instance, otherwise
70
+ # it is `nil`.
71
+ #
72
+ attr :block
73
+
74
+ #
75
+ # Set the configuration procedure.
76
+ #
77
+ # @param [Proc] procedure
78
+ # The configuration procedure.
79
+ #
80
+ def block=(proc)
81
+ @value = nil
82
+ @block = proc.to_proc
83
+ end
84
+
85
+ #
86
+ # The arity of the configuration procedure.
87
+ #
88
+ # @return [Fixnum] number of arguments
89
+ #
90
+ def arity
91
+ @block ? @block.arity : 0
92
+ end
93
+
94
+ #
95
+ # Call the procedure. Configuration procedures are evaluated
96
+ # in the scope of a per-configuration file context instance,
97
+ # which is extended by the {DSL} evaluation context.
98
+ #
99
+ def call(*args)
100
+ #@value || @block.call(*args)
101
+ @value || @context.instance_exec(*args, &block)
102
+ end
103
+
104
+ #
105
+ # Convert the underlying procedure into an `instance_exec`
106
+ # procedure. This allows the procedure to be evaluated in
107
+ # any scope that it is be needed.
108
+ #
109
+ def to_proc
110
+ if value = @value
111
+ lambda{ value }
112
+ else
113
+ block = @block
114
+ lambda do |*args|
115
+ instance_exec(*args, &block)
116
+ end
117
+ end
118
+ end
119
+
120
+ #
121
+ # Return the value or procedure in the form of a Hash.
122
+ #
123
+ # @return [Hash]
124
+ #
125
+ def to_h
126
+ (@value || HashBuilder.new(&@block)).to_h
127
+ end
128
+
129
+ #
130
+ # Return the value or procedure in the form of a String.
131
+ #
132
+ # @return [String]
133
+ #
134
+ def to_s
135
+ (@value || call).to_s
136
+ end
137
+
138
+ #
139
+ # Alias for #to_s.
140
+ #
141
+ # @todo Should this alias be deprecated?
142
+ #
143
+ alias text to_s
144
+
145
+ #
146
+ # Copy the configuration with alterations.
147
+ #
148
+ # @param [Hash] alt
149
+ # Alternate values for configuration attributes.
150
+ #
151
+ # @return [Config] copied config
152
+ #
153
+ def copy(alt={})
154
+ copy = dup
155
+ alt.each do |k,v|
156
+ copy.__send__("#{k}=", v)
157
+ end
158
+ copy
159
+ end
160
+
161
+ #
162
+ # Ruby 1.9 defines #inspect as #to_s, ugh.
163
+ #
164
+ def inspect
165
+ "#<#{self.class.name}:#{object_id} @tool=%s @profile=%s>" % [tool.inspect, profile.inspect]
166
+ end
167
+
168
+ end
169
+
170
+ end
@@ -0,0 +1,175 @@
1
+ module Confection
2
+
3
+ # The Controller class is used to encapsulate the various methods of invocation
4
+ # that are posible on configuration blocks. It applies those invocations
5
+ # across it's set of configurations.
6
+ #
7
+ class Controller
8
+
9
+ include Enumerable
10
+
11
+ #
12
+ # Initialize new Controller instance.
13
+ #
14
+ # @param [Object] scope
15
+ #
16
+ # @param [Array<Config>] configs
17
+ #
18
+ def initialize(scope, *configs)
19
+ @scope = scope
20
+ @configs = configs
21
+ end
22
+
23
+ #
24
+ # Iterate over each config.
25
+ #
26
+ def each(&block)
27
+ @configs.each(&block)
28
+ end
29
+
30
+ #
31
+ # Number of configs.
32
+ #
33
+ def size
34
+ @configs.size
35
+ end
36
+
37
+ #
38
+ # Execute the configuration code.
39
+ #
40
+ def call(*args)
41
+ result = nil
42
+ each do |config|
43
+ result = config.call(*args)
44
+ end
45
+ result
46
+ end
47
+
48
+ #
49
+ # Special configuration call.
50
+ #
51
+ def configure
52
+ result = nil
53
+ each do |config|
54
+ case config.arity
55
+ when 0
56
+ exec
57
+ when 1
58
+ result = config.call(@scope)
59
+ end
60
+ end
61
+ result
62
+ end
63
+
64
+ #
65
+ # Evaluate configuration in the context of the caller.
66
+ #
67
+ # This is the same as calling:
68
+ #
69
+ # instance_exec(*args, &config)
70
+ #
71
+ def exec(*args)
72
+ result = nil
73
+ each do |config|
74
+ if config.respond_to?(:to_proc)
75
+ #@scope.extend(config.dsl) # ?
76
+ result = @scope.instance_exec(*args, &config)
77
+ end
78
+ end
79
+ result
80
+ end
81
+
82
+ #
83
+ # Load config as script code in context of TOPLEVEL.
84
+ #
85
+ # This is the same as calling:
86
+ #
87
+ # main = ::TOPLEVEL_BINDING.eval('self')
88
+ # main.instance_exec(*args, &config)
89
+ #
90
+ def main_exec(*args)
91
+ result = nil
92
+ main = ::Kernel.eval('self', ::TOPLEVEL_BINDING) # ::TOPLEVEL_BINDING.eval('self') [1.9+]
93
+ each do |config|
94
+ if config.respond_to?(:to_proc)
95
+ #main.extend(config.dsl)
96
+ result = main.instance_exec(*args, &config)
97
+ end
98
+ end
99
+ result
100
+ end
101
+
102
+ # @deprecated Alias for `#main_exec` might be deprecated in future.
103
+ alias load main_exec
104
+
105
+ #
106
+ # Only applicable to script and block configs, this method converts
107
+ # a set of code configs into a single block ready for execution.
108
+ #
109
+ def to_proc
110
+ #properties = ::Confection.properties # do these even matter here ?
111
+ __configs__ = @configs
112
+ block = Proc.new do |*args|
113
+ result = nil
114
+ #extend dsl # TODO: extend DSL into instance context ?
115
+ __configs__.each do |config|
116
+ if config.respond_to?(:to_proc)
117
+ result = instance_exec(*args, &config)
118
+ end
119
+ end
120
+ result
121
+ end
122
+ end
123
+
124
+ #
125
+ # Configurations texts joins together the contents of each
126
+ # configuration separated by two newlines (`\n\n`).
127
+ #
128
+ def to_s
129
+ txt = []
130
+ @configs.each do |c|
131
+ txt << c.to_s #if c.text
132
+ end
133
+ txt.join("\n\n")
134
+ end
135
+
136
+ alias text to_s
137
+
138
+ #
139
+ #
140
+ #
141
+ def to_h
142
+ hsh = {}
143
+ @configs.each do |c|
144
+ hsh.merge!(c.to_h)
145
+ end
146
+ hsh
147
+ end
148
+
149
+ ##
150
+ ## Treat configurations as YAML mappings, load, merge and return.
151
+ ##
152
+ #def yaml
153
+ # @configs.inject({}) do |h, c|
154
+ # h.merge(c.yaml)
155
+ # end
156
+ #end
157
+
158
+ #
159
+ # Inspection string for controller.
160
+ #
161
+ def inspect
162
+ "#<#{self.class}##{object_id}>"
163
+ end
164
+
165
+ end
166
+
167
+ #
168
+ #class NullController
169
+ # def exec(*); end
170
+ # def call(*); end
171
+ # def text; ''; end
172
+ # alias to_s text
173
+ #end
174
+
175
+ end
@@ -0,0 +1,154 @@
1
+ module Confection
2
+
3
+ # The File class is used to evaluate the configuration file.
4
+ #
5
+ class DSL < Module #BasicObject
6
+
7
+ #
8
+ # Create new DSL instance and parse file.
9
+ #
10
+ # @todo Does the exception rescue make sense here?
11
+ #
12
+ def self.parse(store, file)
13
+ dsl = new(store, file)
14
+ begin
15
+ text = File.read(file)
16
+ rescue => e
17
+ raise e if $DEBUG
18
+ warn e.message
19
+ end
20
+ dsl.instance_eval(text, file)
21
+ end
22
+
23
+ #
24
+ # Initialize new DSL object.
25
+ #
26
+ # @param [Store] store
27
+ # The configuration storage instance.
28
+ #
29
+ # @param [String] file
30
+ # Configuration file to load.
31
+ #
32
+ def initialize(store, file=nil)
33
+ @_store = store
34
+ @_file = file
35
+
36
+ @_contest = Object.new
37
+ @_context.extend self
38
+
39
+ @_options = {}
40
+ end
41
+
42
+ # TODO: Separate properties from project metadata ?
43
+
44
+ #
45
+ # Profile block.
46
+ #
47
+ def profile(name, options={}, &block)
48
+ raise SyntaxError, "nested tool sections" if @_options[:profile]
49
+
50
+ original_state = @_options.dup
51
+
52
+ @_options.update(options) # TODO: maybe be more exacting about this
53
+ @_options[:profile] = name.to_sym
54
+
55
+ instance_eval(&block)
56
+
57
+ @_options = original_state
58
+ end
59
+
60
+ #
61
+ # Configure a tool.
62
+ #
63
+ # @param [Symbol] tool
64
+ # The name of the tool to configure.
65
+ #
66
+ # @param [Hash] opts
67
+ # Configuration options.
68
+ #
69
+ # @options opts [String] :file
70
+ # File from which to load configuration.
71
+ #
72
+ # @options opts [String] :text
73
+ # Text of text-based configuration.
74
+ #
75
+ # @example
76
+ # config :rake, "*.rake"
77
+ #
78
+ # @example
79
+ # profile :cov do
80
+ # config :qed, "qed/simplecov.rb"
81
+ # end
82
+ #
83
+ # @todo Clean this code up.
84
+ #
85
+ def config(tool, *args, &block)
86
+ case args.first
87
+ when Symbol
88
+ profile = args.shift
89
+ when String
90
+ profile = args.shift unless args.first.index("\n")
91
+ end
92
+
93
+ case args.first
94
+ when Hash
95
+ data = args.shift
96
+ from = data[:from] # special key
97
+ when Proc
98
+ data = args.shift
99
+ # TODO convert data into OpenHash like object
100
+ when String
101
+ data = args.shift
102
+ data = data.tabto(0)
103
+ end
104
+
105
+ raise ArgumentError, "too many arguments" if args.first
106
+ raise SyntaxError, "nested profile sections" if profile && @_options[:profile]
107
+ #raise ArgumentError, "use block or :from setting" if options[:from] && block
108
+
109
+ profile = @_options[:profile] unless profile
110
+
111
+ if from
112
+ @_store.import(tool, profile, data, &block)
113
+ data = nil
114
+ return unless block
115
+ end
116
+
117
+ #original_state = @_options.dup
118
+
119
+ if data && block
120
+ raise ArgumentError, "must use data or block, not both"
121
+ end
122
+
123
+ @_store << Config.new(tool, profile, @_context, data, &block)
124
+
125
+ #@_options = original_state
126
+ end
127
+
128
+ # TODO: use `:default` profile instead of `nil` ?
129
+
130
+ #
131
+ # Evaluate script directory into current scope.
132
+ #
133
+ # @todo Make a core extension ?
134
+ #
135
+ def import(feature)
136
+ file = Find.load_path(feature).first
137
+ raise LoadError, "no such file -- #{feature}" unless file
138
+ instance_eval(::File.read(file), file) if file
139
+ end
140
+
141
+ ##
142
+ ## Cached binding.
143
+ ##
144
+ #def __binding__
145
+ # @_binding ||= binding
146
+ #end
147
+
148
+ #def __eval__(code, file=nil)
149
+ # Kernel.eval(code, __binding__, file || '(eval)')
150
+ #end
151
+
152
+ end
153
+
154
+ end
data/lib/confection.rb CHANGED
@@ -1,162 +1,50 @@
1
- require 'confection/basic_object'
2
-
3
1
  # Welcome to Confection. Your easy means to tool configuration.
4
2
  #
5
3
  module Confection
4
+ end
6
5
 
7
- #
8
- @config = Hash.new{|h,k| h[k]={}}
9
-
10
- #
11
- def self.filename
12
- @filename ||= (
13
- $CONFIG_FILE ? $CONFIG_FILE : '{.,}confile{.rb,}'
14
- )
15
- end
16
-
17
- # Configuration file can be changed using this method.
18
- # Alternatively it can be changed using `$CONFIG_FILE`.
19
- def self.filename=(glob)
20
- @filename = glob
21
- end
22
-
23
- # Bootstrap the system, loading current configurations.
24
- #
25
- def self.bootstrap
26
- if file
27
- @config[Dir.pwd] = {}
28
- begin
29
- ::Kernel.eval(read, Evaluator.binding, file)
30
- rescue => e
31
- raise e if $DEBUG
32
- warn e.message
33
- end
34
- end
35
- @config[Dir.pwd]
36
- end
37
-
38
- # Stores the configuration blocks.
39
- #
40
- # @return [Hash] configuration store
41
- def self.config
42
- if @config.key?(Dir.pwd)
43
- @config[Dir.pwd]
44
- else
45
- bootstrap
46
- end
47
- end
48
-
49
- # Look-up configuration block.
50
- #
51
- # @param name [Symbol,String]
52
- # The identifying name for the config block.
53
- #
54
- def self.[](name)
55
- config[name.to_sym]
56
- end
57
-
58
- # Set configuration block.
59
- #
60
- # @param name [Symbol,String]
61
- # The identifying name for the config block.
62
- #
63
- # @param block [Proc]
64
- # Code block for configuration.
65
- #
66
- # @return [Proc] code block
67
- def self.[]=(name, block)
68
- config[name.to_sym] = block.to_proc
69
- end
70
-
71
- # Read config file.
72
- #
73
- # @return [String] contents of the `.conf.rb` file
74
- def self.read
75
- File.read(file)
76
- end
77
-
78
- # Find config file by looking up the '.conf.rb' file.
79
- #
80
- # @param dir [String]
81
- # Optional directory to begin search.
82
- #
83
- # @return [String] file path
84
- def self.file(dir=nil)
85
- dir = dir || Dir.pwd
86
- while dir != '/'
87
- if file = Dir.glob(File.join(dir,filename),File::FNM_CASEFOLD).first
88
- return file
89
- end
90
- dir = File.dirname(dir)
91
- end
92
- nil
93
- end
6
+ require 'finder'
7
+ require 'yaml'
8
+ require 'ostruct'
94
9
 
95
- # Root directory, where config file is located.
96
- #
97
- # @param dir [String]
98
- # Optional directory to begin search.
99
- #
100
- # @return [String] directory path
101
- def self.root(dir=nil)
102
- f = file(dir)
103
- f ? File.dirname(f) : nil
104
- end
10
+ require 'confection/basic_object'
11
+ require 'confection/core_ext'
12
+ require 'confection/project'
13
+ require 'confection/store'
14
+ require 'confection/dsl'
15
+ require 'confection/hash_builder'
16
+ require 'confection/config'
17
+ require 'confection/controller'
18
+ require 'confection/current'
105
19
 
106
- # The Evaluator class is used to evaluate the `.co.rb` file.
107
- #
108
- class Evaluator < Module #BasicObject
109
- def self.binding
110
- new.__binding__
111
- end
112
- def __binding__
113
- binding
114
- end
115
- def method_missing(sym, *args, &block)
116
- #def block.call
117
- # ::Kernel.eval('self',::TOPLEVEL_BINDING).instance_exec(&self)
118
- #end
119
- ::Confection[sym] = block
120
- end
121
- end
20
+ #
21
+ # Confection's primary use method, lookups a configuration
22
+ # given the tool and profile.
23
+ #
24
+ # To select all profiles for a given tool, use `'*'`.
25
+ #
26
+ # @return [Confection::Controller] config controller
27
+ #
28
+ def config(tool, *options)
29
+ Confection.controller(self, tool, *options)
30
+ end
122
31
 
123
- # The Controller class is used to encapsulate the two types of invocation
124
- # that are posible on configuration blocks.
125
- #
126
- class Controller
127
- def initialize(scope, &block)
128
- @scope = scope
129
- @block = block
130
- end
131
- def exec(*args) # should this be named #call instead?
132
- @scope.instance_exec(*args, &@block)
133
- end
134
- def call(*args)
135
- ::Kernel.eval('self',::TOPLEVEL_BINDING).instance_exec(*args, &@block)
136
- end
137
- def to_proc
138
- @block
139
- end
140
- end
32
+ #
33
+ # Alias for #config.
34
+ #
35
+ alias confection config
141
36
 
142
- class NullController
143
- def exec(*); end
144
- def call(*); end
145
- def to_proc; Proc.new{}; end
146
- end
37
+ #
38
+ #
39
+ #
40
+ def configure(tool, *options)
41
+ controller = Confection.controller(self, tool, *options)
42
+ controller.configure
147
43
  end
148
44
 
149
- # Confection's primary use method.
150
45
  #
151
- # @return [Confection::Controller] config controller
152
- def confection(name, *args)
153
- config_block = Confection[name.to_sym]
154
- if config_block
155
- Confection::Controller.new(self, &config_block)
156
- else
157
- #warn "no configuration -- `#{name}'"
158
- Confection::NullController.new
159
- end
160
- end
46
+ # Alias for #configure.
47
+ #
48
+ alias confect configure
161
49
 
162
50
  # Copyright (c) 2011 Rubyworks (BSD-2-Clause)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: confection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
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: 2011-11-18 00:00:00.000000000 Z
12
+ date: 2012-03-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: blankslate
16
- requirement: &26062180 !ruby/object:Gem::Requirement
15
+ name: finder
16
+ requirement: &70312239870960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,32 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *26062180
24
+ version_requirements: *70312239870960
25
+ - !ruby/object:Gem::Dependency
26
+ name: facets
27
+ requirement: &70312239886780 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70312239886780
36
+ - !ruby/object:Gem::Dependency
37
+ name: blankslate
38
+ requirement: &70312239886280 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70312239886280
25
47
  - !ruby/object:Gem::Dependency
26
48
  name: detroit
27
- requirement: &26077440 !ruby/object:Gem::Requirement
49
+ requirement: &70312239885780 !ruby/object:Gem::Requirement
28
50
  none: false
29
51
  requirements:
30
52
  - - ! '>='
@@ -32,10 +54,21 @@ dependencies:
32
54
  version: '0'
33
55
  type: :development
34
56
  prerelease: false
35
- version_requirements: *26077440
57
+ version_requirements: *70312239885780
36
58
  - !ruby/object:Gem::Dependency
37
59
  name: qed
38
- requirement: &26076620 !ruby/object:Gem::Requirement
60
+ requirement: &70312239885280 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70312239885280
69
+ - !ruby/object:Gem::Dependency
70
+ name: ae
71
+ requirement: &70312239884780 !ruby/object:Gem::Requirement
39
72
  none: false
40
73
  requirements:
41
74
  - - ! '>='
@@ -43,24 +76,27 @@ dependencies:
43
76
  version: '0'
44
77
  type: :development
45
78
  prerelease: false
46
- version_requirements: *26076620
79
+ version_requirements: *70312239884780
47
80
  description: Confection is a multi-tenant configuration system for Ruby projects.
48
81
  email:
49
82
  - transfire@gmail.com
50
83
  executables: []
51
84
  extensions: []
52
85
  extra_rdoc_files:
53
- - HISTORY.rdoc
54
- - README.rdoc
55
- - COPYING.rdoc
86
+ - LICENSE.txt
87
+ - HISTORY.md
88
+ - README.md
56
89
  files:
57
90
  - .ruby
58
91
  - .yardopts
59
92
  - lib/confection/basic_object.rb
93
+ - lib/confection/config.rb
94
+ - lib/confection/controller.rb
95
+ - lib/confection/dsl.rb
60
96
  - lib/confection.rb
61
- - HISTORY.rdoc
62
- - README.rdoc
63
- - COPYING.rdoc
97
+ - LICENSE.txt
98
+ - HISTORY.md
99
+ - README.md
64
100
  homepage: http://rubyworks.github.com/confection
65
101
  licenses:
66
102
  - BSD-2-Clause
@@ -82,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
118
  version: '0'
83
119
  requirements: []
84
120
  rubyforge_project:
85
- rubygems_version: 1.8.10
121
+ rubygems_version: 1.8.11
86
122
  signing_key:
87
123
  specification_version: 3
88
124
  summary: Multi-tenant configuration for Ruby
data/COPYING.rdoc DELETED
@@ -1,31 +0,0 @@
1
- = COPYRIGHT NOTICES
2
-
3
- == Confection
4
-
5
- Copyright:: (c) 2011 Rubyworks
6
- License:: BSD-2-Clause
7
- Website:: http://rubyworks.github.com/tapout
8
-
9
- Copyright 2011 Rubyworks. All rights reserved.
10
-
11
- Redistribution and use in source and binary forms, with or without
12
- modification, are permitted provided that the following conditions are met:
13
-
14
- 1. Redistributions of source code must retain the above copyright notice,
15
- this list of conditions and the following disclaimer.
16
-
17
- 2. Redistributions in binary form must reproduce the above copyright
18
- notice, this list of conditions and the following disclaimer in the
19
- documentation and/or other materials provided with the distribution.
20
-
21
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23
- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
-
data/README.rdoc DELETED
@@ -1,83 +0,0 @@
1
- = Confection
2
-
3
- {Homepage}[http://rubyworks.github.com/confection] |
4
- {Source Code}[http://github.com/rubyworks/confection] |
5
- {Report Issue}[http://github.com/rubyworks/confection/issues] |
6
- {Mailing List}[http://googlegroups.com/group/rubyworks-mailinglist]
7
-
8
- {<img src="http://travis-ci.org/rubyworks/confection.png" />}[http://travis-ci.org/rubyworks/confection]
9
-
10
-
11
- == Description
12
-
13
- Confection is multi-tenant configuration system for Ruby projects. If was
14
- designed to facilitate Ruby-based configuration for multiple tools in a
15
- single file. It is extremely simple, which makes it easy to understand
16
- and flexible in use.
17
-
18
-
19
- == Synopsis
20
-
21
- Create a file in you project called `Confile`. By default the file can have any
22
- name tha matches the glob `{.,}confile{.rb,}` case insensitive. In this file
23
- add configuration blocks by name. For example, let's demonstrate how we could
24
- use this to configure Rake tasks.
25
-
26
- $ cat Confile
27
- rake do
28
- desc 'generate yard docs'
29
- task :yard do
30
- sh 'yard'
31
- end
32
- end
33
-
34
- In our Rakefile:
35
-
36
- $ cat Rakefile
37
- require 'confection'
38
- confection(:rake).call
39
-
40
- Now you might wonder why the heck you would do this. That's where the *multi-tenancy*
41
- comes into play. Let's add another configuration, and this time for a tool that has
42
- native support for Confection.
43
-
44
- $ cat Confile
45
- title = "myapp"
46
-
47
- rake do
48
- desc 'generate yard docs'
49
- task :yard do
50
- sh "yard doc --title #{title}"
51
- end
52
- end
53
-
54
- qed do |config|
55
- config.title = "#{title} Demonstrandum"
56
- end
57
-
58
- Now we have configuration for both the rake tool and the qed test tool in
59
- a single file. Thus we gain the advantage of reducing the file count of our
60
- project while pulling our tool configurations together into one place.
61
- Moreover, these configurations can potentially share settings as demonstrated
62
- here via the `title` variable.
63
-
64
- Using Confection in your libraries is very simple. As you can see from our
65
- example Rakefile. The `#confection` method is used to get a handle on a named
66
- configuration. With it you have two options, `#call` or `#exec`. The first
67
- evaluates the configuration block at the toplevel, while the later evaluates
68
- the block in the context of the caller.
69
-
70
-
71
- == Release Notes
72
-
73
- Please see HISTORY.rdoc file.
74
-
75
-
76
- == Copyrights
77
-
78
- Copyright (c) 2011 Rubyworks
79
-
80
- Confection is distributable in accordance with the terms of the *BSD-2-Clause* license.
81
-
82
- See COPYING.rdoc for details.
83
-