dtk-dsl 1.0.6 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODIxODM3OTNiZmFmM2FhOTg0YzI5OWQ0ZjE5MTk1MmZjN2U3MGI4OQ==
5
- data.tar.gz: !binary |-
6
- MGVhNTI3NzIwMGFkOTkyZGUyMjM4ZmUxYWM5MzU1YTRjOTNkOWZkNg==
2
+ SHA1:
3
+ metadata.gz: 4d895f877404ae93dfc322386df042ec6c5708b6
4
+ data.tar.gz: 8e4bbc8ff03582fdc14619fbca4eaffcdf01600f
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NmQ3YzYxYzEzYzBmZDI5NmZjZTUwM2M1YmMzMTBhMDY4NTYyOTY4NzAwM2Q3
10
- M2VmZDA2NjNkMzMxMjIyMzZmNjEyYTI2MTIyMTBmNTMwODdjYThiN2M5MTQ1
11
- OWUzMTkzMGU0YWUzNTdjYWJlMmNkZGRhM2YzMmE1N2ZmMDUxZTE=
12
- data.tar.gz: !binary |-
13
- MGE0YjM5MmUwZWRjYzRlNDg4NmYzMWFjN2FmZmI1NTQ3ODQ0YmFlZGU0NDcy
14
- Y2FmOTI3NjEyY2Y3ZDY5OWQ5NGYwZjRkNDFkNTQ3Y2IzMDZjYTY2NTAzYWZh
15
- NzI5YjAxZGY0MTM4ZDJmMzA4NDRlOTlmNjJhYTczMWMxMTVmODA=
6
+ metadata.gz: 19a0e962cdfccc33ee683f7817b70d44045a564d4871b9f9c16c400068c9d88236edbc15f60b33683e1850485a6f9d14cc838cbdc0ab03dce3ebd5d4828425ab
7
+ data.tar.gz: 37484780d4ae0127076c4dc7018edb359da0101b2fe4bc8395613aaf5b7f707f3449bb2180762acb9079acda6b15468bce3236d74fb736418b06fc47c090b24a
@@ -30,6 +30,10 @@ module DTK::DSL
30
30
  def set?(output_key, val)
31
31
  set(output_key, val) unless val.nil?
32
32
  end
33
+
34
+ def delete_key(output_key)
35
+ delete(canonical_key_form_from_output_key(output_key))
36
+ end
33
37
 
34
38
  # value at index output_key
35
39
  def val(output_key)
@@ -35,6 +35,9 @@ module DTK::DSL
35
35
  Module = :module
36
36
  Version = :version
37
37
 
38
+ # Used in component links
39
+ ExternalServiceName = :external_service_name
40
+
38
41
  # Used in workflows
39
42
  Subtasks = :subtasks
40
43
  SubtaskOrder = :subtask_order
@@ -50,6 +50,10 @@ module DTK::DSL
50
50
  end
51
51
  end
52
52
 
53
+ def empty_input_hash
54
+ FileParser::Input::Hash.new(self)
55
+ end
56
+
53
57
  private
54
58
 
55
59
  def input_hash?(input)
@@ -27,10 +27,12 @@ module DTK::DSL
27
27
 
28
28
  extend ClassMixin::Constant
29
29
 
30
- Attributes = 'attributes'
31
- ComponentLinks = 'component_links'
32
- Links = 'links'
33
- Variations::ComponentLinks = ['links','component_links', 'component_link']
30
+ Components = 'components'
31
+ Attributes = 'attributes'
32
+ Links = 'links'
33
+ ComponentLinks = 'component_links'
34
+ Variations::ComponentLinks = ['links', 'component_links', 'component_link']
35
+
34
36
  end
35
37
 
36
38
  ### For parsing
@@ -82,10 +84,9 @@ module DTK::DSL
82
84
 
83
85
  def generate_component_hash
84
86
  ret = {}
85
-
86
87
  set_generation_hash(ret, :Attributes, generate_child_elements(:attribute, val(:Attributes)))
87
88
  set_generation_hash(ret, :Links, generate_child_elements(:component_link, val(:ComponentLinks)))
88
-
89
+ set_generation_hash(ret, :Components, generate_child_elements(:component, val(:Components)))
89
90
  ret
90
91
  end
91
92
 
@@ -116,19 +117,38 @@ module DTK::DSL
116
117
  end
