dtk-shell 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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