dtk-dsl 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/dsl/aux.rb +31 -0
  3. data/lib/dsl/directory_parser.rb +3 -7
  4. data/lib/dsl/dsl_version.rb +1 -0
  5. data/lib/dsl/file_generator/content_input/mixin.rb +2 -5
  6. data/lib/dsl/file_generator/content_input/tag/assignment.rb +32 -0
  7. data/lib/dsl/file_generator/content_input/tag/simple.rb +26 -0
  8. data/lib/dsl/file_generator/content_input/{tags.rb → tag.rb} +61 -23
  9. data/lib/dsl/file_generator/content_input.rb +1 -1
  10. data/lib/dsl/file_generator.rb +7 -0
  11. data/lib/dsl/file_parser.rb +1 -0
  12. data/lib/dsl/file_type/match.rb +68 -0
  13. data/lib/dsl/file_type/matching_files.rb +57 -0
  14. data/lib/dsl/file_type/subclasses.rb +71 -0
  15. data/lib/dsl/file_type.rb +120 -51
  16. data/lib/dsl/input_output_common/canonical/hash.rb +7 -1
  17. data/lib/dsl/input_output_common/canonical/hash_key.rb +20 -1
  18. data/lib/dsl/qualified_key.rb +2 -0
  19. data/lib/dsl/template/constant_class_mixin.rb +8 -9
  20. data/lib/dsl/template/generation/class_mixin.rb +6 -2
  21. data/lib/dsl/template/generation/mixin.rb +35 -20
  22. data/lib/dsl/template/loader.rb +1 -1
  23. data/lib/dsl/template/nested_dsl_file/mixin.rb +77 -0
  24. data/lib/dsl/template/nested_dsl_file.rb +25 -0
  25. data/lib/dsl/template/parsing/class_mixin.rb +8 -9
  26. data/lib/dsl/template/parsing/mixin.rb +31 -8
  27. data/lib/dsl/template/v1/assembly.rb +13 -16
  28. data/lib/dsl/template/v1/common_module_summary.rb +1 -1
  29. data/lib/dsl/template/v1/component.rb +12 -8
  30. data/lib/dsl/template/v1/service_instance.rb +5 -3
  31. data/lib/dsl/template/v1/workflow.rb +108 -38
  32. data/lib/dsl/template/v1.rb +4 -0
  33. data/lib/dsl/template.rb +3 -0
  34. data/lib/dsl/version.rb +1 -1
  35. data/lib/dtk_dsl.rb +1 -0
  36. metadata +11 -4
  37. data/lib/dsl/directory_parser/path_info.rb +0 -62
@@ -49,7 +49,13 @@ module DTK::DSL
49
49
  ret
50
50
  end
51
51
  end
52
-
52
+
53
+ def remove_all_except!(*output_keys)
54
+ matching_internal_indexes = output_keys.inject([]) { |a, k| a + possible_key_forms_from_output_key(k) }
55
+ keys.each { |internal_index| delete(internal_index) unless matching_internal_indexes.include?(internal_index) }
56
+ self
57
+ end
58
+
53
59
  private
54
60
 
55
61
  def canonical_key_form_from_output_key(output_key)
@@ -28,9 +28,22 @@ module DTK::DSL
28
28
  Assembly = :asssembly
29
29
 
30
30
  # Used in assembly
31
- Components = :components
32
31
  Workflows = :workflows
33
32
 
33
+ # Used in nested module
34
+ Module = :module
35
+ Version = :version
36
+
37
+ # Used in workflows
38
+ Subtasks = :subtasks
39
+ SubtaskOrder = :subtask_order
40
+ Node = :node
41
+ ExecutionBlocks = :exec_blocks
42
+ Flatten = :flatten
43
+ Action = :action
44
+ Actions = :actions
45
+ OrderedComponents = :ordered_components
46
+
34
47
  # Used at multiple levels
35
48
  Name = :name
