rc 0.1.1 → 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/lib/c.rb DELETED
@@ -1 +0,0 @@
1
- require 'rc'
data/lib/rc.rb DELETED
@@ -1,10 +0,0 @@
1
- # Runtime Configuration system.
2
- #
3
- module RC
4
- require 'rc/interface'
5
- end
6
-
7
- # Bootstrap properties
8
- RC.bootstrap
9
-
10
- # Copyright (c) 2011 Rubyworks (BSD-2-Clause)
@@ -1,142 +0,0 @@
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
@@ -1,192 +0,0 @@
1
- module RC
2
-
3
- # Configuration
4
- #
5
- class Configuration < Module
6
-
7
- #
8
- # Configuration file pattern. The standard configuration file name is
9
- # `Config.rb`, and that name should be used in most cases. However,
10
- # `.config.rb` can also be use and will take precedence if found.
11
- # Conversely, `config.rb` (lowercase form) can also be used but has
12
- # the least precedence.
13
- #
14
- # Config files looked for in the order or precedence:
15
- #
16
- # * `.config.rb`
17
- # * `Config.rb`
18
- # * `config.rb`
19
- #
20
- CONFIG_FILE = '{.c,C,c}onfig{.rb,}'
21
-
22
- #
23
- # When looking up config file, it one of these is found
24
- # then there is no point to looking further.
25
- #
26
- ROOT_INDICATORS = %w{.git .hg _darcs} #.ruby
27
-
28
- #
29
- # Load configuration file from local project or other gem.
30
- #
31
- # @param options [Hash] Load options.
32
- #
33
- # @option options [String] :from
34
- # Name of gem or library.
35
- #
36
- def self.load(options={})
37
- if from = options[:from]
38
- file = Find.path(CONFIG_FILE, :from=>from).first
39
- else
40
- file = lookup(CONFIG_FILE)
41
- end
42
- new(file)
43
- end
44
-
45
- #
46
- # Initialize new Configuration object.
47
- #
48
- # @param [String] file
49
- # Configuration file (optional).
50
- #
51
- def initialize(file=nil)
52
- @file = file
53
-
54
- @_list = []
55
- @_state = {}
56
-
57
- # TODO: does this rescue make sense here?
58
- begin
59
- import_relative(@file) if @file
60
- rescue => e
61
- raise e if $DEBUG
62
- warn e.message
63
- end
64
- end
65
-
66
- #
67
- # Profile block.
68
- #
69
- # @param [String,Symbol] name
70
- # A profile name.
71
- #
72
- def profile(name, &block)
73
- raise SyntaxError, "nested profile sections" if @_state[:profile]
74
- original_state = @_state.dup
75
- @_state[:profile] = name.to_s
76
- instance_eval(&block)
77
- @_state = original_state
78
- end
79
-
80
- #
81
- # Configure a tool.
82
- #
83
- # @param [Symbol] tool
84
- # The name of the tool to configure.
85
- #
86
- # @param [Hash] opts
87
- # Configuration options.
88
- #
89
- # @options opts [String] :from
90
- # Library from which to extract configuration.
91
- #
92
- # @example
93
- # profile :coverage do
94
- # config :qed, :from=>'qed'
95
- # end
96
- #
97
- # @todo Clean this code up.
98
- #
99
- def config(tool, *args, &block)
100
- options = (Hash===args.last ? args.pop : {})
101
-
102
- # @todo Might we have an option to lockdown tool
103
- # So that we do without ToolConfiguration?
104
-
105
- case args.first
106
- when Symbol
107
- profile = args.shift
108
- when String
109
- profile = args.shift unless args.first.index("\n")
110
- end
111
-
112
- data = args.shift
113
- raise ArgumentError, "must use data or block, not both" if data && block
114
- if data
115
- data = data.tabto(0)
116
- block = Proc.new do
117
- YAML.load(data)
118
- end
119
- end
120
-
121
- from = options[:from]
122
-
123
- raise ArgumentError, "too many arguments" if args.first
124
- raise SyntaxError, "nested profile sections" if profile && @_state[:profile]
125
- #raise ArgumentError, "use block or :from setting" if options[:from] && block
126
-
127
- profile = @_state[:profile] unless profile
128
-
129
- if from
130
- from_config = RC.configuration(from)
131
- from_tool = options[:tool] || tool
132
- from_profile = options[:profile] || profile
133
- from_config.each do |c|
134
- if c.match?(from_tool, from_profile)
135
- @_list << Config.new(tool, profile, &c)
136
- end
137
- end
138
-
139
- return unless block
140
- end
141
-
142
- @_list << Config.new(tool, profile, &block)
143
- end
144
-
145
- #
146
- # @return [Hash] Defined configurations.
147
- #
148
- def configurations
149
- @_list
150
- end
151
-
152
- #
153
- # @return [ToolConfiguration] Subset of Configuration.
154
- #
155
- def [](tool)
156
- ToolConfiguration.new(tool, self)
157
- end
158
-
159
- # Configuration is Enumerable.
160
- include Enumerable
161
-
162
- #
163
- def each(&block)
164
- @_list.each(&block)
165
- end
166
-
167
- #
168
- def size
169
- @_list.size
170
- end
171
-
172
- private
173
-
174
- #
175
- # Search upward from working directory.
176
- #
177
- def self.lookup(glob, flags=0)
178
- pwd = File.expand_path(Dir.pwd)
179
- home = File.expand_path('~')
180
- while pwd != '/' && pwd != home
181
- if file = Dir.glob(File.join(pwd, glob), flags).first
182
- return file
183
- end
184
- break if ROOT_INDICATORS.any?{ |r| File.exist?(File.join(pwd, r)) }
185
- pwd = File.dirname(pwd)
186
- end
187
- return nil
188
- end
189
-
190
- end
191
-
192
- end
@@ -1,49 +0,0 @@
1
- module Kernel
2
- #
3
- # Evaluate script directly into current scope.
4
- #
5
- def import(feature)
6
- file = Find.load_path(feature).first
7
- raise LoadError, "no such file -- #{feature}" unless file
8
- instance_eval(::File.read(file), file) if file
9
- end
10
-
11
- #
12
- # Evaluate script directly into current scope.
13
- #
14
- def import_relative(file)
15
- raise LoadError, "no such file -- #{file}" unless File.file?(file)
16
- instance_eval(::File.read(file), file) if file
17
- end
18
- end
19
-
20
- class Hash
21
- def to_h
22
- dup #rehash
23
- end unless method_defined?(:to_h)
24
- end
25
-
26
- class String
27
- def tabto(n)
28
- if self =~ /^( *)\S/
29
- indent(n - $1.length)
30
- else
31
- self
32
- end
33
- end unless method_defined?(:tabto)
34
-
35
- def indent(n, c=' ')
36
- if n >= 0
37
- gsub(/^/, c * n)
38
- else
39
- gsub(/^#{Regexp.escape(c)}{0,#{-n}}/, "")
40
- end
41
- end unless method_defined?(:indent)
42
- end
43
-
44
- #class Symbol
45
- # def /(other)
46
- # "#{self}/#{other}".to_sym
47
- # end
48
- #end
49
-
@@ -1,163 +0,0 @@
1
- module RC
2
- # External requirements.
3
- require 'yaml'
4
- require 'finder'
5
-
6
- # Internal requirements.
7
- require 'rc/core_ext'
8
- require 'rc/config'
9
- require 'rc/configuration'
10
- require 'rc/tool_configuration'
11
- require 'rc/properties'
12
-
13
- #
14
- # Configuration file pattern. The standard configuration file name is
15
- # `Config.rb`, and that name should be used in most cases. However,
16
- # `.config.rb` can also be use and will take precedence if found.
17
- # Conversely, `config.rb` (lowercase form) can also be used but has
18
- # the least precedence.
19
- #
20
- # Config files looked for in the order or precedence:
21
- #
22
- # * `.config.rb`
23
- # * `Config.rb`
24
- # * `config.rb`
25
- #
26
- FILE_PATTERN = '{.c,C,c}onfig{.rb,}'
27
-
28
- #
29
- def self.cache
30
- @cache ||= {}
31
- end
32
-
33
- #
34
- def self.clear!
35
- @cache = {}
36
- end
37
-
38
- #
39
- def self.configuration(gem=nil)
40
- key = gem ? gem.to_s : nil #Dir.pwd
41
- cache[key] ||= Configuration.load(:from=>gem)
42
- end
43
-
44
- #
45
- # @return [Array] List of profiles for given `tool`.
46
- #
47
- def self.profiles(tool, options={})
48
- tool = tool.to_s
49
- gem = options[:from]
50
- configuration(gem).map{ |c| c.tool.to_s }
51
- end
52
-
53
- #
54
- # Get current tool.
55
- #
56
- def self.current_tool
57
- File.basename(ENV['tool'] || $0)
58
- end
59
-
60
- #
61
- # Set current tool.
62
- #
63
- def self.current_tool=(tool)
64
- ENV['tool'] = tool.to_s
65
- end
66
-
67
- #
68
- # Get current profile.
69
- #
70
- def self.current_profile
71
- ENV['profile']
72
- end
73
-
74
- #
75
- # Set current profile.
76
- #
77
- def self.current_profile=(profile)
78
- if profile
79
- ENV['profile'] = profile.to_s
80
- else
81
- ENV['profile'] = nil
82
- end
83
- end
84
-
85
- #
86
- # Project properties.
87
- #
88
- def self.properties
89
- $properties ||= Properties.new
90
- end
91
-
92
- #
93
- # Get/set configuration processor. Tools can use this
94
- # to gain control over the configuration procedure.
95
- #
96
- # The block should take a single argument of the current
97
- # Configuration.
98
- #
99
- # This might be used to save the configuration for
100
- # a later execution, or to evaluate the procedures
101
- # in a special scope, or both.
102
- #
103
- # Keep in mind that if configurations are evaluated in
104
- # a different scope, they may not be able to utilize
105
- # any shared methods defined in the config file.
106
- #
107
- # @example
108
- # RC.processor('qed') do |config|
109
- # if i = ARGV.index('--profile') || ARGV.index('-p')
110
- # ENV['profile'] = ARGV[i+1]
111
- # end
112
- # RC.configure
113
- # end
114
- #
115
- def self.processor(tool, &block)
116
- @processors ||= {}
117
- @processors[tool.to_s] = block if block
118
- @processors[tool.to_s]
119
- end
120
-
121
- #
122
- # Setup configuration.
123
- #
124
- def self.configure(options={})
125
- tool = options[:tool] || current_tool
126
- profile = options[:profile] || current_profile
127
-
128
- configuration.each do |c|
129
- c.call if c.match?(tool, profile)
130
- end
131
- end
132
-
133
- #
134
- # Start RC.
135
- #
136
- def self.bootstrap
137
- properties # prime global properties
138
-
139
- tweak = File.join(File.dirname(__FILE__), 'tweaks', current_tool + '.rb')
140
- if File.exist?(tweak)
141
- require tweak
142
- else
143
- begin
144
- require current_tool
145
- rescue LoadError
146
- end
147
- end
148
-
149
- if proc = processor(current_tool)
150
- tool_config = ToolConfiguration.new(current_tool, configuration)
151
- proc.call(tool_config)
152
- else
153
- configure
154
- end
155
- end
156
-
157
- # @todo: I'm sure this, #bootstrap and #processor can be simplifed.
158
- def self.run(tool, &block)
159
- processor(tool, &block)
160
- require 'rc'
161
- end
162
-
163
- end