class Fire::System

System stores states and rules.

Attributes

digest[R]

File digest.

rules[R]

Array of defined rules.

session[R]

Current session.

states[R]

Array of defined states.

tasks[R]

Mapping of defined tasks.

Public Class Methods

new(options={}) click to toggle source

Instantiate new system.

# File lib/fire/system.rb, line 28
def initialize(options={})
  extend self
  extend ShellUtils

  @ignore  = Array(options[:ignore] || [])
  @files   = Array(options[:files]  || [])

  @rules   = []
  @states  = {}
  @tasks   = {}

  @digest  = Digest.new
  @session = OpenStruct.new

  @files.each do |file|
    module_eval(File.read(file), file)
  end
end

Public Instance Methods

desc(description) click to toggle source

Set task description. The next task defined will get the most recently defined description attached to it.

# File lib/fire/system.rb, line 174
def desc(description)
  @_desc = description
end
env(name_to_pattern) click to toggle source

Define an environment state.

Examples

env('PATH'=>/foo/)

Returns [State]

# File lib/fire/system.rb, line 128
def env(name_to_pattern)
  State.new do
    name_to_pattern.any? do |name, re|
      re === ENV[name.to_s]  # or `all?` instead?
    end
  end
end
file(pattern) click to toggle source

Define a file state.

Returns [FileState]

# File lib/fire/system.rb, line 118
def file(pattern)
  FileState.new(pattern, digest, ignore)
end
ignore(*globs) click to toggle source

Add paths to be ignored in file rules.

# File lib/fire/system.rb, line 81
def ignore(*globs)
  @ignore.concat(globs.flatten)
  @ignore
end
import(*globs) click to toggle source

Import from another file, or glob of files, relative to project root.

@todo Should importing be relative the importing file? @return nothing

# File lib/fire/system.rb, line 66
def import(*globs)
  globs.each do |glob|
    #if File.relative?(glob)
    #  dir = Dir.pwd  #session.root #File.dirname(caller[0])
    #  glob = File.join(dir, glob)
    #end
    Dir[glob].each do |file|
      next unless File.file?(file)
      #instance_eval(File.read(file), file)
      module_eval(File.read(file), file)
    end
  end
end
notify(message, options={}) click to toggle source

Issue notification.

# File lib/fire/system.rb, line 201
def notify(message, options={})
  title = options.delete(:title) || 'Fire Notification'
  Notify.notify(title, message.to_s, options)
end
rule(state, &procedure) click to toggle source

Define a rule. Rules are procedures that are tiggered by logical states.

Examples

rule no_rdocs do |files|
  sh "rdoc --output doc/rdoc " + files.join(" ")
end
# File lib/fire/system.rb, line 144
def rule(state, &procedure)
  state, todo = parse_arrow(state)

  case state
  when String, Regexp
    file_rule(state, :todo=>todo, &procedure)
  when Symbol
    # TODO: Is this really the best idea?
    #@states[state.to_sym]
  else
    @rules << Rule.new(state, :todo=>todo, &procedure)
  end
end
run(task_name) click to toggle source

Run a task.

# File lib/fire/system.rb, line 168
def run(task_name) #, *args)
  tasks[task_name.to_sym].invoke #call(*args)
end
state(name=nil, &condition) click to toggle source

Define a named state. States define conditions that are used to trigger rules. Named states are kept in a hash table to ensure that only one state is ever defined for a given name. Calling state again with the same name as a previously defined state will redefine the condition of that state.

@example

state :no_rdocs? do
  files = Dir.glob('lib/**/*.rb')
  FileUtils.uptodate?('doc', files) ? files : false
end

Returns nil if state name is given. [nil] Returns State in no name is given. [State]

# File lib/fire/system.rb, line 99
def state(name=nil, &condition)
  if name
    if condition
      @states[name.to_sym] = condition
      define_method(name) do |*args|
        state = @states[name.to_sym]
        State.new{ states[name.to_sym].call(*args) }
      end
    else
      raise ArgumentError
    end
  else
    State.new{ condition.call(*args) }
  end
end
state?(name, *args) click to toggle source

Check a name state.

# File lib/fire/system.rb, line 161
def state?(name, *args)
  @states[name.to_sym].call(*args)
end
task(name_and_state, &procedure) click to toggle source

Define a command line task. A task is special type of rule that is triggered when the command line tool is invoked with the name of the task.

Tasks are an isolated set of rules and suppress the activation of all other rules not specifically given as prerequisites.

task :rdoc do
  trip no_rdocs
end

Returns [Task]

# File lib/fire/system.rb, line 190
def task(name_and_state, &procedure)
  name, todo = parse_arrow(name_and_state)
  task = Task.new(name, :todo=>todo, :desc=>@_desc, &procedure)
  @tasks[name.to_sym] = task
  @_desc = nil
  task
end

Private Instance Methods

file_rule(pattern, options={}, &procedure) click to toggle source

Define a file rule. A file rule is a rule with a specific state based on changes in files.

@example

file_rule 'test/**/case_*.rb' do |files|
  sh "ruby-test " + files.join(" ")
end

Returns nothing.

# File lib/fire/system.rb, line 237
def file_rule(pattern, options={}, &procedure)
  state = FileState.new(pattern, digest, ignore)
  @rules << Rule.new(state, options, &procedure)
end
parse_arrow(argument) click to toggle source

Split a hash argument into it’s key and value pair. The hash is expected to have only one entry. If the argument is not a hash then returns the argument and an empty array.

Raises an [ArgumetError] if the hash has more than one entry.

Returns key and value. [Array]

# File lib/fire/system.rb, line 215
def parse_arrow(argument)
  case argument
  when Hash
    raise ArgumentError if argument.size > 1
    head, tail = *argument.to_a.first
    return head, Array(tail)
  else
    return argument, []
  end
end