rc 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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