36
49
  Description = :description
@@ -40,6 +53,12 @@ module DTK::DSL
40
53
  Attributes = :attributes
41
54
  Value = :value
42
55
  Nodes = :nodes
56
+ Target = :target
57
+ Components = :components
58
+
59
+ # meta info
60
+ Import = :import
61
+ HiddenImportStatement = :hidden_import_statement
43
62
 
44
63
  def self.index(output_key)
45
64
  begin
@@ -18,6 +18,8 @@
18
18
  module DTK
19
19
  module DSL
20
20
  class QualifiedKey
21
+ attr_reader :key_elements
22
+
21
23
  Element = Struct.new(:type, :key)
22
24
  def initialize(elements_to_copy = [])
23
25
  @key_elements = copy(elements_to_copy)
@@ -20,13 +20,18 @@ module DTK::DSL
20
20
  # assumption is that where this included could have a Variations module
21
21
  module ClassMixin
22
22
  module Constant
23
- def matches?(object, constant)
23
+ # opts can have keys:
24
+ # :set_matching_key - if specified this wil be an empty array to add matching_key to
25
+ def matches?(object, constant, opts = {})
24
26
  unless object.nil?
25
27
  variations = variations(constant)
26
28
  if object.is_a?(Hash)
27
- hash_value_of_matching_key?(object, variations)
29
+ if matching_key = hash_key_if_match?(object, variations)
30
+ opts[:set_matching_key] << matching_key if opts[:set_matching_key]
31
+ object[matching_key]
32
+ end
28
33
  elsif object.is_a?(String) || object.is_a?(Symbol)
29
- variations.include?(object.to_s)
34
+ variations.include?(object.to_s)
30
35
  else
31
36
  fail Error.new("Unexpected object class (#{object.class})")
32
37
  end
@@ -79,12 +84,6 @@ module DTK::DSL
79
84
  variations.find { |key| hash.key?(key) }
80
85
  end
81
86
 
82
- def hash_value_of_matching_key?(hash, variations)
83
- if matching_key = hash_key_if_match?(hash, variations)
84
- hash[matching_key]
85
- end
86
- end
87
-
88
87
  end
89
88
  end
90
89
  end
@@ -27,11 +27,15 @@ module DTK::DSL
27
27
  private
28
28
 
29
29
  def generate_element(content, parent)
30
- create_for_generation(content, :filter => parent.filter).generate_yaml_object
30
+ create_for_generation(content, generation_opts(parent)).generate_yaml_object
31
31
  end
32
32
 
33
33
  def generate_element?(content, parent)
34
- create_for_generation(content, :filter => parent.filter).generate_yaml_object?
34
+ create_for_generation(content, generation_opts(parent)).generate_yaml_object?
35
+ end
36
+
37
+ def generation_opts(parent)
38
+ { :filter => parent.filter, :top => parent.top }
35
39
  end
36
40
 
37
41
  end
@@ -29,18 +29,21 @@ module DTK::DSL
29
29
  generate!
30
30
  end
31
31
 
32
- attr_reader :filter
32
+ attr_reader :filter, :top
33
33
 
34
34
  # opts can have keys
35
35
  # :content (required)
36
36
  # :filter
37
+ # :top
37
38
  def generation_initialize(opts = {})
38
39
  unless content = opts[:content]
39
40
  raise Error, "Unexpected that opts[:content] is nil"
40
41
  end
41
42
  @content = content
42
43
  @filter = opts[:filter]
43
- @yaml_object = empty_yaml_object(content)
44
+ @yaml_object = empty_yaml_object(content_input: content)
45
+ @top = opts[:top] || self
46
+ generation_initialize_nested_dsl_files
44
47
  end
45
48
  private :generation_initialize
46
49
 
@@ -60,6 +63,13 @@ module DTK::DSL
60
63
  YamlHelper.generate(@yaml_object)
61
64
  end
62
65
 
