confection 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +14 -5
- data/{HISTORY.rdoc → HISTORY.md} +19 -4
- data/LICENSE.txt +27 -0
- data/README.md +149 -0
- data/lib/confection/basic_object.rb +2 -0
- data/lib/confection/config.rb +170 -0
- data/lib/confection/controller.rb +175 -0
- data/lib/confection/dsl.rb +154 -0
- data/lib/confection.rb +37 -149
- metadata +52 -16
- data/COPYING.rdoc +0 -31
- data/README.rdoc +0 -83
data/.ruby
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
---
|
2
2
|
source:
|
3
|
-
-
|
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.
|
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: '
|
54
|
+
date: '2012-03-11'
|
data/{HISTORY.rdoc → HISTORY.md}
RENAMED
@@ -1,6 +1,21 @@
|
|
1
|
-
|
1
|
+
# RELEASE HISTORY
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
-
|
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
|
+
|
@@ -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
|
-
|
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
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
#
|
152
|
-
|
153
|
-
|
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.
|
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:
|
12
|
+
date: 2012-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
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: *
|
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: &
|
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: *
|
57
|
+
version_requirements: *70312239885780
|
36
58
|
- !ruby/object:Gem::Dependency
|
37
59
|
name: qed
|
38
|
-
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: *
|
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
|
-
-
|
54
|
-
-
|
55
|
-
-
|
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
|
-
-
|
62
|
-
-
|
63
|
-
-
|
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.
|
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
|
-
|