dtk-shell 0.10.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.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile_dev +13 -0
  4. data/README.md +121 -0
  5. data/bin/dtk-execute +32 -0
  6. data/bin/dtk-run +92 -0
  7. data/bin/dtk-shell +31 -0
  8. data/dtk-shell.gemspec +50 -0
  9. data/lib/auxiliary.rb +61 -0
  10. data/lib/bundler_monkey_patch.rb +26 -0
  11. data/lib/client.rb +58 -0
  12. data/lib/command_helper.rb +33 -0
  13. data/lib/command_helpers/git_repo.rb +589 -0
  14. data/lib/command_helpers/git_repo/merge.rb +153 -0
  15. data/lib/command_helpers/jenkins_client.rb +106 -0
  16. data/lib/command_helpers/jenkins_client/config_xml.rb +288 -0
  17. data/lib/command_helpers/service_importer.rb +251 -0
  18. data/lib/command_helpers/service_link.rb +33 -0
  19. data/lib/command_helpers/test_module_creator.rb +69 -0
  20. data/lib/command_helpers/test_module_templates/dtk.model.yaml.eruby +10 -0
  21. data/lib/command_helpers/test_module_templates/spec_helper.rb.eruby +10 -0
  22. data/lib/command_helpers/test_module_templates/temp_component_spec.rb.eruby +5 -0
  23. data/lib/commands.rb +57 -0
  24. data/lib/commands/common/thor/access_control.rb +133 -0
  25. data/lib/commands/common/thor/action_result_handler.rb +74 -0
  26. data/lib/commands/common/thor/assembly_template.rb +92 -0
  27. data/lib/commands/common/thor/assembly_workspace.rb +1801 -0
  28. data/lib/commands/common/thor/base_command_helper.rb +59 -0
  29. data/lib/commands/common/thor/clone.rb +82 -0
  30. data/lib/commands/common/thor/common.rb +88 -0
  31. data/lib/commands/common/thor/common_base.rb +49 -0
  32. data/lib/commands/common/thor/create_target.rb +70 -0
  33. data/lib/commands/common/thor/edit.rb +255 -0
  34. data/lib/commands/common/thor/inventory_parser.rb +98 -0
  35. data/lib/commands/common/thor/list_diffs.rb +128 -0
  36. data/lib/commands/common/thor/module.rb +1011 -0
  37. data/lib/commands/common/thor/module/import.rb +210 -0
  38. data/lib/commands/common/thor/node.rb +53 -0
  39. data/lib/commands/common/thor/poller.rb +65 -0
  40. data/lib/commands/common/thor/pull_clone_changes.rb +28 -0
  41. data/lib/commands/common/thor/pull_from_remote.rb +152 -0
  42. data/lib/commands/common/thor/puppet_forge.rb +72 -0
  43. data/lib/commands/common/thor/purge_clone.rb +101 -0
  44. data/lib/commands/common/thor/push_clone_changes.rb +162 -0
  45. data/lib/commands/common/thor/push_to_remote.rb +94 -0
  46. data/lib/commands/common/thor/remotes.rb +71 -0
  47. data/lib/commands/common/thor/reparse.rb +40 -0
  48. data/lib/commands/common/thor/set_required_attributes.rb +46 -0
  49. data/lib/commands/thor/account.rb +239 -0
  50. data/lib/commands/thor/assembly.rb +356 -0
  51. data/lib/commands/thor/attribute.rb +79 -0
  52. data/lib/commands/thor/component.rb +70 -0
  53. data/lib/commands/thor/component_module.rb +501 -0
  54. data/lib/commands/thor/component_template.rb +174 -0
  55. data/lib/commands/thor/dependency.rb +34 -0
  56. data/lib/commands/thor/developer.rb +144 -0
  57. data/lib/commands/thor/dtk.rb +152 -0
  58. data/lib/commands/thor/library.rb +125 -0
  59. data/lib/commands/thor/node.rb +504 -0
  60. data/lib/commands/thor/node_template.rb +94 -0
  61. data/lib/commands/thor/project.rb +34 -0
  62. data/lib/commands/thor/provider.rb +233 -0
  63. data/lib/commands/thor/remotes.rb +49 -0
  64. data/lib/commands/thor/service.rb +941 -0
  65. data/lib/commands/thor/service_module.rb +914 -0
  66. data/lib/commands/thor/state_change.rb +25 -0
  67. data/lib/commands/thor/target.rb +250 -0
  68. data/lib/commands/thor/task.rb +116 -0
  69. data/lib/commands/thor/test_module.rb +310 -0
  70. data/lib/commands/thor/utils.rb +21 -0
  71. data/lib/commands/thor/workspace.rb +685 -0
  72. data/lib/config/cacert.pem +3785 -0
  73. data/lib/config/client.conf.header +20 -0
  74. data/lib/config/configuration.rb +99 -0
  75. data/lib/config/default.conf +16 -0
  76. data/lib/config/disk_cacher.rb +80 -0
  77. data/lib/configurator.rb +176 -0
  78. data/lib/context_router.rb +44 -0
  79. data/lib/core.rb +497 -0
  80. data/lib/domain/git_adapter.rb +412 -0
  81. data/lib/domain/git_error_handler.rb +64 -0
  82. data/lib/domain/response.rb +285 -0
  83. data/lib/domain/response/error_handler.rb +86 -0
  84. data/lib/dtk-shell/version.rb +20 -0
  85. data/lib/dtk_constants.rb +40 -0
  86. data/lib/dtk_error.rb +114 -0
  87. data/lib/dtk_logger.rb +126 -0
  88. data/lib/dtk_shell.rb +31 -0
  89. data/lib/error.rb +85 -0
  90. data/lib/execute.rb +29 -0
  91. data/lib/execute/cli_pure/cli_rerouter.rb +102 -0
  92. data/lib/execute/command.rb +40 -0
  93. data/lib/execute/command/api_call.rb +60 -0
  94. data/lib/execute/command/api_call/map.rb +60 -0
  95. data/lib/execute/command/api_call/service.rb +91 -0
  96. data/lib/execute/command/api_call/translation_term.rb +119 -0
  97. data/lib/execute/command/rest_call.rb +37 -0
  98. data/lib/execute/command_processor.rb +30 -0
  99. data/lib/execute/command_processor/rest_call.rb +59 -0
  100. data/lib/execute/error_usage.rb +21 -0
  101. data/lib/execute/execute_context.rb +86 -0
  102. data/lib/execute/execute_context/result_store.rb +37 -0
  103. data/lib/execute/script.rb +64 -0
  104. data/lib/execute/script/add_tenant.rb +121 -0
  105. data/lib/git-logs/git.log +0 -0
  106. data/lib/parser/adapters/option_parser.rb +70 -0
  107. data/lib/parser/adapters/thor.rb +555 -0
  108. data/lib/parser/adapters/thor/common_option_defs.rb +40 -0
  109. data/lib/require_first.rb +104 -0
  110. data/lib/search_hash.rb +44 -0
  111. data/lib/shell.rb +261 -0
  112. data/lib/shell/context.rb +1065 -0
  113. data/lib/shell/context_aux.rb +46 -0
  114. data/lib/shell/domain/active_context.rb +186 -0
  115. data/lib/shell/domain/context_entity.rb +89 -0
  116. data/lib/shell/domain/context_params.rb +223 -0
  117. data/lib/shell/domain/override_tasks.rb +88 -0
  118. data/lib/shell/domain/shadow_entity.rb +76 -0
  119. data/lib/shell/header_shell.rb +44 -0
  120. data/lib/shell/help_monkey_patch.rb +283 -0
  121. data/lib/shell/interactive_wizard.rb +225 -0
  122. data/lib/shell/message_queue.rb +63 -0
  123. data/lib/shell/parse_monkey_patch.rb +39 -0
  124. data/lib/shell/status_monitor.rb +124 -0
  125. data/lib/task_status.rb +83 -0
  126. data/lib/task_status/refresh_mode.rb +77 -0
  127. data/lib/task_status/snapshot_mode.rb +28 -0
  128. data/lib/task_status/stream_mode.rb +48 -0
  129. data/lib/task_status/stream_mode/element.rb +101 -0
  130. data/lib/task_status/stream_mode/element/format.rb +101 -0
  131. data/lib/task_status/stream_mode/element/hierarchical_task.rb +100 -0
  132. data/lib/task_status/stream_mode/element/hierarchical_task/result.rb +72 -0
  133. data/lib/task_status/stream_mode/element/hierarchical_task/result/action.rb +93 -0
  134. data/lib/task_status/stream_mode/element/hierarchical_task/result/components.rb +26 -0
  135. data/lib/task_status/stream_mode/element/hierarchical_task/result/node_level.rb +26 -0
  136. data/lib/task_status/stream_mode/element/hierarchical_task/steps.rb +34 -0
  137. data/lib/task_status/stream_mode/element/hierarchical_task/steps/action.rb +53 -0
  138. data/lib/task_status/stream_mode/element/hierarchical_task/steps/components.rb +53 -0
  139. data/lib/task_status/stream_mode/element/hierarchical_task/steps/node_level.rb +42 -0
  140. data/lib/task_status/stream_mode/element/no_results.rb +26 -0
  141. data/lib/task_status/stream_mode/element/render.rb +59 -0
  142. data/lib/task_status/stream_mode/element/stage.rb +84 -0
  143. data/lib/task_status/stream_mode/element/stage/render.rb +76 -0
  144. data/lib/task_status/stream_mode/element/task_end.rb +35 -0
  145. data/lib/task_status/stream_mode/element/task_start.rb +37 -0
  146. data/lib/util/common_util.rb +37 -0
  147. data/lib/util/console.rb +235 -0
  148. data/lib/util/dtk_puppet.rb +65 -0
  149. data/lib/util/module_util.rb +66 -0
  150. data/lib/util/os_util.rb +385 -0
  151. data/lib/util/permission_util.rb +31 -0
  152. data/lib/util/remote_dependency_util.rb +84 -0
  153. data/lib/util/ssh_util.rb +94 -0
  154. data/lib/view_processor.rb +129 -0
  155. data/lib/view_processor/augmented_simple_list.rb +44 -0
  156. data/lib/view_processor/hash_pretty_print.rb +123 -0
  157. data/lib/view_processor/simple_list.rb +156 -0
  158. data/lib/view_processor/table_print.rb +309 -0
  159. data/lib/violation.rb +86 -0
  160. data/lib/violation/attribute.rb +76 -0
  161. data/lib/violation/fix.rb +26 -0
  162. data/lib/violation/fix/result.rb +73 -0
  163. data/lib/violation/fix/result/error.rb +34 -0
  164. data/lib/violation/fix/set_attribute.rb +41 -0
  165. data/lib/violation/sub_classes.rb +60 -0
  166. data/puppet/manifests/init.pp +72 -0
  167. data/puppet/manifests/params.pp +16 -0
  168. data/puppet/r8meta.puppet.yml +35 -0
  169. data/puppet/templates/bash_profile.erb +2 -0
  170. data/puppet/templates/client.conf.erb +1 -0
  171. data/puppet/templates/dtkclient.erb +2 -0
  172. data/spec/component_module_spec.rb +34 -0
  173. data/spec/dependency_spec.rb +6 -0
  174. data/spec/dtk_shell_spec.rb +13 -0
  175. data/spec/dtk_spec.rb +33 -0
  176. data/spec/lib/spec_helper.rb +10 -0
  177. data/spec/lib/spec_thor.rb +108 -0
  178. data/spec/node_template_spec.rb +24 -0
  179. data/spec/project_spec.rb +6 -0
  180. data/spec/repo_spec.rb +7 -0
  181. data/spec/response_spec.rb +52 -0
  182. data/spec/service_module_spec.rb +38 -0
  183. data/spec/service_spec.rb +50 -0
  184. data/spec/state_change_spec.rb +7 -0
  185. data/spec/table_print_spec.rb +48 -0
  186. data/spec/target_spec.rb +57 -0
  187. data/spec/task_spec.rb +28 -0
  188. data/views/assembly/augmented_simple_list.rb +12 -0
  189. data/views/assembly_template/augmented_simple_list.rb +12 -0
  190. data/views/list_task/augmented_simple_list.rb +12 -0
  191. metadata +421 -0