117
118
 
118
119
  properties = input_hash.values.first
119
- if attributes = properties['attributes']
120
- set? :Attributes, parse_child_elements?(:attribute, :Attributes, :input_hash => { 'attributes' => attributes })
121
- end
122
120
 
123
- if component_links = properties['component_links']
124
- set? :Links, parse_child_elements?(:component_link, :ComponentLinks, :input_hash => { 'component_links' => component_links})
125
- end
121
+ # removes from peroperties so we can simply merge keys not processed
122
+ parse_set_property_value_and_remove!(properties, :Attributes)
123
+ parse_set_property_value_and_remove__component_links!(properties)
124
+ parse_set_property_value_and_remove!(properties, :Components)
125
+ merge properties unless properties.empty?
126
+ end
126
127
 
127
- # handle keys not processed
128
- properties.delete(Constant::Attributes)
129
- properties.delete(Constant::ComponentLinks)
128
+ # opts can have keys:
129
+ # :matching_key_value
130
+ def parse_set_property_value_and_remove!(properties, constant, opts = {})
131
+ if matching_key_value = opts[:matching_key_value] || constant_class.matching_key_and_value?(properties, constant)
132
+ key_in_properties = matching_key_value.keys.first
133
+ value = matching_key_value.values.first
134
+ canonical_key = constant_class.canonical_value(constant) # this is string
135
+ parse_template_type = canonical_key.sub(/s$/, '').to_sym
136
+
137
+ # example what below looks like set? :Components, parse_child_elements?(:component, :Components, :input_hash => { 'components' => components})
138
+ set? constant, parse_child_elements?(parse_template_type, constant, :input_hash => { canonical_key => value })
139
+ properties.delete(key_in_properties)
140
+ end
141
+ end
130
142
 
131
- merge properties unless properties.empty?
143
+ # This method handles synatic varaints where component links may be an array and can have array elements that are simple term meaning that
144
+ # the link name is the component type
145
+ def parse_set_property_value_and_remove__component_links!(properties)
146
+ constant = :ComponentLinks
147
+ return unless matching_key_value = constant_class.matching_key_and_value?(properties, constant)
148
+ key = matching_key_value.keys.first
149
+ value = matching_key_value.values.first
150
+ transformed_value = ComponentLink.parse_transform_to_hash_form(value, self)
151
+ parse_set_property_value_and_remove!(properties, constant, matching_key_value: { key => transformed_value })
132
152
  end
133
153
 
134
154
  end
@@ -15,60 +15,100 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
- class DTK::DSL::Template
19
- class V1
20
- class ComponentLink < self
21
- require_relative('component_link/semantic_parse')
22
-
23
- module Constant
24
- module Variations
18
+ module DTK::DSL
19
+ class Template
20
+ class V1
21
+ class ComponentLink < self
22
+ require_relative('component_link/semantic_parse')
23
+ require_relative('component_link/implicit_link_name')
24
+ require_relative('component_link/external_service_name')
25
+
26
+ module Constant
27
+ module Variations
28
+ end
29
+
30
+ extend ClassMixin::Constant
31
+ Value = 'value'
32
+
33
+ end
34
+
35
+ ### For parsing
36
+ def parser_output_type
37
+ :hash
38
+ end
39
+
40
+ # Canonical form is an array
41
+ def self.elements_collection_type
42
+ :hash
43
+ end
44
+
45
+ def self.parse_elements(input_hash, parent_info)
46
+ input_hash.inject(file_parser_output_hash) do |h, (name, value)|
47
+ h.merge(name => parse_element({ 'value' => value}, parent_info, :index => name))
48
+ end
49
+ end
50
+
51
+ def parse!
52
+ dependency, external_service_name = parse_value
53
+ set :Value, dependency
54
+ set? :ExternalServiceName, external_service_name
55
+ end
56
+
57
+ def self.parse_transform_to_hash_form(input_links, parent)
58
+ if input_links.kind_of?(::Hash)
59
+ input_links
60
+ elsif input_links.kind_of?(::Array)
61
+ input_links.inject(empty_input_hash) { |h, link| h.merge(ComponentLink.parse_transform_link_to_hash_form(link, parent)) }
62
+ else
63
+ raise parent.parsing_error(:WrongObjectType, input_links, [::Hash, ::Array])
64
+ end
65
+ end
66
+
67
+ ### For generation
68
+ def self.generate_elements(component_links_content, parent)
69
+ # Parsing form can be a hash, but canonical form is an array
70
+ component_links_content.map { |link_name, component_link| generate_canonical_element(link_name, component_link) }
25
71
  end
