rc 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +51 -0
- data/.yardopts +8 -0
- data/Config.rb +68 -0
- data/HISTORY.md +10 -0
- data/LICENSE.txt +27 -0
- data/NOTES.md +38 -0
- data/README.md +182 -0
- data/lib/c.rb +1 -0
- data/lib/rc.rb +10 -0
- data/lib/rc/config.rb +142 -0
- data/lib/rc/configuration.rb +192 -0
- data/lib/rc/core_ext.rb +49 -0
- data/lib/rc/interface.rb +163 -0
- data/lib/rc/properties.rb +44 -0
- data/lib/rc/tool_configuration.rb +54 -0
- data/lib/rc/tweaks/rake.rb +28 -0
- data/spec/00_concept.md +22 -0
- data/spec/01_config.md +14 -0
- data/spec/02_configuration.md +65 -0
- data/spec/03_import.md +48 -0
- data/spec/06_interface.md +36 -0
- data/spec/applique/ae.rb +1 -0
- data/spec/applique/file.rb +8 -0
- data/spec/applique/fixture.rb +10 -0
- data/spec/applique/fixture/config.rb +16 -0
- metadata +121 -0
data/.ruby
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
---
|
2
|
+
source:
|
3
|
+
- var
|
4
|
+
authors:
|
5
|
+
- name: Trans
|
6
|
+
email: transfire@gmail.com
|
7
|
+
copyrights:
|
8
|
+
- holder: Rubyworks
|
9
|
+
year: '2011'
|
10
|
+
license: BSD-2-Clause
|
11
|
+
requirements:
|
12
|
+
- name: finder
|
13
|
+
- name: detroit
|
14
|
+
groups:
|
15
|
+
- build
|
16
|
+
development: true
|
17
|
+
- name: qed
|
18
|
+
groups:
|
19
|
+
- test
|
20
|
+
development: true
|
21
|
+
- name: ae
|
22
|
+
groups:
|
23
|
+
- test
|
24
|
+
development: true
|
25
|
+
dependencies: []
|
26
|
+
alternatives: []
|
27
|
+
conflicts: []
|
28
|
+
repositories:
|
29
|
+
- uri: git://github.com/rubyworks/rc.git
|
30
|
+
scm: git
|
31
|
+
name: upstream
|
32
|
+
resources:
|
33
|
+
home: http://rubyworks.github.com/rc
|
34
|
+
docs: http://rubydoc.info/gems/rc/frames
|
35
|
+
code: http://github.com/rubyworks/rc
|
36
|
+
mail: http://groups.google.com/group/rubyworks-mailinglist
|
37
|
+
chat: http://chat.us.freenode.net/rubyworks
|
38
|
+
extra: {}
|
39
|
+
load_path:
|
40
|
+
- lib
|
41
|
+
name: rc
|
42
|
+
title: RC
|
43
|
+
revision: 0
|
44
|
+
created: '2011-11-06'
|
45
|
+
summary: Multi-tenant configuration for Ruby.
|
46
|
+
version: 0.1.1
|
47
|
+
description: ! "RC is a multi-tenant configuration system for Ruby projects.\nIt is
|
48
|
+
a spin-off of the original Confection project with\na simplifed overall design and
|
49
|
+
the ability to work with \nalmost any Ruby-based command line tool."
|
50
|
+
organization: Rubyworks
|
51
|
+
date: '2012-04-09'
|
data/.yardopts
ADDED
data/Config.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Detroit assembly.
|
5
|
+
#
|
6
|
+
config :detroit do
|
7
|
+
service :email do |s|
|
8
|
+
s.mailto = ['ruby-talk@ruby-lang.org',
|
9
|
+
'rubyworks-mailinglist@googlegroups.com']
|
10
|
+
end
|
11
|
+
|
12
|
+
service :gem do |s|
|
13
|
+
s.gemspec = 'pkg/rc.gemspec'
|
14
|
+
end
|
15
|
+
|
16
|
+
service :github do |s|
|
17
|
+
s.folder = 'web'
|
18
|
+
end
|
19
|
+
|
20
|
+
service :dnote do |s|
|
21
|
+
s.title = 'Source Notes'
|
22
|
+
s.output = 'log/notes.html'
|
23
|
+
end
|
24
|
+
|
25
|
+
service :locat do |s|
|
26
|
+
s.output = 'log/locat.html'
|
27
|
+
end
|
28
|
+
|
29
|
+
service :vclog do |s|
|
30
|
+
s.output = ['log/history.html',
|
31
|
+
'log/changes.html']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# QED test coverage report using SimpleCov.
|
37
|
+
#
|
38
|
+
# Use `$properties.coverage_folder` to set directory in which to store
|
39
|
+
# coverage report this defaults to `log/coverage`.
|
40
|
+
#
|
41
|
+
config :qed, :cov do
|
42
|
+
require 'simplecov'
|
43
|
+
|
44
|
+
dir = $properties.coverage_folder
|
45
|
+
|
46
|
+
SimpleCov.start do
|
47
|
+
coverage_dir(dir || 'log/coverage')
|
48
|
+
#add_group "Label", "lib/qed/directory"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Rake tasks
|
54
|
+
#
|
55
|
+
config :rake do
|
56
|
+
desc 'run unit tests'
|
57
|
+
task :test do
|
58
|
+
puts "boo"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Example configuration.
|
64
|
+
#
|
65
|
+
config :example do
|
66
|
+
puts "Configuration Example!"
|
67
|
+
end
|
68
|
+
|
data/HISTORY.md
ADDED
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/NOTES.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Developer Notes
|
2
|
+
|
3
|
+
|
4
|
+
## 2012-04-07 | Toplevel DSLs
|
5
|
+
|
6
|
+
If it were not for Ruby's mixing toplevel definitions into all
|
7
|
+
objects, I likely would have used the simpler design of
|
8
|
+
just loading the config files directly (via `#load`).
|
9
|
+
|
10
|
+
It's dissapointing that Ruby continues to insist on mixing toplevel
|
11
|
+
methods into all objects. It would be much easier to write script
|
12
|
+
DSLs if it did not, saving a good bit of code. In this case, for
|
13
|
+
instance, I probably could have shaved off 20% to 40% of the
|
14
|
+
current code --neither the Config or the Configuration class
|
15
|
+
would be needed, and the parser could be stripped down to just
|
16
|
+
enough code to collect a list of profiles since that is all it
|
17
|
+
would really be useful for then.
|
18
|
+
|
19
|
+
|
20
|
+
## 2012-04-05 | Multiple Configurations
|
21
|
+
|
22
|
+
Should multiple definitions for the same tool and profile be
|
23
|
+
allowed?
|
24
|
+
|
25
|
+
config :qed, :cov do
|
26
|
+
...
|
27
|
+
end
|
28
|
+
|
29
|
+
config :qed, :cov do
|
30
|
+
...
|
31
|
+
end
|
32
|
+
|
33
|
+
configuration.invoke(:qed, :cov)
|
34
|
+
|
35
|
+
Should both definitions be called, or just the later? I have decide
|
36
|
+
that both will be called. If this becomes a concern, I may add a `#reconfig`
|
37
|
+
method which would first clear the list of matching configurations.
|
38
|
+
|
data/README.md
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
# RC - Runtime Configuration
|
2
|
+
|
3
|
+
[Homepage](http://rubyworks.github.com/rc) /
|
4
|
+
[Source Code](http://github.com/rubyworks/rc) /
|
5
|
+
[Report Issue](http://github.com/rubyworks/rc/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/rc.png)](http://travis-ci.org/rubyworks/rc)
|
10
|
+
|
11
|
+
|
12
|
+
## Description
|
13
|
+
|
14
|
+
RC, short for *Runtime Configuration*, is multi-tenant configuration system
|
15
|
+
for Ruby tools. If was designed to facilitate Ruby-based configuration for
|
16
|
+
multiple tools in a single file. It is extremely simple, and univerally applicable
|
17
|
+
which makes it easy to understand and flexible in use.
|
18
|
+
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
To use RC via tools that support RC directly, there is nothing you need to
|
23
|
+
install. Installing the said tool should install `rc` via a dependency and
|
24
|
+
load `rc` when the tool is used.
|
25
|
+
|
26
|
+
To use RC with tools that don't provide direct support, first install RC
|
27
|
+
in the usual manner via RubyGems.
|
28
|
+
|
29
|
+
$ gem install rc
|
30
|
+
|
31
|
+
Then add `-rc` to your system's `RUBYOPT` environment variable.
|
32
|
+
|
33
|
+
$ export RUBYOPT='-rc'
|
34
|
+
|
35
|
+
You will want to add that to your `.bashrc`, `.profile` or equivalent configuration
|
36
|
+
script.
|
37
|
+
|
38
|
+
|
39
|
+
## Instruction
|
40
|
+
|
41
|
+
To use RC in a project create a master configuration file for the project called
|
42
|
+
`Config.rb`. The file can have any name that matches `.config.rb`, `Config.rb`
|
43
|
+
or `config.rb`, in that order of precedence. In this file add configuration
|
44
|
+
blocks by name of the commandline tool. For example, let's demonstrate how we could
|
45
|
+
use this to configure Rake tasks.
|
46
|
+
|
47
|
+
$ cat Config.rb
|
48
|
+
config :rake do
|
49
|
+
desc 'generate yard docs'
|
50
|
+
task :yard do
|
51
|
+
sh 'yard'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Now when `rake` is run the tasks defined in this configuration will be available.
|
56
|
+
|
57
|
+
You might wonder why anyone would do this. That's where the *multi-tenancy*
|
58
|
+
comes into play. Let's add another configuration.
|
59
|
+
|
60
|
+
$ cat Config.rb
|
61
|
+
title = "MyApp"
|
62
|
+
|
63
|
+
config :rake do
|
64
|
+
desc 'generate yard docs'
|
65
|
+
task :yard do
|
66
|
+
sh "yard doc --title #{title}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
config :qedoc do |doc|
|
71
|
+
doc.title = "#{title} Demos"
|
72
|
+
end
|
73
|
+
|
74
|
+
Now we have configuration for both the rake tool and the qedoc tool in
|
75
|
+
a single file. Thus we gain the advantage of reducing the file count of our
|
76
|
+
project while pulling our tool configurations together into one place.
|
77
|
+
Moreover, these configurations can potentially share settings as demonstrated
|
78
|
+
here via the `title` local variable.
|
79
|
+
|
80
|
+
RC also supports profiles, either via a `profile` block:
|
81
|
+
|
82
|
+
profile :cov
|
83
|
+
config :qed do
|
84
|
+
require 'simplecov'
|
85
|
+
...
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Or via a second config argument:
|
90
|
+
|
91
|
+
config :qed, :cov do
|
92
|
+
require 'simplecov'
|
93
|
+
...
|
94
|
+
end
|
95
|
+
|
96
|
+
When utilizing the tool, set the profile via an environment variable.
|
97
|
+
|
98
|
+
$ profile='cov' qed
|
99
|
+
|
100
|
+
Some tools that support RC out-of-the-box, may support a profile command
|
101
|
+
line option for specifying the profile.
|
102
|
+
|
103
|
+
$ qed -p cov
|
104
|
+
|
105
|
+
Still other tools might utilize profiles to a more specific purpose of
|
106
|
+
the tool at hand. Consult the tool's documentation for details.
|
107
|
+
|
108
|
+
|
109
|
+
## Qualifications
|
110
|
+
|
111
|
+
RC can be used with any Ruby-based commandline tool that can be required by
|
112
|
+
the same name as the tool, e.g. `rake` can be required via `require 'rake'`,
|
113
|
+
and there exists some means of configuring the tool via a toplevel/global
|
114
|
+
interface, or the tool has been customized to directly support RC.
|
115
|
+
|
116
|
+
|
117
|
+
## Customization
|
118
|
+
|
119
|
+
A tool can provide dedicated support for RC by loading the `rc/interface` script
|
120
|
+
and defining a `run` procedure. For example, the `detroit` project defines:
|
121
|
+
|
122
|
+
require 'rc/interface'
|
123
|
+
|
124
|
+
RC.run('detroit') do |configs|
|
125
|
+
Detroit.rc_configs = configs
|
126
|
+
end
|
127
|
+
|
128
|
+
When `detroit` gets around to loading a project's build assemblies, it will
|
129
|
+
check this setting and evaluate the configs via Detroit's confgiruation DSL.
|
130
|
+
|
131
|
+
Some tools may also need to run preconfiguration code before allowing RC to
|
132
|
+
process configuration. Probably the most common use for this is to parse
|
133
|
+
commandline arguments for a profile setting as an alternative to normal
|
134
|
+
environment variable.
|
135
|
+
|
136
|
+
RC.run('qed') do
|
137
|
+
if i = ARGV.index('--profile') || ARGV.index('-p')
|
138
|
+
ENV['profile'] = ARGV[i+1]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
The `run` method forces the loading of `rc`, which triggers tool configuration,
|
143
|
+
regardless of whether the end-user has set `RUBYOPT="-rc"`. If you wish for your
|
144
|
+
tool to only work when `RUBYOPT` is set, then define `RC.processor` instead of
|
145
|
+
`run`.
|
146
|
+
|
147
|
+
|
148
|
+
## Dependencies
|
149
|
+
|
150
|
+
### Libraries
|
151
|
+
|
152
|
+
RC depends on the [Finder](http://rubyworks.github.com/finder) library
|
153
|
+
to provide reliable load path and Gem searching. This is used when importing
|
154
|
+
configurations from other projects.
|
155
|
+
|
156
|
+
### Core Extensions
|
157
|
+
|
158
|
+
RC uses two core extensions, `#to_h`, which applies to a few different
|
159
|
+
classes, and `String#tabto`. These are *copied* from
|
160
|
+
[Ruby Facets](http://rubyworks.github.com/facets) to ensure a high
|
161
|
+
standard of interoperability.
|
162
|
+
|
163
|
+
Both of these methods have been suggested for inclusion in Ruby proper.
|
164
|
+
Please head over to Ruby Issue Tracker and add your support.
|
165
|
+
|
166
|
+
* http://bugs.ruby-lang.org/issues/749
|
167
|
+
* http://bugs.ruby-lang.org/issues/6056
|
168
|
+
|
169
|
+
|
170
|
+
## Release Notes
|
171
|
+
|
172
|
+
Please see HISTORY.rdoc file.
|
173
|
+
|
174
|
+
|
175
|
+
## Copyrights
|
176
|
+
|
177
|
+
Copyright (c) 2011 Rubyworks
|
178
|
+
|
179
|
+
Confection is distributable in accordance with the **BSD-2-Clause** license.
|
180
|
+
|
181
|
+
See LICENSE.txt file for details.
|
182
|
+
|
data/lib/c.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rc'
|
data/lib/rc.rb
ADDED
data/lib/rc/config.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
module RC
|
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, &block)
|
13
|
+
self.tool = tool
|
14
|
+
self.profile = profile
|
15
|
+
self.block = block
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# The name of tool being configured.
|
20
|
+
#
|
21
|
+
attr :tool
|
22
|
+
|
23
|
+
#
|
24
|
+
# Change the tool name. Note, this will rarely be used since,
|
25
|
+
# generally speaking, configurations tend to be very tool
|
26
|
+
# specific.
|
27
|
+
#
|
28
|
+
def tool=(name)
|
29
|
+
@tool = name.to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# The name of the profile to which this configuration belongs.
|
34
|
+
#
|
35
|
+
attr :profile
|
36
|
+
|
37
|
+
#
|
38
|
+
# Change the profile name.
|
39
|
+
#
|
40
|
+
def profile=(name)
|
41
|
+
@profile = name.to_sym if name
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Most configuration are scripted. In thos cases the
|
46
|
+
# `@block` attributes holds the Proc instance, otherwise
|
47
|
+
# it is `nil`.
|
48
|
+
#
|
49
|
+
attr :block
|
50
|
+
|
51
|
+
#
|
52
|
+
# Set the configuration procedure.
|
53
|
+
#
|
54
|
+
# @param [Proc] procedure
|
55
|
+
# The configuration procedure.
|
56
|
+
#
|
57
|
+
def block=(block)
|
58
|
+
@block = block.to_proc
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# The arity of the configuration procedure.
|
63
|
+
#
|
64
|
+
# @return [Fixnum] number of arguments
|
65
|
+
#
|
66
|
+
def arity
|
67
|
+
@block ? @block.arity : 0
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Call the configuration procedure.
|
72
|
+
#
|
73
|
+
def call(*args)
|
74
|
+
block.call(*args)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Returns underlying block.
|
79
|
+
#
|
80
|
+
def to_proc
|
81
|
+
block
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
## Convert block into a Hash.
|
86
|
+
##
|
87
|
+
## @return [Hash]
|
88
|
+
##
|
89
|
+
#def to_h
|
90
|
+
# (@value || HashBuilder.new(&@block)).to_h
|
91
|
+
#end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Copy the configuration with alterations.
|
95
|
+
#
|
96
|
+
# @param [Hash] alt
|
97
|
+
# Alternate values for configuration attributes.
|
98
|
+
#
|
99
|
+
# @return [Config] copied config
|
100
|
+
#
|
101
|
+
def copy(alt={})
|
102
|
+
copy = dup
|
103
|
+
alt.each do |k,v|
|
104
|
+
copy.__send__("#{k}=", v)
|
105
|
+
end
|
106
|
+
copy
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
#
|
111
|
+
#
|
112
|
+
def match?(tool, profile)
|
113
|
+
tool = tool.to_sym
|
114
|
+
profile = profile.to_sym if profile
|
115
|
+
|
116
|
+
self.tool == tool && self.profile == profile
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# Does the given `tool` match the config's tool?
|
121
|
+
#
|
122
|
+
def tool?(tool)
|
123
|
+
self.tool == tool.to_sym
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Does the given `profile` match the config's profile?
|
128
|
+
#
|
129
|
+
def profile?(profile)
|
130
|
+
self.profile == profile.to_sym
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
## Ruby 1.9 defines #inspect as #to_s, ugh.
|
135
|
+
##
|
136
|
+
#def inspect
|
137
|
+
# "#<#{self.class.name}:#{object_id} @tool=%s @profile=%s>" % [tool.inspect, profile.inspect]
|
138
|
+
#end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|