confection 0.2.0 → 0.2.1

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
@@ -47,7 +47,7 @@ revision: 0
47
47
  created: '2011-11-06'
48
48
  summary: Multi-tenant configuration for Ruby
49
49
  title: Confection
50
- version: 0.2.0
50
+ version: 0.2.1
51
51
  name: confection
52
52
  description: Confection is a multi-tenant configuration system for Ruby projects.
53
53
  organization: Rubyworks
data/Confile.rb ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #
4
+ # QED test coverage report using SimpleCov.
5
+ #
6
+ # coverage_folder - the directory in which to store coverage report
7
+ # this defaults to `log/coverage`.
8
+ #
9
+ config :qed, :cov do
10
+ require 'simplecov'
11
+
12
+ dir = $properties.coverage_folder
13
+
14
+ SimpleCov.start do
15
+ coverage_dir(dir || 'log/coverage')
16
+ #add_group "Label", "lib/qed/directory"
17
+ end
18
+ end
19
+
20
+ #
21
+ # Example configuration.
22
+ #
23
+ config :example do
24
+ puts "Configuration Example!"
25
+ end
26
+
27
+ #
28
+ # Detroit assembly.
29
+ #
30
+ config :detroit do
31
+ email do
32
+ mailto 'ruby-talk@ruby-lang.org', 'rubyworks-mailinglist@googlegroups.com'
33
+ end
34
+
35
+ gem do
36
+ active true
37
+ end
38
+
39
+ github do
40
+ folder 'web'
41
+ end
42
+
43
+ dnote do
44
+ title 'Source Notes'
45
+ output 'log/notes.html'
46
+ end
47
+
48
+ locat do
49
+ output 'log/locat.html'
50
+ end
51
+
52
+ vclog do
53
+ output 'log/history.html',
54
+ 'log/changes.html'
55
+ end
56
+ end
57
+
@@ -0,0 +1,14 @@
1
+ # All core extensions come from Ruby Facets to maintain high standard for
2
+ # careful core extensions.
3
+
4
+ require 'facets/string/tabto'
5
+ require 'facets/to_hash'
6
+
7
+ #require 'facets/ostruct/to_h' # TODO: Newer version of facets.
8
+ require 'ostruct'
9
+ class OpenStruct
10
+ def to_h
11
+ @table.dup
12
+ end
13
+ end
14
+
@@ -0,0 +1,79 @@
1
+ module Confection
2
+
3
+ #
4
+ # Global properties is set for parsing project configuration.
5
+ # It is *always* the properties of the current project.
6
+ #
7
+ $properties = nil
8
+
9
+ # Current mixin extends the Confection module. Primarily is provides
10
+ # class methods for working with the current project's configurations.
11
+ #
12
+ module Current
13
+
14
+ #
15
+ def controller(scope, tool, *options)
16
+ params = (Hash === options.last ? options.pop : {})
17
+ params[:profile] = options.shift unless options.empty?
18
+
19
+ if from = params[:from]
20
+ projects[from] ||= Project.load(from)
21
+ projects[from].controller(scope, tool, params)
22
+ else
23
+ bootstrap if $properties.nil? # TODO: better way to go about this?
24
+ current_project.controller(scope, tool, params)
25
+ end
26
+ end
27
+
28
+ #
29
+ def bootstrap
30
+ $properties = current_project.properties
31
+ end
32
+
33
+ #
34
+ def projects
35
+ @projects ||= {}
36
+ end
37
+
38
+ #
39
+ def current_directory
40
+ @current_directory ||= Dir.pwd
41
+ end
42
+
43
+ #
44
+ def current_project
45
+ projects[current_directory] ||= Project.lookup(current_directory)
46
+ end
47
+
48
+ #
49
+ def clear!
50
+ current_project.store.clear!
51
+ end
52
+
53
+ #
54
+ def profiles(tool)
55
+ current_project.profiles(tool)
56
+ end
57
+
58
+ #
59
+ def each(&block)
60
+ current_project.each(&block)
61
+ end
62
+
63
+ #
64
+ def size
65
+ current_project.size
66
+ end
67
+
68
+ #
69
+ # Project properties.
70
+ #
71
+ def properties
72
+ current_project.properties
73
+ end
74
+
75
+ end
76
+
77
+ extend Current
78
+
79
+ end
@@ -0,0 +1,48 @@
1
+ module Confection
2
+
3
+ # HashBuilder takes a procedure and builds a Hash out of it.
4
+ #
5
+ # The procedure must conform to a set of rules to be useful in this respect.
6
+ # They must either take an argument and use that argument to set values, or
7
+ # if no argument is taken then `#instance_eval` is used to evaluate the
8
+ # procedure such that each method represents a key.
9
+ #
10
+ class HashBuilder < BasicObject
11
+
12
+ #
13
+ def initialize(hash={}, &block)
14
+ @hash = hash
15
+ case block.arity
16
+ when 0
17
+ instance_eval(&block)
18
+ else
19
+ block.call(self)
20
+ end
21
+ end
22
+
23
+ #
24
+ def to_h
25
+ @hash
26
+ end
27
+
28
+ #
29
+ def method_missing(s, *a, &b)
30
+ m = s.to_s
31
+ if a.empty? && !b
32
+ @hash[m.to_sym]
33
+ else
34
+ if b
35
+ @hash[m.chomp('=').to_sym] = HashBuilder.new(&b).to_h
36
+ else
37
+ if a.size > 1
38
+ @hash[m.chomp('=').to_sym] = a
39
+ else
40
+ @hash[m.chomp('=').to_sym] = a.first
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,161 @@
1
+ module Confection
2
+
3
+ # Project configuration.
4
+ #
5
+ # @todo Rename to `ProjectConfig` or ?
6
+ #
7
+ class Project
8
+
9
+ include Enumerable
10
+
11
+ #
12
+ # Configuration file pattern.
13
+ #
14
+ PATTERN = '{.,}confile{.rb,}'
15
+
16
+ #
17
+ # Per library cache.
18
+ #
19
+ def self.cache
20
+ @cache ||= {}
21
+ end
22
+
23
+ #
24
+ # Get project configuration from another library.
25
+ #
26
+ # This method uses the Finder gem.
27
+ #
28
+ # @param [String] lib
29
+ # Library name.
30
+ #
31
+ # @return [Project,nil] Located project.
32
+ #
33
+ def self.load(lib=nil)
34
+ if lib
35
+ lib = lib.to_s
36
+ return cache[lib] if cache.key?(lib)
37
+ cache[lib] ||= (
38
+ config_path = Find.path(PATTERN, :from=>lib).first
39
+ config_path ? new(File.dirname(config_path)) : nil
40
+ )
41
+ else
42
+ lookup
43
+ end
44
+ end
45
+
46
+ #
47
+ # Lookup configuation file.
48
+ #
49
+ # @param dir [String]
50
+ # Optional directory to begin search.
51
+ #
52
+ # @return [String] file path
53
+ #
54
+ def self.lookup(dir=nil)
55
+ dir = dir || Dir.pwd
56
+ home = File.expand_path('~')
57
+ while dir != '/' && dir != home
58
+ if file = Dir.glob(File.join(dir, PATTERN), File::FNM_CASEFOLD).first
59
+ return new(File.dirname(file))
60
+ end
61
+ dir = File.dirname(dir)
62
+ end
63
+ return nil
64
+ end
65
+
66
+ #
67
+ # Initialize new ProjectConfig.
68
+ #
69
+ # @param [String] root
70
+ # Project root directory.
71
+ #
72
+ def initialize(root)
73
+ @root = root
74
+ end
75
+
76
+ #
77
+ # Project root directory.
78
+ #
79
+ # @return [String] project's root directory
80
+ #
81
+ attr :root
82
+
83
+ #
84
+ # Alias for #root.
85
+ #
86
+ alias :directory :root
87
+
88
+ #
89
+ # Configuration store tracks a project's confirguration entries.
90
+ #
91
+ def store
92
+ @store ||= Store.new(*source)
93
+ end
94
+
95
+ #
96
+ # The file path of the project's configuration file.
97
+ #
98
+ # @return [String] path to configuration file
99
+ #
100
+ def source
101
+ Dir.glob(File.join(root, PATTERN), File::FNM_CASEFOLD)
102
+ end
103
+
104
+ #
105
+ # List of configuration profiles.
106
+ #
107
+ # @return [Array] profile names
108
+ #
109
+ def profiles(tool)
110
+ store.profiles(tool)
111
+ end
112
+
113
+ #
114
+ # Project properties.
115
+ #
116
+ # @todo Use cascading class, e.g. Confstruct.
117
+ #
118
+ def properties
119
+ dotruby = File.join(directory,'.ruby')
120
+ if File.exist?(dotruby)
121
+ data = YAML.load_file(dotruby)
122
+ OpenStruct.new(data)
123
+ else
124
+ OpenStruct.new
125
+ end
126
+ end
127
+
128
+ #
129
+ # Create a configuration controller.
130
+ #
131
+ # @param [Object] scope
132
+ # Context for which controller is being created.
133
+ #
134
+ # @param [Symbol] tool
135
+ # The tool of the configuration to select.
136
+ #
137
+ def controller(scope, tool, options={})
138
+ profile = options[:profile]
139
+ configs = store.lookup(tool, profile)
140
+ Controller.new(scope, *configs)
141
+ end
142
+
143
+ #
144
+ # Iterate over each configurations.
145
+ #
146
+ def each(&block)
147
+ store.each(&block)
148
+ end
149
+
150
+ #
151
+ # The number of configurations.
152
+ #
153
+ # @return [Fixnum] config count
154
+ #
155
+ def size
156
+ store.size
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -0,0 +1,182 @@
1
+ module Confection
2
+
3
+ class Store
4
+
5
+ include Enumerable
6
+
7
+ =begin
8
+ #
9
+ # Bootstrap the system, loading current configurations.
10
+ #
11
+ def bootstrap
12
+ if file
13
+ @config[root] = []
14
+ begin
15
+ DSL.load_file(file)
16
+ rescue => e
17
+ raise e if $DEBUG
18
+ warn e.message
19
+ end
20
+ end
21
+ @config[root]
22
+ end
23
+ =end
24
+
25
+ #
26
+ def initialize(*sources)
27
+ @sources = sources
28
+
29
+ @list = []
30
+
31
+ sources.each do |source|
32
+ if File.file?(source)
33
+ parse(source)
34
+ else
35
+ # ignore directories
36
+ end
37
+ end
38
+ end
39
+
40
+ #
41
+ attr :sources
42
+
43
+ #
44
+ def parse(file)
45
+ DSL.parse(self, file)
46
+ end
47
+
48
+ #
49
+ # Iterate over each configurations.
50
+ #
51
+ def each(&block)
52
+ @list.each(&block)
53
+ end
54
+
55
+ #
56
+ # The number of configurations.
57
+ #
58
+ # @return [Fixnum] config count
59
+ #
60
+ def size
61
+ @list.size
62
+ end
63
+
64
+ #
65
+ # Add as configuratio to the store.
66
+ #
67
+ def <<(conf)
68
+ raise TypeError, "not a configuration instance -- `#{conf}'" unless Config === conf
69
+ @list << conf
70
+ end
71
+
72
+ #
73
+ # Add a list of configs.
74
+ #
75
+ def concat(configs)
76
+ configs.each{ |c| self << c }
77
+ end
78
+
79
+ #
80
+ # Lookup configuration by tool and profile name.
81
+ #
82
+ # @todo Future versions should allow this to handle regex and fnmatches.
83
+ #
84
+ def lookup(tool, profile=nil)
85
+ if profile == '*'
86
+ select do |c|
87
+ c.tool.to_sym == tool.to_sym
88
+ end
89
+ else
90
+ profile = profile.to_sym if profile
91
+
92
+ select do |c|
93
+ c.tool.to_sym == tool.to_sym && c.profile == profile
94
+ end
95
+ end
96
+ end
97
+
98
+ #
99
+ # Returns list of profiles collected from all configs.
100
+ #
101
+ def profiles(tool)
102
+ names = []
103
+ each do |c|
104
+ names << c.profile if c.tool == tool.to_sym
105
+ end
106
+ names.uniq
107
+ end
108
+
109
+ #
110
+ # Clear configs.
111
+ #
112
+ def clear!
113
+ @list = []
114
+ end
115
+
116
+ #
117
+ def first
118
+ @list.first
119
+ end
120
+
121
+ #
122
+ def last
123
+ @list.last
124
+ end
125
+
126
+ #
127
+ #def config(*args, &block)
128
+ # dsl.config(*args, &block)
129
+ #end
130
+
131
+ #
132
+ #def controller(scope, name, profile=nil)
133
+ # configs = lookup(name, profile)
134
+ # Controller.new(scope, *configs)
135
+ #end
136
+
137
+ #
138
+ # Import configuration from another project.
139
+ #
140
+ def import(tool, profile, options, &block)
141
+ from_tool = options[:tool] || tool
142
+ from_profile = options[:profile] || profile
143
+
144
+ case from = options[:from]
145
+ when String, Symbol
146
+ project = Project.load(from.to_s)
147
+ store = project ? project.store : nil
148
+ else
149
+ from = '(self)'
150
+ store = self
151
+ end
152
+
153
+ raise "no configuration found in `#{from}'" unless store
154
+
155
+ configs = store.lookup(from_tool, from_profile)
156
+
157
+ configs.each do |config|
158
+ new_config = config.copy(:tool=>tool, :profile=>profile)
159
+
160
+ #new_options = @_options.dup
161
+ #new_options[:tool] = tool
162
+ #new_options[:profile] = profile
163
+ #new_options[:block] = config.block
164
+ #new_options[:text] = config.text
165
+
166
+ # not so sure about this one
167
+ if String === new_config.value
168
+ new_config.value += ("\n" + options[:text].to_s) if options[:text]
169
+ end
170
+
171
+ self << new_config
172
+ end
173
+
174
+ #if block
175
+ # self << Config::Block.new(tool, profile, nil, &block)
176
+ #end
177
+ end
178
+
179
+ end
180
+
181
+ end
182
+
@@ -0,0 +1,33 @@
1
+ = Confection
2
+
3
+ The idea of confection is a unified configuration management across multiple
4
+ tools for Ruby. The structure of a confection configuration file is very simple.
5
+ It is a ruby script sectioned into named blocks:
6
+
7
+ config :rake do
8
+ # ... rake tasks ...
9
+ end
10
+
11
+ config :vclog do
12
+ # ... configure vclog ...
13
+ end
14
+
15
+ Utilization of the these configurations is strictly up to the consuming
16
+ application. For example, save native support in Rake itself, we can add
17
+ to a Rakefile:
18
+
19
+ require 'confection'
20
+
21
+ confection('rake').call
22
+
23
+ ANALYSIS:
24
+
25
+ config :qed, :coverage, -> do
26
+ name 'Tommy'
27
+ age 42
28
+ end
29
+
30
+ config :qed, :coverage do
31
+ puts "Scripted"
32
+ end
33
+
data/spec/01_dsl.md ADDED
@@ -0,0 +1,69 @@
1
+ # DSL
2
+
3
+ The DSL class handle evaluation of a project configuration file.
4
+
5
+ store = Confection::Store.new
6
+
7
+ dsl = Confection::DSL.new(store)
8
+
9
+ The DSL instance will have a cached binding.
10
+
11
+ #dsl.__binding__ == dsl.__binding__
12
+
13
+ We can use the `#instance_eval` method to evaluate a configuration for our
14
+ demonstration.
15
+
16
+ dsl.instance_eval(<<-HERE)
17
+ config :sample1 do
18
+ "block code"
19
+ end
20
+ HERE
21
+
22
+ Evaluation of a configuration file, populate the Confection.config instance.
23
+
24
+ sample = store.last
25
+ sample.tool #=> :sample1
26
+ sample.profile #=> nil
27
+ sample.class #=> Confection::Config
28
+
29
+ A profile can be used as a means fo defining multiple configuration options
30
+ for a single tool. This can be done by setting the second argument to a Symbol.
31
+
32
+ dsl.instance_eval(<<-HERE)
33
+ config :sample2, :opt1 do
34
+ "block code"
35
+ end
36
+ HERE
37
+
38
+ sample = store.last
39
+ sample.tool #=> :sample2
40
+ sample.profile #=> :opt1
41
+
42
+ Or it can be done by using a `profile` block.
43
+
44
+ dsl.instance_eval(<<-HERE)
45
+ profile :opt1 do
46
+ config :sample2 do
47
+ "block code"
48
+ end
49
+ end
50
+ HERE
51
+
52
+ sample = store.last
53
+ sample.tool #=> :sample2
54
+ sample.profile #=> :opt1
55
+
56
+ Different types of configuration can be defined. For instance, if a multi-line
57
+ string is passed to the `config` method will be a text-based configuration.
58
+
59
+ dsl.instance_eval(<<-HERE)
60
+ config :sample3, %{
61
+ text config
62
+ }
63
+ HERE
64
+
65
+ sample = store.last
66
+ sample.tool #=> :sample3
67
+ sample.profile #=> nil
68
+ sample.to_s.strip.assert == "text config"
69
+
data/spec/02_import.md ADDED
@@ -0,0 +1,52 @@
1
+ # Importing
2
+
3
+ ## Configuration Importing
4
+
5
+ Configurations can be imported from another project
6
+ using the `:from` option.
7
+
8
+ store = Confection::Store.new
9
+
10
+ dsl = Confection::DSL.new(store)
11
+
12
+ dsl.config :qed, :profile=>'example', :from=>'qed'
13
+
14
+ store.size.assert == 1
15
+
16
+ The configuration can also be imported from a different profile.
17
+
18
+ dsl.config :qed, :coverage, :from=>'qed', :profile=>:simplecov
19
+
20
+ store.size.assert == 2
21
+
22
+ Although it will rarely be useful, it may also be imported from another tool.
23
+
24
+ dsl.config :example, :from=>'qed', :tool=>:sample
25
+
26
+ Imported configurations can also be augmented via a block.
27
+
28
+ store = Confection::Store.new
29
+
30
+ dsl = Confection::DSL.new(store)
31
+
32
+ dsl.config :qed, :from=>'qed', :profile=>:simplecov do
33
+ # additional code here
34
+ end
35
+
36
+ store.size.assert == 2
37
+
38
+ Technically this last form just creates two configurations for the same
39
+ tool and profile, but the ultimate effect is the same.
40
+
41
+ ## Script Importing
42
+
43
+ Library files can be imported directly into configuration blocks via the
44
+ `#import` method.
45
+
46
+ dsl.config :example do
47
+ import "fruitbasket/example.rb"
48
+ end
49
+
50
+ This looks up the file via the `finder` gem and then evals it in the context
51
+ of the config block.
52
+
data/spec/03_store.md ADDED
@@ -0,0 +1,20 @@
1
+ ## Store
2
+
3
+ A Confection::Store encapsulates the list of configurations that belong
4
+ to a project.
5
+
6
+ store = Confection::Store.new
7
+
8
+ Only Config instance can be added to a store. Any other type of object
9
+ will raise an error.
10
+
11
+ expect TypeError do
12
+ store << 1
13
+ end
14
+
15
+ We can get a list of profiles for a given tool.
16
+
17
+ profiles = store.profiles(:text)
18
+
19
+ profiles.assert == []
20
+
@@ -0,0 +1,68 @@
1
+ # Controller
2
+
3
+ When working with configurations, Confection wraps configurations in a
4
+ Controller instance.
5
+
6
+ An empty controller can be made simply enough.
7
+
8
+ Confection::Controller.new(self, *[])
9
+
10
+ The #confection method simple calls this with the configs it finds.
11
+
12
+ ctrl = config(:block)
13
+
14
+ Confection::Controller.assert === ctrl
15
+
16
+ A controller will most oftern encapsulate just a sigle configuration,
17
+ but it may contain more if the search parameters used to create it
18
+ returned more than one matching configuration. We can see how many
19
+ configurations the controller is harnessing using the `#size` method.
20
+
21
+ ctrl.size.assert == 1
22
+
23
+ With the controller, we can utilize the configuration(s) it encapsulates
24
+ through the handful of methods it provides for doing so. Probably the
25
+ most useful, which applies to Ruby-based configurations is the `#call`
26
+ methods. This will execute the configuration script in the context
27
+ in which it was defined.
28
+
29
+ result = ctrl.call
30
+
31
+ result.assert == "example block config"
32
+
33
+ Instead of being executed in the context in which a configuration was
34
+ defined, it can be executed in the current scope using the #exec method.
35
+
36
+ result = ctrl.exec
37
+
38
+ result.assert == "example block config"
39
+
40
+ Of course, as this example only outputs a string, we won't notice any
41
+ difference here.
42
+
43
+ Lastly, script based configurations can be executed in the TOPLEVEL
44
+ context by using `#main_exec`, or its alias `#load`.
45
+
46
+ result = ctrl.main_exec
47
+
48
+ result.assert == "example block config"
49
+
50
+ The controller can be converted to a Proc object, in which case the
51
+ underlying execution is equivalent to using `#exec`. This allows
52
+ the procedure to be evaluated in other bindings as needed.
53
+
54
+ proc = ctrl.to_proc
55
+
56
+ result = proc.call
57
+
58
+ result.assert == "example block config"
59
+
60
+ For text configuration, the controller will concat each configuration's
61
+ content.
62
+
63
+ ctrl = config(:text)
64
+
65
+ text = ctrl.to_s
66
+
67
+ text.strip.assert == 'example text config'
68
+
data/spec/05_config.md ADDED
@@ -0,0 +1,99 @@
1
+ # Config Classes
2
+
3
+ There are three classes of configuration: test, data and block. Block
4
+ configurations encapsulate a block of Ruby code. Text configurations
5
+ simply contain a text string --whatever that string may represent.
6
+ Data configuration contantain a table of key-value pairs.
7
+
8
+ ## Block Configuration
9
+
10
+ File configuration come from separate files rather then from definitions
11
+ in a project's master configuration file.
12
+
13
+ config = confection(:block).first
14
+
15
+ Confection::Config.assert === config
16
+
17
+ A Ruby-based configuration file, like our example, can be called via the `#call`
18
+ method. This evaluates the code at the TOPLEVEL, like standard `Kernel.load`
19
+ would.
20
+
21
+ result = config.call
22
+
23
+ result.assert == "example block config"
24
+
25
+ The call can also be converted into a Proc object via `#to_proc`. This uses
26
+ `instance_eval` internally, so that the Proc object can be evaluated in
27
+ any context it may be needed.
28
+
29
+ proc = config.to_proc
30
+
31
+ Proc.assert === proc
32
+
33
+ result = proc.call
34
+
35
+ result.strip.assert == "example block config"
36
+
37
+
38
+ ## Text Configuraiton
39
+
40
+ Text-based configurations
41
+
42
+ config = confection(:text).first
43
+
44
+ Confection::Config.assert === config
45
+
46
+ result = config.to_s
47
+
48
+ result.strip.assert == "example text config"
49
+
50
+ For a text-based configuration `#call` does the same thing as `#to_s`.
51
+
52
+ result = config.call
53
+
54
+ result.strip.assert == "example text config"
55
+
56
+ As with the other configuration classes, we may also convert this call
57
+ into a Proc instance.
58
+
59
+ proc = config.to_proc
60
+
61
+ Proc.assert === proc
62
+
63
+ The configuration object can be copied, with a special `#copy` method
64
+ that accepts option parameters for changing the tool or profile of the copy.
65
+
66
+ alt = config.copy(:profile=>:alt)
67
+
68
+ alt.profile.assert == :alt
69
+
70
+
71
+ ## Data Configuration
72
+
73
+ Data-based configuration.
74
+
75
+ config = confection(:example, :data).first
76
+
77
+ Confection::Config.assert === config
78
+
79
+ result = config.to_h
80
+
81
+ result.assert == {:name=>'Tommy', :age=>42 }
82
+
83
+ For a Data-based configuration `#call` does the same thing as `#to_data`.
84
+
85
+ data = OpenStruct.new
86
+
87
+ result = config.call(data)
88
+
89
+ data.to_h.assert == {:name=>'Tommy', :age=>42 }
90
+
91
+ As with the other configuration classes, we may also convert this call
92
+ into a Proc instance.
93
+
94
+ proc = config.to_proc
95
+
96
+ Proc.assert === proc
97
+
98
+ This just encapsulates the `#to_data` call in a lambda.
99
+
data/spec/06_manage.md ADDED
@@ -0,0 +1,38 @@
1
+ # Manage
2
+
3
+ The Confection module has some convenice class methods for working
4
+ with the configuration of the *current* project --the one relative
5
+ to the current working directory.
6
+
7
+ The current project root directory can be had via the `current_directory`
8
+ method.
9
+
10
+ Confection.current_directory
11
+
12
+ The Project instance can be had via the `current_project` method.
13
+
14
+ project = Confection.current_project
15
+
16
+ Confection::Project.assert === project
17
+
18
+ The configuration properties of the current project can be
19
+ had via the `properties` method.
20
+
21
+ Confection.properties
22
+
23
+ The profile names can be looked up for any given tool via the `profiles`
24
+ method.
25
+
26
+ Confection.profiles(:file)
27
+
28
+ The number of configurations in the current project can be had via
29
+ the `size` method. (This is the number of configurations we have
30
+ defined in our test fixture.)
31
+
32
+ Confection.size.assert == 3
33
+
34
+ And we can loop through each configuration via the `each` method.
35
+
36
+ Confection.each{ |c| c }
37
+
38
+
@@ -0,0 +1 @@
1
+ require 'ae'
@@ -0,0 +1,8 @@
1
+ require 'confection'
2
+
3
+ When 'configuration file `(((\S+)))` containing' do |slots, text|
4
+ Confection.clear!
5
+ fname = [slots].flatten.first # temporary transition to new QED
6
+ File.open(fname, 'w'){ |f| f << text }
7
+ end
8
+
@@ -0,0 +1,10 @@
1
+ # Setup the fixtures.
2
+
3
+ dir = File.dirname(__FILE__) + '/fixture'
4
+ Dir.entries(dir).each do |file|
5
+ next if file == '.' or file == '..'
6
+ path = File.join(dir, file)
7
+ next if File.directory?(path)
8
+ FileUtils.install(path, Dir.pwd)
9
+ end
10
+
@@ -0,0 +1,15 @@
1
+ # exmaple configuration file
2
+
3
+ config :block do
4
+ "example block config"
5
+ end
6
+
7
+ config :text do
8
+ "example text config"
9
+ end
10
+
11
+ config :example, :data do |ex|
12
+ ex.name = 'Tommy'
13
+ ex.age = 42
14
+ end
15
+
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.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-03-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: finder
16
- requirement: &70312239870960 !ruby/object:Gem::Requirement
16
+ requirement: &69827679742240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70312239870960
24
+ version_requirements: *69827679742240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: facets
27
- requirement: &70312239886780 !ruby/object:Gem::Requirement
27
+ requirement: &69827679741700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70312239886780
35
+ version_requirements: *69827679741700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: blankslate
38
- requirement: &70312239886280 !ruby/object:Gem::Requirement
38
+ requirement: &69827679741200 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70312239886280
46
+ version_requirements: *69827679741200
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: detroit
49
- requirement: &70312239885780 !ruby/object:Gem::Requirement
49
+ requirement: &69827679740700 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70312239885780
57
+ version_requirements: *69827679740700
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: qed
60
- requirement: &70312239885280 !ruby/object:Gem::Requirement
60
+ requirement: &69827679740200 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70312239885280
68
+ version_requirements: *69827679740200
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ae
71
- requirement: &70312239884780 !ruby/object:Gem::Requirement
71
+ requirement: &69827679739700 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70312239884780
79
+ version_requirements: *69827679739700
80
80
  description: Confection is a multi-tenant configuration system for Ruby projects.
81
81
  email:
82
82
  - transfire@gmail.com
@@ -92,11 +92,28 @@ files:
92
92
  - lib/confection/basic_object.rb
93
93
  - lib/confection/config.rb
94
94
  - lib/confection/controller.rb
95
+ - lib/confection/core_ext.rb
96
+ - lib/confection/current.rb
95
97
  - lib/confection/dsl.rb
98
+ - lib/confection/hash_builder.rb
99
+ - lib/confection/project.rb
100
+ - lib/confection/store.rb
96
101
  - lib/confection.rb
102
+ - spec/00_concept.md
103
+ - spec/01_dsl.md
104
+ - spec/02_import.md
105
+ - spec/03_store.md
106
+ - spec/04_controller.md
107
+ - spec/05_config.md
108
+ - spec/06_manage.md
109
+ - spec/applique/ae.rb
110
+ - spec/applique/file.rb
111
+ - spec/applique/fixture/confile.rb
112
+ - spec/applique/fixture.rb
97
113
  - LICENSE.txt
98
114
  - HISTORY.md
99
115
  - README.md
116
+ - Confile.rb
100
117
  homepage: http://rubyworks.github.com/confection
101
118
  licenses:
102
119
  - BSD-2-Clause