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.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/Gemfile_dev +13 -0
- data/README.md +121 -0
- data/bin/dtk-execute +32 -0
- data/bin/dtk-run +92 -0
- data/bin/dtk-shell +31 -0
- data/dtk-shell.gemspec +50 -0
- data/lib/auxiliary.rb +61 -0
- data/lib/bundler_monkey_patch.rb +26 -0
- data/lib/client.rb +58 -0
- data/lib/command_helper.rb +33 -0
- data/lib/command_helpers/git_repo.rb +589 -0
- data/lib/command_helpers/git_repo/merge.rb +153 -0
- data/lib/command_helpers/jenkins_client.rb +106 -0
- data/lib/command_helpers/jenkins_client/config_xml.rb +288 -0
- data/lib/command_helpers/service_importer.rb +251 -0
- data/lib/command_helpers/service_link.rb +33 -0
- data/lib/command_helpers/test_module_creator.rb +69 -0
- data/lib/command_helpers/test_module_templates/dtk.model.yaml.eruby +10 -0
- data/lib/command_helpers/test_module_templates/spec_helper.rb.eruby +10 -0
- data/lib/command_helpers/test_module_templates/temp_component_spec.rb.eruby +5 -0
- data/lib/commands.rb +57 -0
- data/lib/commands/common/thor/access_control.rb +133 -0
- data/lib/commands/common/thor/action_result_handler.rb +74 -0
- data/lib/commands/common/thor/assembly_template.rb +92 -0
- data/lib/commands/common/thor/assembly_workspace.rb +1801 -0
- data/lib/commands/common/thor/base_command_helper.rb +59 -0
- data/lib/commands/common/thor/clone.rb +82 -0
- data/lib/commands/common/thor/common.rb +88 -0
- data/lib/commands/common/thor/common_base.rb +49 -0
- data/lib/commands/common/thor/create_target.rb +70 -0
- data/lib/commands/common/thor/edit.rb +255 -0
- data/lib/commands/common/thor/inventory_parser.rb +98 -0
- data/lib/commands/common/thor/list_diffs.rb +128 -0
- data/lib/commands/common/thor/module.rb +1011 -0
- data/lib/commands/common/thor/module/import.rb +210 -0
- data/lib/commands/common/thor/node.rb +53 -0
- data/lib/commands/common/thor/poller.rb +65 -0
- data/lib/commands/common/thor/pull_clone_changes.rb +28 -0
- data/lib/commands/common/thor/pull_from_remote.rb +152 -0
- data/lib/commands/common/thor/puppet_forge.rb +72 -0
- data/lib/commands/common/thor/purge_clone.rb +101 -0
- data/lib/commands/common/thor/push_clone_changes.rb +162 -0
- data/lib/commands/common/thor/push_to_remote.rb +94 -0
- data/lib/commands/common/thor/remotes.rb +71 -0
- data/lib/commands/common/thor/reparse.rb +40 -0
- data/lib/commands/common/thor/set_required_attributes.rb +46 -0
- data/lib/commands/thor/account.rb +239 -0
- data/lib/commands/thor/assembly.rb +356 -0
- data/lib/commands/thor/attribute.rb +79 -0
- data/lib/commands/thor/component.rb +70 -0
- data/lib/commands/thor/component_module.rb +501 -0
- data/lib/commands/thor/component_template.rb +174 -0
- data/lib/commands/thor/dependency.rb +34 -0
- data/lib/commands/thor/developer.rb +144 -0
- data/lib/commands/thor/dtk.rb +152 -0
- data/lib/commands/thor/library.rb +125 -0
- data/lib/commands/thor/node.rb +504 -0
- data/lib/commands/thor/node_template.rb +94 -0
- data/lib/commands/thor/project.rb +34 -0
- data/lib/commands/thor/provider.rb +233 -0
- data/lib/commands/thor/remotes.rb +49 -0
- data/lib/commands/thor/service.rb +941 -0
- data/lib/commands/thor/service_module.rb +914 -0
- data/lib/commands/thor/state_change.rb +25 -0
- data/lib/commands/thor/target.rb +250 -0
- data/lib/commands/thor/task.rb +116 -0
- data/lib/commands/thor/test_module.rb +310 -0
- data/lib/commands/thor/utils.rb +21 -0
- data/lib/commands/thor/workspace.rb +685 -0
- data/lib/config/cacert.pem +3785 -0
- data/lib/config/client.conf.header +20 -0
- data/lib/config/configuration.rb +99 -0
- data/lib/config/default.conf +16 -0
- data/lib/config/disk_cacher.rb +80 -0
- data/lib/configurator.rb +176 -0
- data/lib/context_router.rb +44 -0
- data/lib/core.rb +497 -0
- data/lib/domain/git_adapter.rb +412 -0
- data/lib/domain/git_error_handler.rb +64 -0
- data/lib/domain/response.rb +285 -0
- data/lib/domain/response/error_handler.rb +86 -0
- data/lib/dtk-shell/version.rb +20 -0
- data/lib/dtk_constants.rb +40 -0
- data/lib/dtk_error.rb +114 -0
- data/lib/dtk_logger.rb +126 -0
- data/lib/dtk_shell.rb +31 -0
- data/lib/error.rb +85 -0
- data/lib/execute.rb +29 -0
- data/lib/execute/cli_pure/cli_rerouter.rb +102 -0
- data/lib/execute/command.rb +40 -0
- data/lib/execute/command/api_call.rb +60 -0
- data/lib/execute/command/api_call/map.rb +60 -0
- data/lib/execute/command/api_call/service.rb +91 -0
- data/lib/execute/command/api_call/translation_term.rb +119 -0
- data/lib/execute/command/rest_call.rb +37 -0
- data/lib/execute/command_processor.rb +30 -0
- data/lib/execute/command_processor/rest_call.rb +59 -0
- data/lib/execute/error_usage.rb +21 -0
- data/lib/execute/execute_context.rb +86 -0
- data/lib/execute/execute_context/result_store.rb +37 -0
- data/lib/execute/script.rb +64 -0
- data/lib/execute/script/add_tenant.rb +121 -0
- data/lib/git-logs/git.log +0 -0
- data/lib/parser/adapters/option_parser.rb +70 -0
- data/lib/parser/adapters/thor.rb +555 -0
- data/lib/parser/adapters/thor/common_option_defs.rb +40 -0
- data/lib/require_first.rb +104 -0
- data/lib/search_hash.rb +44 -0
- data/lib/shell.rb +261 -0
- data/lib/shell/context.rb +1065 -0
- data/lib/shell/context_aux.rb +46 -0
- data/lib/shell/domain/active_context.rb +186 -0
- data/lib/shell/domain/context_entity.rb +89 -0
- data/lib/shell/domain/context_params.rb +223 -0
- data/lib/shell/domain/override_tasks.rb +88 -0
- data/lib/shell/domain/shadow_entity.rb +76 -0
- data/lib/shell/header_shell.rb +44 -0
- data/lib/shell/help_monkey_patch.rb +283 -0
- data/lib/shell/interactive_wizard.rb +225 -0
- data/lib/shell/message_queue.rb +63 -0
- data/lib/shell/parse_monkey_patch.rb +39 -0
- data/lib/shell/status_monitor.rb +124 -0
- data/lib/task_status.rb +83 -0
- data/lib/task_status/refresh_mode.rb +77 -0
- data/lib/task_status/snapshot_mode.rb +28 -0
- data/lib/task_status/stream_mode.rb +48 -0
- data/lib/task_status/stream_mode/element.rb +101 -0
- data/lib/task_status/stream_mode/element/format.rb +101 -0
- data/lib/task_status/stream_mode/element/hierarchical_task.rb +100 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/result.rb +72 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/result/action.rb +93 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/result/components.rb +26 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/result/node_level.rb +26 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/steps.rb +34 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/steps/action.rb +53 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/steps/components.rb +53 -0
- data/lib/task_status/stream_mode/element/hierarchical_task/steps/node_level.rb +42 -0
- data/lib/task_status/stream_mode/element/no_results.rb +26 -0
- data/lib/task_status/stream_mode/element/render.rb +59 -0
- data/lib/task_status/stream_mode/element/stage.rb +84 -0
- data/lib/task_status/stream_mode/element/stage/render.rb +76 -0
- data/lib/task_status/stream_mode/element/task_end.rb +35 -0
- data/lib/task_status/stream_mode/element/task_start.rb +37 -0
- data/lib/util/common_util.rb +37 -0
- data/lib/util/console.rb +235 -0
- data/lib/util/dtk_puppet.rb +65 -0
- data/lib/util/module_util.rb +66 -0
- data/lib/util/os_util.rb +385 -0
- data/lib/util/permission_util.rb +31 -0
- data/lib/util/remote_dependency_util.rb +84 -0
- data/lib/util/ssh_util.rb +94 -0
- data/lib/view_processor.rb +129 -0
- data/lib/view_processor/augmented_simple_list.rb +44 -0
- data/lib/view_processor/hash_pretty_print.rb +123 -0
- data/lib/view_processor/simple_list.rb +156 -0
- data/lib/view_processor/table_print.rb +309 -0
- data/lib/violation.rb +86 -0
- data/lib/violation/attribute.rb +76 -0
- data/lib/violation/fix.rb +26 -0
- data/lib/violation/fix/result.rb +73 -0
- data/lib/violation/fix/result/error.rb +34 -0
- data/lib/violation/fix/set_attribute.rb +41 -0
- data/lib/violation/sub_classes.rb +60 -0
- data/puppet/manifests/init.pp +72 -0
- data/puppet/manifests/params.pp +16 -0
- data/puppet/r8meta.puppet.yml +35 -0
- data/puppet/templates/bash_profile.erb +2 -0
- data/puppet/templates/client.conf.erb +1 -0
- data/puppet/templates/dtkclient.erb +2 -0
- data/spec/component_module_spec.rb +34 -0
- data/spec/dependency_spec.rb +6 -0
- data/spec/dtk_shell_spec.rb +13 -0
- data/spec/dtk_spec.rb +33 -0
- data/spec/lib/spec_helper.rb +10 -0
- data/spec/lib/spec_thor.rb +108 -0
- data/spec/node_template_spec.rb +24 -0
- data/spec/project_spec.rb +6 -0
- data/spec/repo_spec.rb +7 -0
- data/spec/response_spec.rb +52 -0
- data/spec/service_module_spec.rb +38 -0
- data/spec/service_spec.rb +50 -0
- data/spec/state_change_spec.rb +7 -0
- data/spec/table_print_spec.rb +48 -0
- data/spec/target_spec.rb +57 -0
- data/spec/task_spec.rb +28 -0
- data/views/assembly/augmented_simple_list.rb +12 -0
- data/views/assembly_template/augmented_simple_list.rb +12 -0
- data/views/list_task/augmented_simple_list.rb +12 -0
- 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
|