Class: Babushka::DepTemplate

Inherits:
Object
  • Object
show all
Includes:
LogHelpers
Defined in:
lib/babushka/dep_template.rb

Overview

This class represents a template against which deps can be defined. The resulting deps are structured just like regular ones, except for the context against which they were defined.

Standard deps are defined against DepContext, which makes just the basic dep DSL available, i.e. requires/met?/meet, etc. Templated deps are defined against a subclass of TemplatedDepContext as built by build_context.

This means that when a templated dep is defined, the context will be a superset of that of a standard dep – the normal stuff, plus whatever the template adds.

Constant Summary collapse

INVALID_NAMES =
%w[base]
VALID_NAME_START_CHARS =
/[a-z]/
VALID_NAME_CHARS =
/#{VALID_NAME_START_CHARS}[a-z0-9_]*/
VALID_NAME_START =
/^#{VALID_NAME_START_CHARS}/
VALID_NAME =
/\A#{VALID_NAME_CHARS}\z/m
TEMPLATE_NAME_MATCH =
/\A.+\.(#{VALID_NAME_CHARS})\z/m

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LogHelpers

debug, deprecated!, log, log_block, log_error, log_ok, log_stderr, log_warn, removed!

Constructor Details

#initialize(name, source, &block) ⇒ DepTemplate

Returns a new instance of DepTemplate.


56
57
58
59
60
61
# File 'lib/babushka/dep_template.rb', line 56

def initialize name, source, &block
  @name, @source, @block = name, source, block
  debug "Defining #{source.name}:#{name} template"
  @context_class = build_context block
  source.templates.register self
end

Instance Attribute Details

#context_classObject (readonly)

Returns the value of attribute context_class


52
53
54
# File 'lib/babushka/dep_template.rb', line 52

def context_class
  @context_class
end

#nameObject (readonly)

Returns the value of attribute name


52
53
54
# File 'lib/babushka/dep_template.rb', line 52

def name
  @name
end

#sourceObject (readonly)

Returns the value of attribute source


52
53
54
# File 'lib/babushka/dep_template.rb', line 52

def source
  @source
end

Class Method Details

.for(supplied_name, source, &block) ⇒ Object


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/babushka/dep_template.rb', line 34

def self.for supplied_name, source, &block
  name = supplied_name.to_s.downcase

  if name.empty?
    raise ArgumentError, "You can't define a template with a blank name."
  elsif INVALID_NAMES.include? name
    raise ArgumentError, "You can't use '#{name}' for a template name, because it's reserved."
  elsif name[VALID_NAME_START].nil?
    raise ArgumentError, "You can't use '#{name}' for a template name - it must start with a letter."
  elsif name[VALID_NAME].nil?
    raise ArgumentError, "You can't use '#{name}' for a template name - it can only contain [a-z0-9_]."
  elsif Base.sources.current_load_source.templates.for(name)
    raise ArgumentError, "A template called '#{name}' has already been defined."
  else
    new name, source, &block
  end
end

Instance Method Details

#build_context(block) ⇒ Object


75
76
77
78
79
80
81
82
# File 'lib/babushka/dep_template.rb', line 75

def build_context block
  Class.new(TemplatedDepContext, &block).tap {|context|
    shadow = self
    context.metaclass.send :define_method, :source_template do
      shadow
    end
  }
end

#contextual_nameObject

Returns this template's name, including its source name as a prefix if the source is remote.

The contextual name is the name you can use to refer to unambiguously refer to this template on your system; i.e. the name that properly identifies the template, taking your (possibly customised) source names into account.


70
71
72
73
# File 'lib/babushka/dep_template.rb', line 70

def contextual_name
  # TODO This isn't quite right; it should be source.default? instead."
  source.remote? ? "#{source.name}:#{name}" : name
end

#descObject


54
# File 'lib/babushka/dep_template.rb', line 54

def desc; context_class.desc end