66
+ # Array where each element has keys :path and :content
67
+ def generate_yaml_file_path__content_array(top_file_path)
68
+ self.generate!
69
+ [{ :path => top_file_path, :content => YamlHelper.generate(@yaml_object) }] + generate_nested_dsl_file_path__content_array
70
+ end
71
+
72
+
63
73
  # The methods yaml_object_type can be set on concrete class; it wil be set if input and output types are different
64
74
  def yaml_object_type
65
75
  nil
@@ -71,7 +81,7 @@ module DTK::DSL
71
81
  if content.nil?
72
82
  nil
73
83
  else
74
- template_class(parse_template_type).create_for_generation(content, :filter => @filter).generate_yaml_object
84
+ template_class(parse_template_type).create_for_generation(content, :filter => @filter, :top => @top).generate_yaml_object
75
85
  end
76
86
  end
77
87
 
@@ -81,11 +91,16 @@ module DTK::DSL
81
91
  end
82
92
  end
83
93
 
84
- def empty_yaml_object(content_input)
85
- if self.yaml_object_type
86
- FileGenerator::YamlObject.create(:output_type => yaml_object_type)
87
- else
94
+ # opts can have keys
95
+ # :content_input
96
+ # :output_type
97
+ def empty_yaml_object(opts = {})
98
+ if output_type = opts[:output_type] || self.yaml_object_type
99
+ FileGenerator::YamlObject.create(:output_type => output_type)
100
+ elsif content_input = opts[:content_input]
88
101
  FileGenerator::YamlObject.create(:input => content_input)
102
+ else
103
+ raise Error, "If opts[:content_input] is nil, self.yaml_object_type or opts[:output_type] must have a value"
89
104
  end
90
105
  end
91
106
 
@@ -99,32 +114,32 @@ module DTK::DSL
99
114
  obj.respond_to?(:empty?) and obj.empty?
100
115
  end
101
116
 
117
+ def generation_val(key)
118
+ @content.val(key)
119
+ end
120
+
121
+ def generation_req(key)
122
+ @content.req(key)
123
+ end
124
+
102
125
  def skip_for_generation?
103
126
  @content.skip_for_generation?
104
127
  end
105
128
 
106
129
  def generation_set(constant, val)
107
- set_generation_hash(@yaml_object, constant, val)
108
- end
109
-
110
- def generation_set_scalar(scalar)
111
- @yaml_object = scalar
130
+ set_generation_hash(select_yaml_object_or_nested_dsl_file, constant, val)
112
131
  end
113
132
 
114
133
  def generation_merge(hash)
115
- @yaml_object.merge!(hash)
134
+ select_yaml_object_or_nested_dsl_file.merge!(hash)
116
135
  end
117
136
 
118
137
  def generation_add(array_element)
119
- @yaml_object << array_element
138
+ select_yaml_object_or_nested_dsl_file << array_element
120
139
  end
121
140
 
122
- def generation_val(key)
123
- @content.val(key)
124
- end
125
-
126
- def generation_req(key)
127
- @content.req(key)
141
+ def generation_set_scalar(scalar)
142
+ @yaml_object = scalar
128
143
  end
129
144
 
130
145
  end
@@ -52,7 +52,7 @@ module DTK::DSL
52
52
  def self.template_class_aux(template_type, template_version)
53
53
  base_class = Template.const_get("V#{template_version}")
54
54
  begin
55
- base_class.const_get(::DTK::Common::Aux.snake_to_camel_case(template_type.to_s))
55
+ base_class.const_get(Aux.snake_to_camel_case(template_type.to_s))
56
56
  rescue
57
57
  raise Error, "Invalid template_type '#{template_type}'"
58
58
  end
