Module: RC::Interface

Included in:
RC
Defined in:
lib/rc/interface.rb

Overview

The Interface module extends the RC module.

A tool can control RC configuration by loading ‘rc/api` and calling the `RC.configure` method with a block that handles the configuration for the feature as provided by a project’s config file.

The block will often need to be conditioned on the current profile and/or the the current command. This is easy enough to do with #profile? and #command? methods.

For example, is RSpec wanted to support RC out-of-the-box, the code would look something like:

require 'rc/api'

RC.configure('rspec') do |config|
  if config.profile?
    RSpec.configure(&config)
  end
end

Constant Summary collapse

TWEAKS_DIR =

The tweaks directory is where special augementation script reside the are used to adjust behavior of certain popular tools to work with RC that would not otherwise do so.

File.dirname(__FILE__) + '/tweaks'

Instance Method Summary collapse

Instance Method Details

#autoconfig?Boolean

Returns:

  • (Boolean)
[View source]

251
252
253
# File 'lib/rc/interface.rb', line 251

def autoconfig?
  @autoconfig
end

#autoconfigureObject (protected)

[View source]

260
261
262
263
# File 'lib/rc/interface.rb', line 260

def autoconfigure
  @autoconfig = true
  configure_tool(current_tool)
end

#bootstrapObject (private)

Setup the system.

[View source]

289
290
291
292
293
294
295
# File 'lib/rc/interface.rb', line 289

def bootstrap
  @bootstrap ||= (
    properties  # prime global properties
    bootstrap_require
    true
  )
end

#bootstrap_requireObject (private)

Tap into require via loaded hook. The hook is only triggered on #require, not #load.

[View source]

301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/rc/interface.rb', line 301

def bootstrap_require
  def RC.required(feature)
    config = RC.configuration[feature]
    if config
      config.each do |config|
        next unless config.apply_to_feature?
        config.call
      end
    end
    super(feature) if defined?(super)
  end
end

#cacheHash

Library configuration cache. Since configuration can be imported from other libraries, we keep a cache for each library.

Returns:

[View source]

55
56
57
# File 'lib/rc/interface.rb', line 55

def cache
  @cache ||= {}
end

#clear!Object

Clear the library configuration cache. This is mostly used for testing.

[View source]

63
64
65
# File 'lib/rc/interface.rb', line 63

def clear!
  @cache = {}
end

#configuration(gem = nil) ⇒ Configuration

Load library configuration for a given gem. If no gem is specified then the current project’s configuration is used.

Returns:

[View source]

73
74
75
76
# File 'lib/rc/interface.rb', line 73

def configuration(gem=nil)
  key = gem ? gem.to_s : nil #Dir.pwd
  cache[key] ||= Configuration.load(:from=>gem)
end

#configure(tool = nil) ⇒ Object

Configure current tool.

[View source]

158
159
160
# File 'lib/rc/interface.rb', line 158

def configure(tool=nil)
  configure_tool(tool || RC.current_tool)
end

#configure_tool(tool) ⇒ Object (private)

Configure current commnad.

[View source]

270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/rc/interface.rb', line 270

def configure_tool(tool)
  tweak(tool)

  configs = RC.configuration[tool]

  return unless configs

  configs.each do |config|
    next unless config.apply_to_tool?
    config.require_feature if autoconfig?
    setup = setup(tool)
    next if setup == false  # deactivated
    setup ? setup.call(config) : config.call
  end
end

#current_profileObject

Get current profile.

[View source]

128
129
130
# File 'lib/rc/interface.rb', line 128

def current_profile
  ENV['profile'] || ENV['p'] || 'default'
end

#current_profile=(profile) ⇒ Object

Set current profile.

[View source]

135
136
137
138
139
140
141
# File 'lib/rc/interface.rb', line 135

def current_profile=(profile)
  if profile
    ENV['profile'] = profile.to_s
  else
    ENV['profile'] = nil
  end
end

#current_toolObject Also known as: current_command

TODO:

Not so sure ‘ENV` is a good idea.

Get current tool.

[View source]

110
111
112
# File 'lib/rc/interface.rb', line 110

def current_tool
  File.basename(ENV['tool'] || $0)
end

#current_tool=(tool) ⇒ Object Also known as: current_command=

Set current tool.

