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)


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

def autoconfig?
  @autoconfig
end

#autoconfigureObject (protected)



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.



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.



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:



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.



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:



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.



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.



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.



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.



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.



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.



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.



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.



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')


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.



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')


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)



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.



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

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