dtk-dsl 1.0.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.