@@ -0,0 +1,77 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK::DSL
19
+ class Template
20
+ module NestedDSLFile
21
+ module Mixin
22
+ attr_reader :nested_file_content
23
+
24
+ private
25
+ def generation_initialize_nested_dsl_files
26
+ # If there iis any nested dsl in conetnt being generated then tese wil go on @nested_file_content
27
+ # which has keys that are relative paths and values being
28
+ @nested_file_content = {}
29
+ end
30
+
31
+ def generate_nested_dsl_file_path__content_array
32
+ @nested_file_content.inject([]) do |a, (path, content)|
33
+ a + [{ :path => path, :content => YamlHelper.generate(content) }]
34
+ end
35
+ end
36
+
37
+ # returns the path of a file if @yaml_object should be written to a nested dsl file
38
+ def nested_dsl_file?
39
+ val(:Import)
40
+ end
41
+
42
+ def add_nested_dsl_file_import?(nested_dsl_file)
43
+ unless val(:HiddenImportStatement)
44
+ if @yaml_object.kind_of?(::Hash)
45
+ add_import_statement!(nested_dsl_file, @yaml_object)
46
+ elsif @yaml_object.kind_of?(::Array)
47
+ @yaml_object << add_import_statement!(nested_dsl_file)
48
+ else
49
+ raise Error, "Unexpected that @yaml_object is not a hash or array"
50
+ end
51
+ end
52
+ end
53
+
54
+ def add_import_statement!(nested_dsl_file, yaml_object = nil)
55
+ yaml_object ||= empty_yaml_object(:output_type => :hash)
56
+ set_generation_hash(yaml_object, :Import, nested_dsl_file)
57
+ yaml_object
58
+ end
59
+
60
+ def select_yaml_object_or_nested_dsl_file
61
+ if nested_dsl_file = nested_dsl_file?
62
+ add_nested_dsl_file_import?(nested_dsl_file)
63
+ empty_nested_dsl_file_hash(nested_dsl_file, InputOutputCommon.obj_type(@yaml_object))
64
+ else
65
+ @yaml_object
66
+ end
67
+ end
68
+
69
+ def empty_nested_dsl_file_hash(nested_dsl_file, output_type)
70
+ @top.nested_file_content[nested_dsl_file] ||= empty_yaml_object(output_type: output_type)
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,25 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK::DSL
19
+ class Template
20
+ module NestedDSLFile
21
+ require_relative('nested_dsl_file/mixin')
22
+ end
23
+ end
24
+ end
25
+
@@ -29,9 +29,14 @@ module DTK::DSL
29
29
  def elements_collection_type
30
30
  nil
31
31
  end
32
-
33
- private
34
32
 
33
+ def file_parser_output_array
34
+ FileParser::Output.create(:output_type => :array)
35
+ end
36
+
37
+ def file_parser_output_hash
38
+ FileParser::Output.create(:output_type => :hash)
39
+ end
35
40
 
36
41
  # opts can have keys
37
42
  # :index
@@ -45,13 +50,7 @@ module DTK::DSL
45
50
  end
46
51
  end
47
52
 
48
- def file_parser_output_array
49
- FileParser::Output.create(:output_type => :array)
50
- end
51
-
52
- def file_parser_output_hash
53
- FileParser::Output.create(:output_type => :hash)
54
- end
53
+ private
55
54
 
56
55
  def input_hash?(input)
57
56
  input.kind_of?(FileParser::Input::Hash)
@@ -54,6 +54,13 @@ module DTK::DSL
54
54
  nil
55
55
  end
56
56
 
57
+ # args can have form
58
+ # (:ParsingErrorName,*parsing_error_params) or
59
+ # (*parsing_error_params)
60
+ def parsing_error(*args)
61
+ parsing_error_with_opts(args)
62
+ end
63
+
57
64
  private
58
65
 
59
66
  def empty_parser_output(input, parent_key)
@@ -67,6 +74,20 @@ module DTK::DSL
67
74
  end
68
75
  end
69
76
 
