Class: Mamiya::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/mamiya/dsl.rb

Direct Known Subclasses

Configuration, Script

Defined Under Namespace

Classes: HelperNotFound, TaskNotDefinedError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDSL

Creates new DSL environment.



12
13
14
15
16
17
18
# File 'lib/mamiya/dsl.rb', line 12

def initialize
  @variables = {}
  @tasks = {}
  @hooks = {}
  @eval_lock = Mutex.new
  @use_lock = Mutex.new
end

Instance Attribute Details

#hooksObject (readonly)

Returns the value of attribute hooks.



20
21
22
# File 'lib/mamiya/dsl.rb', line 20

def hooks
  @hooks
end

#tasksObject (readonly)

Returns the value of attribute tasks.



20
21
22
# File 'lib/mamiya/dsl.rb', line 20

def tasks
  @tasks
end

Class Method Details

.add_hook(name, attributes = {}) ⇒ Object

Add hook point with name name. This defines method with same name in class to call and define hooks.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mamiya/dsl.rb', line 49

def self.add_hook(name, attributes={})
  define_method(name) do |*args, &block|
    @hooks[name] ||= []

    if block
      hook_name = args.shift if args.first.kind_of?(String)
      options = args.pop if args.last.kind_of?(Hash)

      hook = {block: block, options: options || {}, name: hook_name}
      case args.first
      when :overwrite
        @hooks[name] = [hook]
      when :prepend
        @hooks[name][0,0] = [hook]
      else
        @hooks[name] << hook
      end

    else
      matcher = Mamiya::Util::LabelMatcher::Simple.new(args)
      Proc.new { |*args|
        filtered_hooks = @hooks[name].reject { |hook|
          options = hook[:options]

          (options[:only]   && !matcher.match?(*options[:only]  )) ||
          (options[:except] &&  matcher.match?(*options[:except]))
        }

        if attributes[:chain]
          init = args.shift
          filtered_hooks.inject(init) do |result, hook|
            hook[:block].call(result, *args)
          end
        else
          filtered_hooks.each do |hook|
            hook[:block].call *args
          end
        end
      }
    end
  end
end

.defaultsObject

Returns Hash of default setting variables.



24
25
26
# File 'lib/mamiya/dsl.rb', line 24

def self.defaults
  @defaults ||= {}
end

.define_variable_accessor(name) ⇒ Object

:nodoc:



28
29
30
31
32
33
# File 'lib/mamiya/dsl.rb', line 28

def self.define_variable_accessor(name) # :nodoc:
  k = name.to_sym
  return if self.instance_methods.include?(k)

  define_method(k) { self[k] }
end

.set_default(key, value) ⇒ Object

Sets default value value for variable name key. Values set by this method will available for all instances of same class.



38
39
40
41
42
# File 'lib/mamiya/dsl.rb', line 38

def self.set_default(key, value)
  k = key.to_sym
  defaults[k] = value
  self.define_variable_accessor(k)
end

Instance Method Details

#[](key) ⇒ Object

(DSL) Retrieve value for key key. Value can be set using DSL#set .



163
164
165
# File 'lib/mamiya/dsl.rb', line 163

def [](key)
  @variables[key] || self.class.defaults[key]
end

#evaluate!(str = nil, filename = nil, lineno = nil, &block) ⇒ Object

:call-seq:

evaluate!(string [, filename [, lineno]])
evaluate! { block }

Evaluates given string or block in DSL environment.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/mamiya/dsl.rb', line 98

def evaluate!(str = nil, filename = nil, lineno = nil, &block)
  @eval_lock.synchronize {
    begin
      if block_given?
        self.instance_eval(&block)
      elsif str
        @file = filename if filename

        if str && filename && lineno
          self.instance_eval(str, filename.to_s, lineno)
        elsif str && filename
          self.instance_eval(str, filename.to_s)
        elsif str
          self.instance_eval(str)
        end
      end
    ensure
      @file = nil
    end
  }
  self
end

#invoke(name) ⇒ Object

(DSL) Invoke task named name.



175
176
177
178
# File 'lib/mamiya/dsl.rb', line 175

def invoke(name)
  raise TaskNotDefinedError unless @tasks[name]
  self.instance_eval &@tasks[name]
end

#load!(file) ⇒ Object

Evaluates specified file file in DSL environment.



123
124
125
126
# File 'lib/mamiya/dsl.rb', line 123

def load!(file)
  set :_file, Pathname.new(file)
  evaluate! File.read(file), file, 1
end

#load_pathObject

Returns current load path used by use method.



182
183
184
185
186
187
188
# File 'lib/mamiya/dsl.rb', line 182

def load_path
  (@variables[:load_path] ||= []) +
    [
      "#{__dir__}/helpers",
      *(@file ? ["#{File.dirname(@file)}/helpers"] : [])
    ]
end

#set(key, value) ⇒ Object

(DSL) Set value value for variable named key.



147
148
149
150
151
# File 'lib/mamiya/dsl.rb', line 147

def set(key, value)
  k = key.to_sym
  self.class.define_variable_accessor(key) unless self.methods.include?(k)
  @variables[k] = value
end

#set_default(key, value) ⇒ Object

(DSL) Set value value for variable named key unless value is present for the variable.



155
156
157
158
159
# File 'lib/mamiya/dsl.rb', line 155

def set_default(key, value)
  k = key.to_sym
  return @variables[k] if @variables.key?(k)
  set(k, value)
end

#task(name, &block) ⇒ Object

(DSL) Define task named name with given block.



169
170
171
# File 'lib/mamiya/dsl.rb', line 169

def task(name, &block)
  @tasks[name] = block
end

#use(name, options = {}) ⇒ Object

(DSL) Find file using name from current load_path then load. options will be available as variable options in loaded file.



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/mamiya/dsl.rb', line 131

def use(name, options={})
  helper_file = find_helper_file(name)
  raise HelperNotFound unless helper_file

  @use_lock.lock unless @use_lock.owned? # to avoid lock recursively

  @_options = options
  self.instance_eval File.read(helper_file).prepend("options = @_options; @_options = nil;\n"), helper_file, 1

ensure
  @_options = nil
  @use_lock.unlock if @use_lock.owned?
end