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,412 @@
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 'git'
19
+ # monkey patch
20
+ class Git::Lib
21
+ public :command
22
+ end
23
+
24
+ module DTK
25
+ module Client
26
+ class GitAdapter
27
+ attr_accessor :git_repo
28
+
29
+ def initialize(repo_dir, local_branch_name = nil)
30
+
31
+ if DTK::Configuration.get(:debug_grit)
32
+ logger = Logger.new(STDOUT)
33
+ logger.level = Logger::INFO
34
+ @git_repo = Git.init(repo_dir, :log => logger)
35
+ else
36
+ @git_repo = Git.init(repo_dir)
37
+ end
38
+ # If we want to log GIT interaction
39
+ # @git_repo = Git.init(repo_dir, :log => Logger.new(STDOUT))
40
+ @local_branch_name = local_branch_name
41
+ end
42
+
43
+ def command(*args, &block)
44
+ @git_repo.lib.command(*args, &block)
45
+ end
46
+
47
+ def changed?
48
+ (!(changed().empty? && untracked().empty? && deleted().empty?) || staged_commits?)
49
+ end
50
+
51
+ def stage_changes()
52
+ handle_git_error do
53
+ @git_repo.add(untracked())
54
+ @git_repo.add(added())
55
+ @git_repo.add(changed())
56
+ end
57
+ deleted().each do |file|
58
+ begin
59
+ @git_repo.remove(file)
60
+ rescue
61
+ # ignore this error means file has already been staged
62
+ # we cannot support status of file, in 1.8.7 so this is
63
+ # solution for that
64
+ end
65
+ end
66
+ end
67
+
68
+ def print_status()
69
+ changes = [changed(), untracked(), deleted()]
70
+ puts "\nModified files:\n".colorize(:green) unless changes[0].empty?
71
+ changes[0].each { |item| puts "\t#{item}" }
72
+ puts "\nAdded files:\n".colorize(:yellow) unless changes[1].empty?
73
+ changes[1].each { |item| puts "\t#{item}" }
74
+ puts "\nDeleted files:\n".colorize(:red) unless changes[2].empty?
75
+ changes[2].each { |item| puts "\t#{item}" }
76
+ puts ""
77
+ end
78
+
79
+ def diff_summary(local_branch, remote_reference)
80
+ branch_local_obj = @git_repo.branches.local.find { |b| b.name == local_branch }
81
+ branch_remote_obj = @git_repo.branches.remote.find{|r| "#{r.remote}/#{r.name}" == remote_reference }
82
+
83
+ if branch_local_obj && branch_remote_obj
84
+
85
+ difference = @git_repo.diff(branch_local_obj, branch_remote_obj)
86
+
87
+ files_modified = difference.stats[:files] ? difference.stats[:files].keys.collect { |file| { :path => file }} : []
88
+ {
89
+ :files_modified => files_modified,
90
+ :are_there_changes => !files_modified.empty?
91
+ }
92
+ else
93
+ raise Error.new("Error finding branches: local branch '#{local_branch}' (found: #{!branch_local_obj.nil?}), remote branch '#{remote_reference}' (found: #{!branch_remote_obj.nil?})")
94
+ end
95
+ end
96
+
97
+ def diff_remote_summary(local_branch, remote_reference)
98
+ branch_local_obj = @git_repo.branches.local.find { |b| b.name == local_branch }
99
+ branch_remote_obj = @git_repo.branches.remote.find{|r| "#{r.remote}/#{r.name}" == remote_reference }
100
+
101
+ if branch_local_obj && branch_remote_obj
102
+ difference = @git_repo.lib.diff_full(branch_remote_obj, branch_local_obj)
103
+ # difference = @git_repo.diff(branch_remote_obj, branch_local_obj)
104
+ {
105
+ :diffs => difference
106
+ }
107
+ else
108
+ raise Error.new("Error finding branches: local branch '#{local_branch}' (found: #{!branch_local_obj.nil?}), remote branch '#{remote_reference}' (found: #{!branch_remote_obj.nil?})")
109
+ end
110
+ end
111
+
112
+ def local_summary()
113
+
114
+ {
115
+ :files_added => (untracked() + added()).collect { |file| { :path => file }},
116
+ :files_modified => changed().collect { |file| { :path => file }},
117
+ :files_deleted => deleted().collect { |file| { :path => file }},
118
+ :are_there_changes => something_changed?
119
+ }
120
+ end
121
+
122
+ def new_version()
123
+ return local_summary()
124
+ end
125
+
126
+ def stage_and_commit(commit_msg = "")
127
+ stage_changes()
128
+ commit(commit_msg)
129
+ end
130
+
131
+ def commit(commit_msg = "")
132
+ @git_repo.commit(commit_msg)
133
+ end
134
+
135
+ def add_remote(name, url)
136
+ @git_repo.remove_remote(name) if is_there_remote?(name)
137
+
138
+ @git_repo.add_remote(name, url)
139
+ end
140
+
141
+ def fetch(remote = 'origin')
142
+ @git_repo.fetch(remote)
143
+ end
144
+
145
+ def rev_list(commit_sha)
146
+ git_command('rev-list', commit_sha)
147
+ end
148
+
149
+ def staged_commits?()
150
+ response = git_command('diff','--cached')
151
+ !response.empty?
152
+ end
153
+
154
+ def rev_list_contains?(container_sha, index_sha)
155
+ results = rev_list(container_sha)
156
+ !results.split("\n").grep(index_sha).empty?
157
+ end
158
+
159
+ def head_commit_sha()
160
+ ret_local_branch.gcommit.sha
161
+ end
162
+
163
+ def find_remote_sha(ref)
164
+ remote = @git_repo.branches.remote.find{|r| "#{r.remote}/#{r.name}" == ref}
165
+ remote.gcommit.sha
166
+ end
167
+
168
+ def merge_relationship(type, ref, opts={})
169
+ ref_remote, ref_branch = ref.split('/')
170
+ # fetch remote branch
171
+ fetch(ref_remote) if opts[:fetch_if_needed]
172
+
173
+
174
+ git_reference = case type
175
+ when :remote_branch
176
+ @git_repo.branches.remote.find { |r| "#{r.remote}/#{r.name}" == ref }
177
+ when :local_branch
178
+ @git_repo.branches.find { |b| b.name == ref }
179
+ else
180
+ raise Error.new("Illegal type parameter (#{type}) passed to merge_relationship")
181
+ end
182
+
183
+ local_sha = ret_local_branch.gcommit.sha
184
+
185
+ opts[:ret_commit_shas][:local_sha] = local_sha if opts[:ret_commit_shas]
186
+
187
+ unless git_reference
188
+ return :no_remote_ref if type.eql?(:remote_branch)
189
+
190
+ raise Error.new("Cannot find git ref '#{ref}'")
191
+ end
192
+
193
+ git_reference_sha = git_reference.gcommit.sha
194
+ opts[:ret_commit_shas][:other_sha] = git_reference_sha if opts[:ret_commit_shas]
195
+
196
+ # shas can be different but content the same
197
+ if git_reference_sha.eql?(local_sha) || !any_differences?(local_sha, git_reference_sha)
198
+ :equal
199
+ else
200
+ if rev_list_contains?(local_sha, git_reference_sha)
201
+ :local_ahead
202
+ elsif rev_list_contains?(git_reference_sha, local_sha)
203
+ :local_behind
204
+ else
205
+ :branchpoint
206
+ end
207
+ end
208
+ end
209
+
210
+ def delete_branch(branch, opts = {})
211
+ @git_repo.branch(branch).delete
212
+ end
213
+
214
+ def checkout(branch, opts = {})
215
+ @git_repo.checkout(branch, opts)
216
+ end
217
+
218
+ def push(remote_branch_ref, opts={})
219
+ remote, remote_branch = remote_branch_ref.split('/')
220
+ push_with_remote(remote, remote_branch, opts)
221
+ end
222
+
223
+ def push_with_remote(remote, remote_branch, opts={})
224
+ branch_for_push = "#{local_branch_name}:refs/heads/#{remote_branch||local_branch_name}"
225
+ @git_repo.push(remote, branch_for_push, opts)
226
+ end
227
+
228
+ def add_file(file_rel_path, content)
229
+ content ||= String.new
230
+ file_path = "#{@git_repo.dir}/#{file_rel_path}"
231
+ File.open(file_path,"w"){|f|f << content}
232
+ @git_repo.add(file_path)
233
+ end
234
+
235
+ def pull_remote_to_local(remote_branch, local_branch, remote='origin')
236
+ # special case; if no branches and local_branch differs from master
237
+ # creates master plus local_branch
238
+ # special_case must be calculated before pull
239
+ special_case = current_branch().nil? and local_branch != 'master'
240
+ @git_repo.pull(remote,"#{remote_branch}:#{local_branch}")
241
+ if special_case
242
+ @git_repo.branch(local_branch).checkout
243
+ @git_repo.branch('master').delete
244
+ end
245
+ end
246
+
247
+ def merge(remote_branch_ref)
248
+ @git_repo.merge(remote_branch_ref)
249
+ end
250
+
251
+ def self.clone(repo_url, target_path, branch, opts={})
252
+ git_base = handle_git_error{Git.clone(repo_url, target_path)}
253
+
254
+ unless branch.nil?
255
+ if opts[:track_remote_branch]
256
+ # This just tracks remote branch
257
+ begin
258
+ git_base.checkout(branch)
259
+ rescue => e
260
+ # TODO: see if any other kind of error
261
+ raise DtkError.new("The branch or tag '#{branch}' does not exist on repo '#{repo_url}'")
262
+ end
263
+ else
264
+ # This wil first create a remote branch;
265
+ # TODO: this might be wrong and should be deprecated
266
+ git_base.branch(branch).checkout
267
+ end
268
+ end
269
+ git_base
270
+ end
271
+
272
+ def repo_dir
273
+ @git_repo.dir.path
274
+ end
275
+
276
+ def repo_exists?
277
+ File.exists?(repo_dir)
278
+ end
279
+
280
+ def local_branch_name
281
+ ret_local_branch.name
282
+ end
283
+
284
+ def ret_local_branch
285
+ # This build in assumption that just one local branch
286
+ unless ret = current_branch()
287
+ raise Error.new("Unexpected that current_branch() is nil")
288
+ end
289
+ if @local_branch_name
290
+ unless ret.name == @local_branch_name
291
+ raise Error.new("Unexpected that @local_branch_name (#{@local_branch_name}) does not equal current branch (#{current_branch()})")
292
+ end
293
+ end
294
+ ret
295
+ end
296
+
297
+ def current_branch()
298
+ @git_repo.branches.local.find { |b| b.current }
299
+ end
300
+
301
+ TEMP_BRANCH = "temp_branch"
302
+
303
+ def merge_theirs(remote_branch_ref)
304
+ branch = local_branch_name
305
+
306
+ # Git is not agile enoguh to work with following commands so we are using native commands to achive this
307
+ Dir.chdir(repo_dir) do
308
+ OsUtil.suspend_output do
309
+ puts `git checkout -b #{TEMP_BRANCH} #{remote_branch_ref}`
310
+ puts `git merge #{branch} -s ours`
311
+ puts `git checkout #{branch}`
312
+ puts `git reset #{TEMP_BRANCH} --hard`
313
+ puts `git branch -D #{TEMP_BRANCH}`
314
+ end
315
+ end
316
+ end
317
+
318
+ def reset_hard(current_branch_sha)
319
+ @git_repo.reset_hard(current_branch_sha)
320
+ end
321
+
322
+ private
323
+ def handle_git_error(&block)
324
+ self.class.handle_git_error(&block)
325
+ end
326
+ def self.handle_git_error(&block)
327
+ ret = nil
328
+ begin
329
+ ret = yield
330
+ rescue => e
331
+ unless e.respond_to?(:message)
332
+ raise e
333
+ else
334
+ err_msg = e.message
335
+ lines = err_msg.split("\n")
336
+ if lines.last =~ GitErrorPattern
337
+ err_msg = error_msg_when_git_error(lines)
338
+ end
339
+ raise DtkError.new(err_msg)
340
+ end
341
+ end
342
+ ret
343
+ end
344
+ GitErrorPattern = /^fatal:/
345
+ def self.error_msg_when_git_error(lines)
346
+ ret = lines.last.gsub(GitErrorPattern,'').strip()
347
+ # TODO start putting in special cases here
348
+ if ret =~ /adding files failed/
349
+ if lines.first =~ /\.git/
350
+ ret = "Cannot add files that are in a .git directory; remove any nested .git directory"
351
+ end
352
+ end
353
+ ret
354
+ end
355
+
356
+ # Method bellow show different behavior when working with 1.8.7
357
+ # so based on Hash response we know it it is:
358
+ # Hash => 1.9.3 +
359
+ # Array => 1.8.7
360
+ #
361
+
362
+ def changed
363
+ status.is_a?(Hash) ? status.changed().keys : status.changed().collect { |file| file.first }
364
+ end
365
+
366
+ def untracked
367
+ status.is_a?(Hash) ? status.untracked().keys : status.untracked().collect { |file| file.first }
368
+ end
369
+
370
+ def deleted
371
+ status.is_a?(Hash) ? status.deleted().keys : status.deleted().collect { |file| file.first }
372
+ end
373
+
374
+ def added
375
+ status.is_a?(Hash) ? status.added().keys : status.added().collect { |file| file.first }
376
+ end
377
+
378
+ def something_changed?
379
+ ![changed, untracked, deleted, added].flatten.empty?
380
+ end
381
+
382
+ def status
383
+ @git_repo.status
384
+ end
385
+
386
+ def is_there_remote?(remote_name)
387
+ @git_repo.remotes.find { |r| r.name == remote_name }
388
+ end
389
+
390
+ def any_differences?(sha1, sha2)
391
+ @git_repo.diff(sha1, sha2).size > 0
392
+ end
393
+
394
+ def git_command(cmd, opts=[])
395
+ ENV['GIT_DIR'] = "#{@git_repo.dir.path}/.git"
396
+ ENV['GIT_INDEX_FILE'] = @git_repo.index.path
397
+
398
+ path = @git_repo.dir.path
399
+
400
+ opts = [opts].flatten.join(' ')
401
+
402
+ response = `git #{cmd} #{opts}`.chomp
403
+
404
+ ENV.delete('GIT_DIR')
405
+ ENV.delete('GIT_INDEX_FILE')
406
+
407
+ return response
408
+ end
409
+
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,64 @@
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
+
19
+ module DTK
20
+ module Client
21
+
22
+ class GitHandledException < Exception
23
+ def initialize(msg, backtrace)
24
+ super(msg)
25
+ set_backtrace(backtrace)
26
+ end
27
+ end
28
+
29
+ class GitErrorHandler
30
+
31
+ # due to problems with git logging messages which are not user friendly we are going to wrap their error and try to produce more readable results
32
+ def self.handle(exception)
33
+ handled_exception = exception
34
+
35
+ if exception.is_a? Git::GitExecuteError
36
+ error_message = user_friendly_message(exception.message)
37
+ handled_exception = GitHandledException.new(error_message, exception.backtrace)
38
+ end
39
+
40
+ handled_exception
41
+ end
42
+
43
+ private
44
+
45
+ def self.user_friendly_message(message)
46
+ case message
47
+ when /repository not found/i
48
+ "Repository not found"
49
+ when /repository (.*) not found/i
50
+ "Repository #{$1.strip()} not found"
51
+ when /destination path (.*) already exists/i
52
+ "Destination folder #{$1.strip()} already exists"
53
+ when /Authentication failed for (.*)$/i
54
+ "Authentication failed for given repository #{$1.strip()}"
55
+ when /timed out/
56
+ "Timeout - not able to contact remote"
57
+ else
58
+ message
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end