26
72
 
27
- extend ClassMixin::Constant
28
- Value = 'value'
29
- end
30
-
31
- ### For parsing
32
- def parser_output_type
33
- :hash
34
- end
35
-
36
- def self.elements_collection_type
37
- :hash
38
- end
39
-
40
- def self.parse_elements(input_hash, parent_info)
41
- input_hash.inject(file_parser_output_hash) do |h, (name, value)|
42
- h.merge(name => parse_element({ 'value' => value}, parent_info, :index => name))
73
+ private
74
+
75
+ def self.parse_transform_link_to_hash_form(link_input, parent)
76
+ if link_input.kind_of?(::Hash)
77
+ link_input
78
+ elsif link_input.kind_of?(::String)
79
+ { ImplicitLinkName.parse(link_input, parent: parent) => link_input }
80
+ else
81
+ parent.parsing_error(:WrongObjectType, link_input, [::Hash, ::String])
82
+ end
43
83
  end
44
- end
45
84
 
46
- def parse!
47
- # using 'input_key_value?' (i.e., with '?') in case null value
48
- set :Value, input_key_value?(:Value)
49
- end
85
+ # returns [dependency, external_service_name]; second can be nil
86
+ def parse_value
87
+ dependency = external_service_name = nil
88
+ string = input_key_value(:Value)
89
+ dependency, external_service_name = ExternalServiceName.parse?(string)
90
+ dependency ||= string
91
+ [dependency, external_service_name]
92
+ end
50
93
 
51
- ### For generation
52
- def self.generate_elements(component_links_content, parent)
53
- component_links_content.inject({}) do |h, (component_link_name, component_link)|
54
- component_link.set(:Name, component_link_name)
55
- element = generate_element?(component_link, parent)
56
- element.nil? ? h : h.merge(element)
94
+ def self.generate_canonical_element(link_name, component_link)
95
+ dependent_ref = dependent_component_ref(component_link)
96
+ if ImplicitLinkName.implicit_link_name(dependent_ref) == link_name
97
+ dependent_ref
98
+ else
99
+ { link_name => dependent_ref }
100
+ end
57
101
  end
58
- end
59
102
 
60
- def generate!
61
- value = val(:Value)
62
- unless value.nil?
63
- merge(req(:Name) => val(:Value))
64
- self
103
+ def self.dependent_component_ref(component_link)
104
+ component_ref = component_link.req(:Value)
105
+ if external_service_name = component_link.val(:ExternalServiceName)
106
+ ExternalServiceName.dependent_component_ref(external_service_name, component_ref)
107
+ else
108
+ component_ref
109
+ end
65
110
  end
66
111
  end
67
-
68
- def generate?
69
- generate! unless skip_for_generation?
70
- end
71
-
72
112
  end
73
113
  end
74
114
  end