@@ -0,0 +1,156 @@
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
+ require 'erubis'
19
+ module DTK
20
+ module Client
21
+ class ViewProcSimpleList < ViewProcessor
22
+ def render(hash)
23
+ pp_adapter = ViewProcessor.get_adapter("hash_pretty_print",@command_class,@data_type_index)
24
+ ordered_hash = pp_adapter.render(hash)
25
+ if ordered_hash.size == 1
26
+ render_simple_assignment(ordered_hash.keys.first,ordered_hash.values.first)
27
+ else
28
+ render_ordered_hash(ordered_hash)
29
+ end
30
+ end
31
+ private
32
+ #TODO Aldin check if assembly or assembly_name
33
+ HIDE_FROM_VIEW = ["assembly"]
34
+ def render_simple_assignment(key,val)
35
+ key + KeyValSeperator + val.to_s + "\n"
36
+ end
37
+ def render_ordered_hash(ordered_hash,ident_info={},index=1)
38
+ #find next value that is type pretty print hash or array
39
+ beg,nested,rest = find_first_non_scalar(ordered_hash)
40
+ ret = String.new
41
+ unless beg.empty?
42
+ ret = simple_value_render(beg,ident_info.merge(:index => index))
43
+ end
44
+ unless nested.empty?
45
+ ident_info_nested = {
46
+ :ident => (ident_info[:ident]||0) +IdentAdd,
47
+ :nested_key => nested.keys.first
48
+ }
49
+ ident_info_nested[:ident] += IdentAdd
50
+ ret << "#{ident_str(ident_info_nested[:ident])}#{nested.keys.first.upcase}\n"
51
+ vals = nested.values.first
52
+ vals = [vals] unless vals.kind_of?(Array)
53
+ vals.each_with_index{|val,i|ret << render_ordered_hash(val,ident_info_nested,i+1)}
54
+ end
55
+ unless rest.empty?
56
+ rest = hide_from_view(rest)
57
+ ret << render_ordered_hash(rest,ident_info.merge(:include_first_key => true))
58
+ end
59
+ ret
60
+ end
61
+
62
+ def hide_from_view(ordered_hash)
63
+ ordered_hash.each do |k,v|
64
+ ordered_hash.delete_if{|k,v| HIDE_FROM_VIEW.include?(k)}
65
+ end
66
+ return ordered_hash
67
+ end
68
+
69
+ # Exclude = ["op_status","assembly_template"]
70
+ IdentAdd = 2
71
+ def find_first_non_scalar(ordered_hash)
72
+ found = nil
73
+ keys = ordered_hash.keys
74
+ keys.each_with_index do |k,i|
75
+ val = ordered_hash[k]
76
+ if val.kind_of?(ViewPrettyPrintHash) or
77
+ (val.kind_of?(Array) and val.size > 0 and val.first.kind_of?(ViewPrettyPrintHash))
78
+ found = i
79
+ break
80
+ end
81
+ end
82
+ if found.nil?
83
+ empty_ordered_hash = ordered_hash.class.new
84
+ [ordered_hash,empty_ordered_hash,empty_ordered_hash]
85
+ else
86
+ [keys[0,found],keys[found,1],keys[found+1,keys.size-1]].map{|key_array|ordered_hash.slice(*key_array)}
87
+ end
88
+ end
89
+ def is_scalar_type?(x)
90
+ [String,Fixnum,Bignum].find{|t|x.kind_of?(t)}
91
+ end
92
+
93
+ def convert_to_string_form(val)
94
+ if val.kind_of?(Array)
95
+ "[#{val.map{|el|convert_to_string_form(el)}.join(",")}]"
96
+ elsif is_scalar_type?(val)
97
+ val.to_s
98
+ else #catchall
99
+ pp_form val
100
+ end
101
+ end
102
+ def pp_form(obj)
103
+ ret = String.new
104
+ PP.pp obj, ret
105
+ ret.chomp!
106
+ end
107
+
108
+ def ident_str(n)
109
+ Array.new(n, " ").join
110
+ end
111
+
112
+ #process elements that are not scalars
113
+ def proc_ordered_hash(ordered_hash)
114
+ updated_els = Hash.new
115
+ ordered_hash.each do |k,v|
116
+ unless is_scalar_type?(v)
117
+ updated_els[k] = convert_to_string_form(v)
118
+ end
119
+ end
120
+
121
+ ordered_hash.merge(updated_els)
122
+ end
123
+
124
+ def simple_value_render(ordered_hash,ident_info)
125
+
126
+ proc_ordered_hash = proc_ordered_hash(ordered_hash)
127
+
128
+ ident = ident_info[:ident]||0
129
+ first_prefix = (ident_info[:include_first_key] ?
130
+ (ident_str(ident+IdentAdd) + ordered_hash.keys.first + KeyValSeperator) : ident_str(ident))
131
+ first_suffix = ((ident_info[:include_first_key] or not ordered_hash.object_type) ? "" : " (#{ordered_hash.object_type})")
132
+ rest_prefix = ident_str(ident+IdentAdd)
133
+
134
+ template_bindings = {
135
+ :ordered_hash => proc_ordered_hash,
136
+ :first_prefix => first_prefix,
137
+ :first_suffix => first_suffix,
138
+ :rest_prefix => rest_prefix,
139
+ :sep => KeyValSeperator
140
+ }
141
+
142
+ SimpleListTemplate.result(template_bindings)
143
+ end
144
+ KeyValSeperator = ": "
145
+ SimpleListTemplate = Erubis::Eruby.new <<eos
146
+ <% keys = ordered_hash.keys %>
147
+ <% first = keys.shift %>
148
+ <%= rest_prefix %><%= first_prefix.strip %><%= ordered_hash[first] %>
149
+ <% keys.each do |k| %>
150
+ <%= rest_prefix %><%= k %><%= sep %><%= ordered_hash[k] %>
151
+ <% end %>
152
+ eos
153
+
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,309 @@
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
+ require 'hirb'
19
+ require 'ostruct'
20
+ require 'colorize'
21
+ require 'rest_client'
22
+ require 'json'
23
+
24
+ dtk_require("../config/disk_cacher")
25
+
26
+ # we override String here to give power to our mutators defined in TableDefintions
27
+ class String
28
+ def get_date
29
+ DateTime.parse(self).strftime('%H:%M:%S %d/%m/%y') unless self.nil?
30
+ end
31
+ end
32
+
33
+ # override OpenStruct to remove defintion for id
34
+ class DtkOpenStruct < OpenStruct
35
+ if RUBY_VERSION.match(/^1\.8\..*$/)
36
+ undef id
37
+ undef type
38
+ end
39
+ end
40
+
41
+ # [Haris]
42
+ # Elements with action column (taks status) have been removed since they are no longer in use. In case of bug that is relying
43
+ # on existance of element and logic, please contact me to resolve it.
44
+ #
45
+
46
+ module DTK
47
+ module Client
48
+ class ViewProcTablePrint < ViewProcessor
49
+ def render(data, command_clazz, data_type_clazz, forced_metadata=nil, print_error_table=false)
50
+ DtkResponse.new(data, data_type_clazz, forced_metadata, print_error_table).print
51
+ end
52
+ end
53
+
54
+ class DtkResponse
55
+
56
+ include Hirb::Console
57
+ include CommandBase
58
+ extend CommandBase
59
+ attr_accessor :command_name, :order_defintion, :evaluated_data
60
+
61
+ # when adding class to table view you need to define mapping and order to be displayed in table
62
+ # this can be fixed with facets, but that is todo for now TODO: use facets with ordered hashes
63
+
64
+ def initialize(data, data_type, forced_metadata, print_error_table)
65
+ # if there is no custom metadata, then we use metadata predefined in meta-response.json file
66
+
67
+ if forced_metadata.nil?
68
+ # get all table definitions from json file
69
+ @table_defintions = get_metadata()
70
+ # e.g. data type ASSEMBLY
71
+ @command_name = data_type
72
+ # e.g. ASSEMBLY => TableDefintions::ASSEMBLY
73
+ table_defintion = get_table_defintion(@command_name)
74
+ # e.g. ASSEMBLY => TableDefintions::ASSEMBLY_ORDER
75
+ @order_definition = get_table_defintion(@command_name, true)
76
+ else
77
+ # if there is custom metadata, check if it is in valid format
78
+ validate_forced_metadata(forced_metadata)
79
+
80
+ table_defintion = forced_metadata['mapping']
81
+ @order_definition = forced_metadata['order']
82
+ end
83
+
84
+ # if one defintion is missing we stop the execution
85
+ if table_defintion.nil? || @order_definition.nil?
86
+ raise DTK::Client::DtkError,"Missing table definition(s) for data type #{data_type}."
87
+ end
88
+
89
+ # transforms data to DtkOpenStruct
90
+ structured_data = []
91
+
92
+ # very important since rest of the code expect array to be used
93
+ data = [data] unless data.kind_of?(Array)
94
+
95
+ data.each do |data_element|
96
+ # special flag to filter out data not needed here
97
+ next if data_element['dtk_client_hidden']
98
+
99
+ structured_data << to_ostruct(data_element)
100
+ end
101
+
102
+ # we use array of OpenStruct to hold our evaluated values
103
+ @evaluated_data = []
104
+ @error_data = []
105
+ @action_data = []
106
+ structured_data.each do |structured_element|
107
+ evaluated_element = DtkOpenStruct.new
108
+ error_element = DtkOpenStruct.new
109
+
110
+ # based on mapping we set key = eval(value)
111
+ table_defintion.each do |k,v|
112
+ begin
113
+ # due to problems with space we have special way of handling error columns
114
+ # in such a way that those error will be specially printed later on
115
+
116
+ if print_error_table && k.include?('error')
117
+ error_message = value_of(structured_element, v)
118
+ server_error = nil
119
+
120
+ # here we see if there was an error if not we will skip this
121
+ # if so we add it to @error_data
122
+
123
+ if error_message.empty?
124
+ # no error message just add it as regular element
125
+ evaluated_element.send("#{k}=",value_of(structured_element, v))
126
+ else
127
+ error_index = ""
128
+ error_type = value_of(structured_element,'errors.dtk_type') || ""
129
+
130
+ val = value_of(structured_element,'dtk_type')||''
131
+ # extract e.g. 3.1.1.1 from '3.1.1.1 action' etc.
132
+ error_index = "[ #{val.scan( /\d+[,.]?\d?[,.]?\d?[,.]?\d?[,.]?\d?/ ).first} ]"
133
+
134
+ # original table takes that index
135
+ evaluated_element.send("#{k}=", error_index)
136
+ # we set new error element
137
+ error_element.id = error_index
138
+
139
+ if error_type == "user_error"
140
+ error_element.message = "[USER ERROR] " + error_message
141
+ elsif error_type == "test_error"
142
+ error_element.message = "[TEST ERROR] " + error_message
143
+ else
144
+ error_element.message = "[SERVER ERROR] " + error_message
145
+ end
146
+
147
+ # add it with other
148
+ @error_data << error_element
149
+ end
150
+ else
151
+ evaluated_element.send("#{k}=", value_of(structured_element, v))
152
+ # eval "evaluated_element.#{k}=structured_element.#{v}"
153
+ end
154
+ rescue NoMethodError => e
155
+ unless e.message.include? "nil:NilClass"
156
+ # when chaining comands there are situations where more complex strcture
157
+ # e.g. external_ref.region will not be there. So we are handling that case
158
+ # make sure when in development to disable this TODO: better solution needed
159
+ raise DTK::Client::DtkError,"Error with missing metadata occurred. There is a mistake in table metadata or unexpected data presented to table view."
160
+ end
161
+ end
162
+ end
163
+
164
+ @order_definition.delete('errors')
165
+
166
+ @evaluated_data << evaluated_element
167
+ end
168
+ end
169
+
170
+ def get_metadata
171
+ content = DiskCacher.new.fetch("table_metadata", ::DTK::Configuration.get(:meta_table_ttl))
172
+ raise DTK::Client::DtkError, "Table metadata is empty, please contact DTK team." if content.empty?
173
+ return JSON.parse(content)
174
+ end
175
+
176
+ def to_ostruct(data)
177
+ result = data.inject({}) do |res, (k, v)|
178
+ k = safe_name(k)
179
+ case v
180
+ when Hash
181
+ res.store(k, to_ostruct(v))
182
+ res
183
+ when Array
184
+ res.store(k, v.each { |el| Hash === el ? to_ostruct(el) : el })
185
+ res
186
+ else
187
+ res.store(k,v)
188
+ res
189
+ end
190
+ end
191
+
192
+ DtkOpenStruct.new(result)
193
+ end
194
+
195
+ def safe_name(identifier)
196
+ (identifier == 'id' || identifier == 'type') ? "dtk_#{identifier}" : identifier
197
+ end
198
+
199
+ def get_table_defintion(name,is_order=false)
200
+ begin
201
+ @table_defintions[name.downcase][(is_order ? 'order' : 'mapping')]
202
+ rescue NameError => e
203
+ return nil
204
+ end
205
+ end
206
+
207
+ # Check if custom metadata is sent in valid format
208
+ def validate_forced_metadata(forced_metadata)
209
+ # if custom metadata does not contain order(Array) or mapping(Hash),then it's not valid metadata
210
+ unless (forced_metadata['order'].nil? || forced_metadata['mapping'].nil?)
211
+ return if (forced_metadata['order'].class.eql?(Array) && forced_metadata['mapping'].class.eql?(Hash))
212
+ end
213
+
214
+ raise DTK::Client::DtkError,"Provided table definition is not valid. Please review your order and mapping for provided definition: \n #{forced_metadata.inspect}"
215
+ end
216
+
217
+ def filter_remove_underscore(field)
218
+
219
+ end
220
+
221
+ def print
222
+ filter_remove_underscore = Proc.new { |header| header.gsub('_',' ').upcase }
223
+ # hirb print out of our evaluated data in order defined
224
+ # Available options can be viewed here: http://tagaholic.me/hirb/doc/classes/Hirb/Helpers/Table.html#M000008
225
+ table(@evaluated_data,{:fields => @order_definition,:escape_special_chars => true, :resize => false, :vertical => false, :header_filter => filter_remove_underscore })
226
+
227
+ # in case there were error we print those errors
228
+ unless @error_data.empty?
229
+ printf "\nERRORS: \n\n"
230
+ #table(@error_data,{:fields => [ :id, :message ]})
231
+ @error_data.each do |error_row|
232
+ printf "%15s %s\n", error_row.id.colorize(:yellow), error_row.message.colorize(:red)
233
+ end
234
+ end
235
+
236
+ unless @action_data.empty?
237
+ printf " \n"
238
+ #table(@error_data,{:fields => [ :id, :message ]})
239
+ printed = []
240
+ @action_data.each do |action_row|
241
+ # printf "%15s\n"
242
+ # printf(" INFO: #{action_row.message.colorize(:yellow)} \n") #, action_row.id.colorize(:yellow), action_row.message.colorize(:yellow)
243
+ message = action_row.message
244
+ printf "%15s %s\n", "INFO:".colorize(:yellow), message.colorize(:yellow) unless printed.include?(message)
245
+ printed << message
246
+ end
247
+ end
248
+ end
249
+
250
+ private
251
+
252
+ # based on string sequence in mapped_command we are executing list of commands to follow
253
+ # so for value of "foo.bar.split('.').last" we will get 4 commands that will
254
+ # sequentaly be executed using values from previus results
255
+ def value_of(open_struct_object, mapped_command)
256
+ # split string by '.' delimiter keeping in mind to split when words only
257
+ commands = mapped_command.split(/\.(?=\w)/)
258
+
259
+ value = open_struct_object
260
+ commands.each do |command|
261
+ value = evaluate_command(value, command)
262
+ end
263
+ return value
264
+ end
265
+
266
+
267
+ def evaluate_command(value, command)
268
+ case
269
+ when command.include?('map{')
270
+ matched_data = command.match(/\['(.+)'\]/)
271
+
272
+ my_lambda = lambda{|_x| _x.map{|r|r["#{matched_data[1]}"]||[]}}
273
+ value = my_lambda.call(value)
274
+
275
+ raise DTK::Client::DtkError,"There is a mistake in table metadata: #{command.inspect}" if value.nil?
276
+ when command.include?('(')
277
+ # matches command and params e.g. split('.') => [1] split, [2] '.'
278
+ matched_data = command.match(/(.+)\((.+)\)/)
279
+ command, params = matched_data[1], matched_data[2]
280
+ value = value.send(command,params)
281
+ when command.include?('[')
282
+ # matches command such as first['foo']
283
+ matched_data = command.match(/(.+)\[(.+)\]/)
284
+ command, params = matched_data[1],matched_data[2]
285
+
286
+ value = evaluate_command(value,command)
287
+ value = value.send('[]',params)
288
+ when command.start_with?("list_")
289
+ matched_data = command.match(/list_(.+)/)
290
+
291
+ my_lambda = lambda{|_x| _x.map{|r|r["#{matched_data[1]}"]||[]}}
292
+ value = my_lambda.call(value)
293
+
294
+ raise DTK::Client::DtkError,"There is a mistake in table metadata: #{command.inspect}" if value.nil?
295
+ when command.start_with?("count_")
296
+ matched_data = command.match(/count_(.+)/)
297
+
298
+ my_lambda = lambda{|_x| _x.map{|r|r["#{matched_data[1]}"]||[]}.flatten.size}
299
+ value = my_lambda.call(value)
300
+
301
+ raise DTK::Client::DtkError,"There is a mistake in table metadata: #{command.inspect}" if value.nil?
302
+ else
303
+ value = value.send(command)
304
+ end
305
+ return value
306
+ end
307
+ end
308
+ end
309
+ end