Class: DSLCompose::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/dsl_compose/dsl.rb,
lib/dsl_compose/dsl/arguments.rb,
lib/dsl_compose/dsl/dsl_method.rb,
lib/dsl_compose/dsl/interpreter.rb,
lib/dsl_compose/dsl/arguments/argument.rb,
lib/dsl_compose/dsl/dsl_method/interpreter.rb,
lib/dsl_compose/dsl/arguments/argument/interpreter.rb,
lib/dsl_compose/dsl/arguments/argument/in_validation.rb,
lib/dsl_compose/dsl/arguments/argument/is_a_validation.rb,
lib/dsl_compose/dsl/arguments/argument/format_validation.rb,
lib/dsl_compose/dsl/arguments/argument/length_validation.rb,
lib/dsl_compose/dsl/arguments/argument/not_in_validation.rb,
lib/dsl_compose/dsl/arguments/argument/end_with_validation.rb,
lib/dsl_compose/dsl/arguments/argument/equal_to_validation.rb,
lib/dsl_compose/dsl/arguments/argument/less_than_validation.rb,
lib/dsl_compose/dsl/arguments/argument/start_with_validation.rb,
lib/dsl_compose/dsl/arguments/argument/greater_than_validation.rb,
lib/dsl_compose/dsl/arguments/argument/not_end_with_validation.rb,
lib/dsl_compose/dsl/arguments/argument/not_start_with_validation.rb,
lib/dsl_compose/dsl/arguments/argument/less_than_or_equal_to_validation.rb,
lib/dsl_compose/dsl/arguments/argument/greater_than_or_equal_to_validation.rb

Overview

The class is reponsible for creating and representing a dynamic DSL

These new dynamic DSL’s are created using our own internal DSL, which is accessed by calling ‘define_dsl` in a class and passing it a block which contains the DSL definition

Defined Under Namespace

Classes: Arguments, DSLMethod, DescriptionAlreadyExistsError, Interpreter, InvalidDescriptionError, InvalidNameError, InvalidNamespaceError, InvalidTitleError, MethodAlreadyExistsError, MethodDoesNotExistError, NamespaceAlreadyExistsError, NoBlockProvidedError, TitleAlreadyExistsError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, klass) ⇒ DSL

Create a new DSL object with the provided name and class.

‘name` must be a symbol. `klass` should be the class in which `define_dsl` is being called.



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/dsl_compose/dsl.rb', line 59

def initialize name, klass
  @dsl_methods = {}

  @arguments = Arguments.new

  if name.is_a? Symbol
    @name = name
  else
    raise InvalidNameError, "The DSL name `#{name}` is invalid, it must be of type symbol"
  end

  @klass = klass
end

Instance Attribute Details

#argumentsObject (readonly)

an object which represents the argument configuration



53
54
55
# File 'lib/dsl_compose/dsl.rb', line 53

def arguments
  @arguments
end

#descriptionObject (readonly)

An otional description of this DSL, if provided then it must be a string. The description accepts markdown and is used when generating documentation.



45
46
47
# File 'lib/dsl_compose/dsl.rb', line 45

def description
  @description
end

#klassObject (readonly)

klass will be the class where ‘define_dsl` was called.



42
43
44
# File 'lib/dsl_compose/dsl.rb', line 42

def klass
  @klass
end

#nameObject (readonly)

The name of this DSL.



40
41
42
# File 'lib/dsl_compose/dsl.rb', line 40

def name
  @name
end

#namespaceObject (readonly)

An otional namespace for this DSL, if provided then it must be a Symbol. This is currently used to group DSLs for the sake of documentation.



48
49
50
# File 'lib/dsl_compose/dsl.rb', line 48

def namespace
  @namespace
end

#titleObject (readonly)

An otional namespace for this DSL, if provided then it must be a String. This is currently used when generating documentation.



51
52
53
# File 'lib/dsl_compose/dsl.rb', line 51

def title
  @title
end

Instance Method Details

#add_method(name, unique, required, &block) ⇒ Object

Takes a method name, unique flag, required flag, and a block and creates a new DSLMethod object.

Method ‘name` must be unique within the DSL.



157
158
159
160
161
162
163
# File 'lib/dsl_compose/dsl.rb', line 157

def add_method name, unique, required, &block
  if has_dsl_method? name
    raise MethodAlreadyExistsError, "The method `#{name}` already exists for this DSL"
  end

  @dsl_methods[name] = DSLMethod.new(name, unique, required, &block)
end

#dsl_method(name) ⇒ Object

returns a specific DSLMethod by it’s name, if the DSLMethod does not exist, then an error is raised



197
198
199
200
201
202
203
# File 'lib/dsl_compose/dsl.rb', line 197

def dsl_method name
  if has_dsl_method? name
    @dsl_methods[name]
  else
    raise MethodDoesNotExistError, "The method `#{name}` does not exist for this DSL"
  end