77
+ def remove_processed_keys_from_input_hash!(&body)
78
+ @found_keys = []
79
+ body.call
80
+ @found_keys.each { |key| input_hash.delete(key) }
81
+ end
82
+
83
+ def add_found_key?(key)
84
+ @found_keys << key if @found_keys
85
+ end
86
+
87
+ def file_parser_output_array
88
+ self.class.file_parser_output_array
89
+ end
90
+
70
91
  # opts can have key
71
92
  # :key_type
72
93
  def parse_child_elements(parse_template_type, key_constant, opts = {})
@@ -105,7 +126,12 @@ module DTK::DSL
105
126
  end
106
127
  def input_key_value?(constant, opts = {})
107
128
  input_hash = opts[:input_hash] || input_hash()
108
- constant_class.matches?(input_hash, constant)
129
+ set_matching_key = []
130
+ ret = constant_class.matches?(input_hash, constant, :set_matching_key => set_matching_key)
131
+ if matching_key = set_matching_key.first
132
+ add_found_key?(matching_key)
133
+ end
134
+ ret
109
135
  end
110
136
 
111
137
  # returns nil or {key => value}
@@ -114,6 +140,10 @@ module DTK::DSL
114
140
  def input_key_and_value?(constant, opts = {})
115
141
  input_hash = opts[:input_hash] || input_hash()
116
142
  constant_class.matching_key_and_value?(input_hash, constant)
143
+ if ret = constant_class.matching_key_and_value?(input_hash, constant)
144
+ add_found_key?(ret.keys.first)
145
+ end
146
+ ret
117
147
  end
118
148
 
119
149
  def parsing_set(constant, val)
@@ -179,13 +209,6 @@ module DTK::DSL
179
209
  raise parsing_error(:MissingKeyValue, key)
180
210
  end
181
211
 
182
- # args can have form
183
- # (:ParsingErrorName,*parsing_error_params) or
184
- # (*parsing_error_params)
185
- def parsing_error(*args)
186
- parsing_error_with_opts(args)
187
- end
188
-
189
212
  # opts can have keys
190
213
  # :key
191
214
  def parsing_error_with_opts(args, opts = {})
@@ -28,6 +28,7 @@ class DTK::DSL::Template
28
28
  Attributes = 'attributes'
29
29
  Nodes = 'nodes'
30
30
  Components = 'components'
31
+ Target = 'target'
31
32
 
32
33
  Workflows = 'workflows'
33
34
  Variations::Workflows = ['workflows', 'workflow']
@@ -49,28 +50,24 @@ class DTK::DSL::Template
49
50
  end
50
51
 
51
52
  def parse!
52
- set :Name, input_key_value(:Name)
53
- set? :Description, input_key_value?(:Description)
54
- set? :Attributes, parse_child_elements?(:attribute, :Attributes)
55
- set? :Nodes, parse_child_elements?(:node, :Nodes)
56
- set? :Components, parse_child_elements?(:component, :Components)
57
- set? :Workflows, parse_child_elements?(:workflow, :Workflows)
58
-
59
- # TODO: This is a catchall that removes ones we so far are parsing and then has catch all
60
- input_hash.delete('name')
61
- input_hash.delete('description')
62
- input_hash.delete('attributes')
63
- input_hash.delete('nodes')
64
- input_hash.delete('components')
65
- input_hash.delete('workflow')
66
- input_hash.delete('workflows')
67
- merge input_hash
53
+ remove_processed_keys_from_input_hash! do
54
+ set :Name, input_key_value(:Name)
55
+ set? :Description, input_key_value?(:Description)
56
+ set? :Target, input_key_value?(:Target)
57
+ set? :Attributes, parse_child_elements?(:attribute, :Attributes)
58
+ set? :Nodes, parse_child_elements?(:node, :Nodes)
59
+ set? :Components, parse_child_elements?(:component, :Components)
60
+ set? :Workflows, parse_child_elements?(:workflow, :Workflows)
61
+ end
62
+ # handle keys not processed
63
+ merge input_hash unless input_hash.empty?
68
64
  end