[View source]

119
120
121
# File 'lib/rc/interface.rb', line 119

def current_tool=(tool)
  ENV['tool'] = tool.to_s
end

#define_config(tool, options = {}, &block) ⇒ Object Also known as: setup

Define a custom configuration handler.

If the current tool matches the given tool, and autoconfiguration is not being used, then configuration is applied immediately.

[View source]

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/rc/interface.rb', line 168

def define_config(tool, options={}, &block)
  tool = tool.to_s

  @setup ||= {}

  if block
    @setup[tool] = Setup.new(tool, options, &block)

    # REMOVED: Doing this automatically made it impossible for tools to set the profile.
    #if tool == current_tool
    #  configure_tool(tool) unless autoconfig?
    #end
  end     

  @setup[tool]
end

#profile_names(tool = nil, opts = {}) ⇒ Object

Return a list of names of defined profiles for a given tool.

Examples:

profile_names(:qed)

Parameters:

  • tool (#to_sym) (defaults to: nil)

    Tool for which lookup defined profiles. If none given the current tool is used.

  • opts (Hash) (defaults to: {})

    Options for looking up profiles.

Options Hash (opts):

  • :gem (#to_s)

    Name of library from which to load the configuration.

[View source]

94
95
96
97
98
99
100
101
102
103
# File 'lib/rc/interface.rb', line 94

def profile_names(tool=nil, opts={})
  if Hash === tool
    opts, tool = tool, nil
  end

  tool = tool || current_tool
  gem  = opts[:from]

  configuration(gem).profile_names(tool)
end

#profile_switch(command, *switches) ⇒ Object

Set current profile via ARGV switch. This is done immediately, setting ‘ENV` to the switch value if this setup is for the current commandline tool. The reason it is done immediately, rather than assigning it in bootstrap, is b/c option parsers somtimes consume ARGV as they parse it, and by then it would too late.

Examples:

RC.profile_switch('qed', '-p', '--profile')
[View source]

211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rc/interface.rb', line 211

def profile_switch(command, *switches)
  return unless command.to_s == RC.current_command

  switches.each do |switch, envar|
    if index = ARGV.index(switch)
      self.current_profile = ARGV[index+1]
    elsif arg = ARGV.find{ |a| a =~ /#{switch}=(.*?)/ }
      value = $1
      value = value[1..-2] if value.start_with?('"') && value.end_with?('"')
      value = value[1..-2] if value.start_with?("'") && value.end_with?("'")
      self.currrent_profile = value
    end
  end
end

#propertiesObject

Properties of the current project. These can be used in a project’s config file to make configuration more interchangeable. Presently project properties are gathered from .index YAML or .gemspec.

It’s important to note that properties are not per-gem. Rather they are global and belong only the current project.

[View source]

151
152
153
# File 'lib/rc/interface.rb', line 151

def properties
  $properties ||= Properties.new
end

#switch(command, switches = {}) ⇒ Object

Set enviroment variable(s) to command line switch value(s). This is a more general form of #profile_switch and will probably not get much use in this context.

Examples:

RC.switch('qed', '-p'=>'profile', '--profile'=>'profile')
[View source]

233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/rc/interface.rb', line 233

def switch(command, switches={})
  return unless command.to_s == RC.current_command

  switches.each do |switch, envar|
    if index = ARGV.index(switch)
      ENV[envar] = ARGV[index+1]
    elsif arg = ARGV.find{ |a| a =~ /#{switch}=(.*?)/ }
      value = $1
      value = value[1..-2] if value.start_with?('"') && value.end_with?('"')
      value = value[1..-2] if value.start_with?("'") && value.end_with?("'")
      ENV[envar] = value
    end
  end
end

#tweak(command) ⇒ Object (private)

[View source]

317
318
319
320
321
322
# File 'lib/rc/interface.rb', line 317

def tweak(command)
  tweak = File.join(TWEAKS_DIR, command + '.rb')
  if File.exist?(tweak)
    require tweak
  end
end

#undefine_config(tool) ⇒ Object Also known as: unset

Remove a configuration setup.

NOTE: This is probably a YAGNI.

[View source]

195
196
197
# File 'lib/rc/interface.rb', line 195

def undefine_config(tool)
  @setup[tool.to_s] = false
end