Module: Minestrone::Configuration::Namespaces

Included in:
Minestrone::Configuration, Namespace
Defined in:
lib/minestrone/configuration/namespaces.rb

Defined Under Namespace

Classes: Namespace

Constant Summary collapse

DEFAULT_TASK =
:default

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#nameObject (readonly)

The name of this namespace. Defaults to nil for the top-level namespace.



13
14
15
# File 'lib/minestrone/configuration/namespaces.rb', line 13

def name
  @name
end

#namespacesObject (readonly)

The hash of namespaces defined for this namespace.



23
24
25
# File 'lib/minestrone/configuration/namespaces.rb', line 23

def namespaces
  @namespaces
end

#parentObject (readonly)

The parent namespace of this namespace. Returns nil for the top-level namespace.



17
18
19
# File 'lib/minestrone/configuration/namespaces.rb', line 17

def parent
  @parent
end

#tasksObject (readonly)

The hash of tasks defined for this namespace.



20
21
22
# File 'lib/minestrone/configuration/namespaces.rb', line 20

def tasks
  @tasks
end

Instance Method Details

#default_taskObject

Returns the default task for this namespace. This will be nil if the namespace is at the top-level, and will otherwise return the task named “default”. If no such task exists, nil will be returned.



159
160
161
# File 'lib/minestrone/configuration/namespaces.rb', line 159

def default_task
  parent ? tasks[DEFAULT_TASK] : nil
end

#define_task(task) ⇒ Object



106
107
108
109
110
111
# File 'lib/minestrone/configuration/namespaces.rb', line 106

def define_task(task)
  tasks[task.name] = task

  metaclass = class << self; self; end
  metaclass.send(:define_method, task.name) { execute_task(tasks[task.name]) }
end

#desc(text) ⇒ Object

Describe the next task to be defined. The given text will be attached to the next task that is defined and used as its description.



49
50
51
# File 'lib/minestrone/configuration/namespaces.rb', line 49

def desc(text)
  @next_description = text
end

#find_task(name) ⇒ Object

Find the task with the given name, where name is the fully-qualified name of the task. This will search into the namespaces and return the referenced task, or nil if no such task can be found. If the name refers to a namespace, the task in that namespace named “default” will be returned instead, if one exists.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/minestrone/configuration/namespaces.rb', line 119

def find_task(name)
  parts = name.to_s.split(/:/)
  tail = parts.pop.to_sym

  ns = self

  until parts.empty?
    next_part = parts.shift
    ns = next_part.empty? ? nil : ns.namespaces[next_part.to_sym]
    return nil if ns.nil?
  end

  if ns.namespaces.key?(tail)
    ns = ns.namespaces[tail]
    tail = DEFAULT_TASK
  end

  ns.tasks[tail]
end

#fully_qualified_nameObject

Returns the fully-qualified name of this namespace, or nil if the namespace is at the top-level.



39
40
41
42
43
44
45
# File 'lib/minestrone/configuration/namespaces.rb', line 39

def fully_qualified_name
  if name
    [parent.fully_qualified_name, name].compact.join(':')
  else
    nil
  end
end

#initialize_namespaces(name = nil, parent = nil) ⇒ Object

:nodoc:



25
26
27
28
29
30
# File 'lib/minestrone/configuration/namespaces.rb', line 25

def initialize_namespaces(name = nil, parent = nil) #:nodoc:
  @name = name
  @parent = parent
  @tasks = {}
  @namespaces = {}
end

#namespace(name, &block) ⇒ Object

Open a namespace in which to define new tasks. If the namespace was defined previously, it will be reopened, otherwise a new namespace will be created for the given name.

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/minestrone/configuration/namespaces.rb', line 64

def namespace(name, &block)
  name = name.to_sym
  raise ArgumentError, "expected a block" unless block_given?

  namespace_already_defined = namespaces.key?(name)

  if all_methods.any? { |m| m.to_sym == name } && !namespace_already_defined
    thing = tasks.key?(name) ? "task" : "method"
    raise ArgumentError, "defining a namespace named `#{name}' would shadow an existing #{thing} with that name"
  end

  namespaces[name] ||= Namespace.new(name, self)
  namespaces[name].instance_eval(&block)

  # make sure any open description gets terminated
  namespaces[name].desc(nil)

  if !namespace_already_defined
    metaclass = class << self; self; end
    metaclass.send(:define_method, name) { namespaces[name] }
  end
end

#next_description(reset = false) ⇒ Object

Returns the value set by the last, pending “desc” call. If reset is not false, the value will be reset immediately afterwards.



55
56
57
58
59
# File 'lib/minestrone/configuration/namespaces.rb', line 55

def next_description(reset = false)
  @next_description
ensure
  @next_description = nil if reset
end

#search_task(name) ⇒ Object

Given a task name, this will search the current namespace, and all parent namespaces, looking for a task that matches the name, exactly. It returns the task, if found, or nil, if not.



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/minestrone/configuration/namespaces.rb', line 143

def search_task(name)
  name = name.to_sym
  ns = self

  until ns.nil?
    return ns.tasks[name] if ns.tasks.key?(name)
    ns = ns.parent
  end

  return nil
end

#task(name, options = {}, &block) ⇒ Object

Describe a new task. If a description is active (see #desc), it is added to the options under the :desc key. The new task is added to the namespace.

Raises:

  • (ArgumentError)


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/minestrone/configuration/namespaces.rb', line 90

def task(name, options = {}, &block)
  name = name.to_sym
  raise ArgumentError, "expected a block" unless block_given?

  task_already_defined = tasks.key?(name)

  if all_methods.any? { |m| m.to_sym == name } && !task_already_defined
    thing = namespaces.key?(name) ? "namespace" : "method"
    raise ArgumentError, "defining a task named `#{name}' would shadow an existing #{thing} with that name"
  end

  task = TaskDefinition.new(name, self, { :desc => next_description(:reset) }.merge(options), &block)

  define_task(task)
end

#task_list(all = false) ⇒ Object

Returns the tasks in this namespace as an array of TaskDefinition objects. If a non-false parameter is given, all tasks in all namespaces under this namespace will be returned as well.



167
168
169
170
171
# File 'lib/minestrone/configuration/namespaces.rb', line 167

def task_list(all = false)
  list = tasks.values
  namespaces.each { |name,space| list.concat(space.task_list(:all)) } if all
  list
end

#topObject

Returns the top-level namespace (the one with no parent).



33
34
35
# File 'lib/minestrone/configuration/namespaces.rb', line 33

def top
  parent ? parent.top : self
end