69
65
 
70
66
  ### For generation
71
67
  def generate!
72
68
  # TODO: add attributes
73
69
  set :Description, val(:Description)
70
+ set :Target, val(:Target)
74
71
  set :Components, generate_child_elements(:component, val(:Components))
75
72
  set :Nodes, generate_child_elements(:node, val(:Nodes))
76
73
  set :Workflows, generate_child_elements(:workflow, val(:Workflows))
@@ -32,7 +32,7 @@ class DTK::DSL::Template
32
32
  end
33
33
 
34
34
  def parse!
35
- set :DSLVersion, input_key_value(:DSLVersion)
35
+ set :DSLVersion, input_key_value?(:DSLVersion) || dsl_version
36
36
  set :ModuleVersion, input_key_value(:ModuleVersion)
37
37
  merge parse_child(:module_ref, input_key_value(:Module), :parent_key => Constant::Module)
38
38
  set? :DependentModules, parse_child_elements?(:dependency, :DependentModules)
@@ -42,7 +42,7 @@ module DTK::DSL
42
42
 
43
43
  def self.parse_elements(input_array, parent_info)
44
44
  input_array.inject(file_parser_output_hash) do |h, component|
45
- name = name(component)
45
+ name = name(component, :parent => parent_info.parent)
46
46
  h.merge(name => parse_element(component, parent_info, :index => name))
47
47
  end
48
48
  end
@@ -85,18 +85,22 @@ module DTK::DSL
85
85
  ret
86
86
  end
87
87
 
88
- def self.name(input)
88
+ # opts can have keys:
89
+ # :parent
90
+ # :this
91
+ # Will not have both keys
92
+ def self.name(input, opts = {})
89
93
  if input.kind_of?(::String)
90
94
  input
91
95
  elsif input.kind_of?(::Hash) and input.size > 0
92
96
  input.keys.first
93
97
  else
94
- raise parsing_error(:WrongObjectType, input, [::String, ::Hash])
98
+ raise (opts[:this] || opts[:parent]).parsing_error([:WrongObjectType, input, [::String, ::Hash]])
95
99
  end
96
100
  end
97
101
 
98
102
  def name
99
- self.class.name(@input)
103
+ self.class.name(@input, :this => self)
100
104
  end
101
105
 
102
106
  def parse_when_string!
@@ -104,14 +108,14 @@ module DTK::DSL
104
108
 
105
109
  def parse_when_hash!
106
110
  unless input_hash.size == 1 and input_hash.values.first.kind_of?(::Hash)
107
- raise parsing_error("Component is ill-formed; it must be string or hash with has value")
111
+ raise parsing_error("Component is ill-formed; it must be string or hash")
108
112
  end
109
113
  properties = input_hash.values.first
110
114
  set? :Attributes, parse_child_elements?(:attribute, :Attributes, :input_hash => properties)
111
115
 
112
- # TODO: This is a catchall that removes ones we so far are parsing and then has catch all
113
- properties.delete('attributes')
114
- merge properties
116
+ # handle keys not processed
117
+ properties.delete(Constant::Attributes)
118
+ merge properties unless properties.empty?
115
119
  end
116
120
 
117
121
  end
@@ -31,9 +31,11 @@ class DTK::DSL::Template
31
31
 
32
32
  ### For parsing
33
33
  def parse!
34
- set :DSLVersion, input_key_value(:DSLVersion)
35
- set :Name, input_key_value(:DSLVersion)
36
- set? :DependentModules, input_key_value?(:DependentModules)
34
+ remove_processed_keys_from_input_hash! do
35
+ set :DSLVersion, input_key_value(:DSLVersion)
36
+ set :Name, input_key_value(:DSLVersion)
37
+ set? :DependentModules, input_key_value?(:DependentModules)
38
+ end
37
39
  merge parse_child(:assembly, input_hash)
38
40
  end
39
41