end

#dsl_methodsObject

Returns an array of all this DSLs DSLMethods.



166
167
168
# File 'lib/dsl_compose/dsl.rb', line 166

def dsl_methods
  @dsl_methods.values
end

#evaluate_configuration_block(&block) ⇒ Object

Evaluate the configuration block which defines our new DSL ‘block` contains the DSL definition and will be evaluated to create the rest of the DSL.



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/dsl_compose/dsl.rb', line 76

def evaluate_configuration_block &block
  if block
    # We evaluate the internal DSL configuration blocks using a seperate interpreter
    # class. We do this because the interpreter class contains no other methods or
    # variables, if it was evaluated in the context of this class then the block
    # would have access to all of the methods defined in here.
    Interpreter.new(self).instance_eval(&block)
  else
    raise NoBlockProvidedError, "No block was provided for this DSL"
  end
end

#has_description?Boolean

Returns ‘true` if this DSL has a description, else false.

Returns:

  • (Boolean)


139
140
141
# File 'lib/dsl_compose/dsl.rb', line 139

def has_description?
  @description.nil? == false
end

#has_dsl_method?(name) ⇒ Boolean

Returns ‘true` if a DSLMethod with the provided name exists in this DSL, otherwise it returns `false`.

Returns:

  • (Boolean)


207
208
209
# File 'lib/dsl_compose/dsl.rb', line 207

def has_dsl_method? name
  @dsl_methods.key? name
end

#has_methods?Boolean

does this DSL have any methods

Returns:

  • (Boolean)


171
172
173
# File 'lib/dsl_compose/dsl.rb', line 171

def has_methods?
  dsl_methods.any?
end

#has_namespace?Boolean

Returns ‘true` if this DSL has a namespace, else false.

Returns:

  • (Boolean)


144
145
146
# File 'lib/dsl_compose/dsl.rb', line 144

def has_namespace?
  @namespace.nil? == false
end

#has_optional_methods?Boolean

does this DSL have any optional methods

Returns:

  • (Boolean)


181
182
183
# File 'lib/dsl_compose/dsl.rb', line 181

def has_optional_methods?
  optional_dsl_methods.any?
end

#has_required_methods?Boolean

does this DSL have any required methods

Returns:

  • (Boolean)


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

def has_required_methods?
  required_dsl_methods.any?
end

#has_title?Boolean

Returns ‘true` if this DSL has a title, else false.

Returns:

  • (Boolean)


149
150
151
# File 'lib/dsl_compose/dsl.rb', line 149

def has_title?
  @title.nil? == false
end

#optional_dsl_methodsObject

Returns an array of only the optional DSLMethods in this DSL.



191
192
193
# File 'lib/dsl_compose/dsl.rb', line 191

def optional_dsl_methods
  dsl_methods.filter(&:optional?)
end

#required_dsl_methodsObject

Returns an array of only the required DSLMethods in this DSL.



186
187
188
# File 'lib/dsl_compose/dsl.rb', line 186

def required_dsl_methods
  dsl_methods.filter(&:required?)
end

#set_description(description) ⇒ Object

Set the description for this DSL to the provided value.

‘description` must be a string with a length greater than 0. The `description` can only be set once per DSL



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/dsl_compose/dsl.rb', line 92

def set_description description
  unless description.is_a?(String) && description.strip.length > 0
    raise InvalidDescriptionError, "The DSL description `#{description}` is invalid, it must be of type string and have length greater than 0"
  end

  if has_description?
    raise DescriptionAlreadyExistsError, "The DSL description has already been set"
  end

  @description = description.strip
end

#set_namespace(namespace) ⇒ Object

Set the namespace for this DSL to the provided value.

‘namespace` must be a Symbol. The `namespace` can only be set once per DSL this is currently used for grouping together DSLS for the sake of documentation



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/dsl_compose/dsl.rb', line 109

def set_namespace namespace
  unless namespace.is_a?(Symbol)
    raise InvalidNamespaceError, "The DSL namespace `#{namespace}` is invalid, it must be of type Symbol"
  end

  if has_namespace?
    raise NamespaceAlreadyExistsError, "The DSL namespace has already been set"
  end

  @namespace = namespace
end

#set_title(title) ⇒ Object

Set the title for this DSL to the provided value.

‘title` must be a String with a length greater than 0. The `title` can only be set once per DSL this is currently used for documentation



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/dsl_compose/dsl.rb', line 126

def set_title title
  unless title.is_a?(String) && title.strip.length > 0
    raise InvalidTitleError, "The DSL title `#{title}` is invalid, it must be of type string and have length greater than 0"
  end

  if has_title?
    raise TitleAlreadyExistsError, "The DSL title has already been set"
  end

  @title = title.strip
end