@@ -0,0 +1,55 @@
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::V1::ComponentLink
20
+ module ExternalServiceName
21
+ SERVICE_NAME_VAR = '*'
22
+ COMPONENT_VAR = '+'
23
+ MAPPINGS = {
24
+ short_form: {
25
+ generate: "#{SERVICE_NAME_VAR}/#{COMPONENT_VAR}",
26
+ parse_regexp: /^([^\/\]\[]+)\/(.+$)/
27
+ },
28
+ long_form: {
29
+ generate: "service[#{SERVICE_NAME_VAR}]/#{COMPONENT_VAR}",
30
+ parse_regexp: /^service\[([^\]]+)\]\/(.+$)/
31
+ }
32
+ }
33
+ PARSE_REGEXPS = MAPPINGS.values.map { |info| info[:parse_regexp] }
34
+
35
+ CANONICAL_FORM = :short_form
36
+
37
+ def self.dependent_component_ref(external_service_name, component_ref)
38
+ MAPPINGS[CANONICAL_FORM][:generate].sub(SERVICE_NAME_VAR, external_service_name).sub(COMPONENT_VAR, component_ref)
39
+ end
40
+
41
+ # returns [dependency, external_service_name] or nil if no external_service_name
42
+ def self.parse?(input_string)
43
+ # assume that cant have form ATOMIC-TERM/... where ATOMIC-TERM is not a external name
44
+ PARSE_REGEXPS.each do |regexp|
45
+ if input_string =~ regexp
46
+ external_service_name, dependency = [$1, $2]
47
+ return [dependency, external_service_name]
48
+ end
49
+ end
50
+ nil
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,46 @@
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::V1::ComponentLink
20
+ module ImplicitLinkName
21
+ # opts can have keys:
22
+ # :parent
23
+ # :donot_raise_error
24
+ def self.parse(dependent_component_ref, opts = {})
25
+ last_component = dependent_component_ref.split('/').last
26
+ # remove title if it exists
27
+ title_split = last_component.split('[')
28
+ case title_split.size
29
+ when 1
30
+ return last_component
31
+ when 2
32
+ return title_split[0] if title_split[1] =~ /\]$/
33
+ end
34
+ unless opts[:donot_raise_error]
35
+ raise opts[:parent].parsing_error("The term '#{dependent_component_ref}' is an ill-formed component link dependency reference")
36
+ end
37
+ nil
38
+ end
39
+
40
+ def self.implicit_link_name(dependent_component_ref)
41
+ # This should not return nil, but allowing it to be more robust
42
+ parse(dependent_component_ref, donot_raise_error: true)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -19,6 +19,14 @@ module DTK::DSL
19
19
  class Template::V1
20
20
  class ComponentLink
21
21
  class SemanticParse < InputOutputCommon::SemanticParse::Hash
22
+ def value
23
+ val(:Value) || fail(Error, "Unexpected that val(:Value) is nil")
24
+ end
25
+
26
+ def external_service_name?
27
+ val(:ExternalServiceName)
28
+ end
29
+
22
30
  end
23
31
  end
24
32
  end
@@ -36,7 +36,8 @@ class DTK::DSL::Template
36
36
 
37
37
  def self.parse_elements(input_hash, parent_info)
38
38
  input_hash.inject(file_parser_output_hash) do |h, (name, content)|
39
- h.merge(name => parse_element(content, parent_info, :index => name))
39
+ # The term' content || {}' is in case node has no attributes or components
40
+ h.merge(name => parse_element(content || {}, parent_info, :index => name))
40
41
  end
41
42
  end
42
43
 
data/lib/dsl/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module DTK
2
2
  module DSL
3
- VERSION="1.0.6"
3
+ VERSION="1.1.0"
4
4
  end
5
5
  end
6
6
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dtk-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reactor8
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-24 00:00:00.000000000 Z
11
+ date: 2017-05-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Library for parsing DT DSL files.
14
14
  email: support@reactor8.com
@@ -16,7 +16,7 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
- - .gitignore
19
+ - ".gitignore"
20
20
  - Gemfile
21
21
  - README.md
22
22
  - dtk-dsl.gemspec
@@ -115,6 +115,8 @@ files:
115
115
  - lib/dsl/template/v1/component_def.rb
116
116
  - lib/dsl/template/v1/component_def/semantic_parse.rb
117
117
  - lib/dsl/template/v1/component_link.rb
118
+ - lib/dsl/template/v1/component_link/external_service_name.rb
119
+ - lib/dsl/template/v1/component_link/implicit_link_name.rb
118
120
  - lib/dsl/template/v1/component_link/semantic_parse.rb
119
121
  - lib/dsl/template/v1/dependency.rb
120
122
  - lib/dsl/template/v1/module_ref.rb
@@ -139,17 +141,17 @@ require_paths:
139
141
  - lib
140
142
  required_ruby_version: !ruby/object:Gem::Requirement
141
143
  requirements:
142
- - - ! '>='
144
+ - - ">="
143
145
  - !ruby/object:Gem::Version
144
146
  version: 1.9.3
145
147
  required_rubygems_version: !ruby/object:Gem::Requirement
146
148
  requirements:
147
- - - ! '>='
149
+ - - ">="
148
150
  - !ruby/object:Gem::Version
149
151
  version: '0'
150
152
  requirements: []
151
153
  rubyforge_project:
152
- rubygems_version: 2.6.11
154
+ rubygems_version: 2.4.1
153
155
  signing_key:
154
156
  specification_version: 4
155
157
  summary: Library for parsing DT DSL files.