module Courtier::Interface

The Interface module extends Courtier module.

A tool can control Courtier configuration by loading ‘courtier` and calling the toplevel `court` or `Courtier.setup` 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 then current command. This is easy enough to do with profile? and command? methods.

require 'courtier'

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

Constants

FILE_PATTERN

Configuration file pattern. The standard configuration file name is ‘Config.rb`, and that name should be used in most cases. However, `.config.rb` can also be use and will take precedence if found. Conversely, `config.rb` (lowercase form) can also be used but has the least precedence.

Config files looked for in the order or precedence:

* `.config.rb` or `.confile.rb`
* `Config.rb`  or `Confile.rb`
* `config.rb`  or `confile.rb`

Yes, there are really too many choices here, but we haven’t been able to settle on a smaller list just yet. Please come argue with us about what’s best.

TWEAKS_DIR

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

Public Instance Methods

cache() click to toggle source

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

# File lib/courtier/interface.rb, line 65
def cache
  @cache ||= {}
end
clear!() click to toggle source

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

# File lib/courtier/interface.rb, line 73
def clear!
  @cache = {}
end
configuration(gem=nil) click to toggle source

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

@return [Configuration]

# File lib/courtier/interface.rb, line 83
def configuration(gem=nil)
  key = gem ? gem.to_s : nil #Dir.pwd
  cache[key] ||= Configuration.load(:from=>gem)
end
configure(tool, options={}, &setup) click to toggle source
# File lib/courtier/interface.rb, line 233
def configure(tool, options={}, &setup)
  court(tool, options, &setup)
  _configure(tool)
end
court(tool, options={}, &block) click to toggle source

Define a specialized configuration handler.

# File lib/courtier/interface.rb, line 168
def court(tool, options={}, &block)
  @setup ||= {}
  tool = tool.to_s
  if block
    @setup[tool] = Setup.new(tool, options, &block)
    #path = Find.load_path(tool, :absolute=>true)
    #if path
    #  if $LOADED_FEATURES.include?(path)
    #    configure(tool)
    #  end
    #end
  end
  @setup[tool.to_s]
end
current_command()
Alias for: current_tool
current_command=(tool)
Alias for: current_tool=
current_profile() click to toggle source

Get current profile.

# File lib/courtier/interface.rb, line 136
def current_profile
  ENV['profile'] || ENV['p'] || 'default'
end
current_profile=(profile) click to toggle source

Set current profile.

# File lib/courtier/interface.rb, line 143
def current_profile=(profile)
  if profile
    ENV['profile'] = profile.to_s
  else
    ENV['profile'] = nil
  end
end
current_tool() click to toggle source

Get current tool.

@todo Not so sure ‘ENV` is a good idea.

# File lib/courtier/interface.rb, line 120
def current_tool
  File.basename(ENV['tool'] || $0)
end
Also aliased as: current_command
current_tool=(tool) click to toggle source

Set current tool.

# File lib/courtier/interface.rb, line 128
def current_tool=(tool)
  ENV['tool'] = tool.to_s
end
Also aliased as: current_command=
profile_names(tool=nil, opts={}) click to toggle source

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

@param [#to_sym] tool

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

@param [Hash] opts

Options for looking up profiles.

@option opts [#to_s] :gem

Name of library from which to load the configuration.

@example

profile_names(:qed)
# File lib/courtier/interface.rb, line 104
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) click to toggle source

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.

@example

Courtier.profile_switch('qed', '-p', '--profile')
# File lib/courtier/interface.rb, line 193
def profile_switch(command, *switches)
  return unless command.to_s == Courtier.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
properties() click to toggle source

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 .ruby YAML or .gemspec.

NOTE: How properties are gathered will be refined in the future.

# File lib/courtier/interface.rb, line 161
def properties
  $properties ||= Properties.new
end
switch(command, switches={}) click to toggle source

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.

@example

Courtier.switch('qed', '-p'=>'profile', '--profile'=>'profile')
# File lib/courtier/interface.rb, line 215
def switch(command, switches={})
  return unless command.to_s == Courtier.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

Private Instance Methods

_configure(command) click to toggle source
# File lib/courtier/interface.rb, line 281
def _configure(command) #, &setup)
  tweak(command)

  command_config = Courtier.configuration[command]

  return unless command_config

  setup = Courtier.court(command)

  command_config.each do |config|
    next if config.onload? # not command config
    next unless config.apply?
    config.require_feature
    setup ? setup.call(config) : config.call
  end
end
autoconfigure() click to toggle source

Copnfgure current commnad. This is used by the ‘rc` script.

# File lib/courtier/interface.rb, line 274
def autoconfigure
  _configure(current_command)
end
bootstrap() click to toggle source

Setup courtier system.

# File lib/courtier/interface.rb, line 243
def bootstrap
  @bootstrap ||= (
    properties  # prime global properties
    bootstrap_require
    true
  )
end
bootstrap_require() click to toggle source

Override require.

# File lib/courtier/interface.rb, line 256
def bootstrap_require
  def Kernel.required(feature)
    config = Courtier.configuration[feature]
    if config
      setup = Courtier.court(feature)  # FIXME: how to differentiate feature from command setup ?
      config.each do |config|
        next unless config.onload? # only command config
        next unless config.apply?
        setup ? setup.call(config) : config.call
      end
    end
    super(feature) if defined?(super)
  end
end
tweak(command) click to toggle source
# File lib/courtier/interface.rb, line 301
def tweak(command)
  tweak = File.join(TWEAKS_DIR, command + '.rb')
  if File.exist?(tweak)
    require tweak
  end
end