dtk-client 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.license_header +15 -0
  4. data/LICENSE +202 -0
  5. data/README.md +25 -2
  6. data/Rakefile +17 -1
  7. data/bin/dtk +18 -1
  8. data/lib/cli/command/account/add_ssh_key.rb +40 -0
  9. data/lib/cli/command/account/delete_ssh_key.rb +43 -0
  10. data/lib/cli/command/account/list_ssh_keys.rb +31 -0
  11. data/lib/cli/command/account/register_catalog_user.rb +31 -0
  12. data/lib/cli/command/account/set_catalog_credentials.rb +31 -0
  13. data/lib/cli/command/account/set_password.rb +31 -0
  14. data/lib/cli/command/account.rb +31 -0
  15. data/lib/cli/command/mixin.rb +1 -1
  16. data/lib/cli/command/module/delete_from_remote.rb +36 -0
  17. data/lib/cli/command/module/install.rb +15 -5
  18. data/lib/cli/command/module/publish.rb +34 -0
  19. data/lib/cli/command/module/pull_dtkn.rb +35 -0
  20. data/lib/cli/command/module/push_dtkn.rb +34 -0
  21. data/lib/cli/command/module/stage.rb +1 -1
  22. data/lib/cli/command/module/uninstall.rb +13 -7
  23. data/lib/cli/command/module.rb +14 -1
  24. data/lib/cli/command/options.rb +2 -0
  25. data/lib/cli/command/service/converge.rb +1 -1
  26. data/lib/cli/command/service/delete.rb +1 -1
  27. data/lib/cli/command/service/exec.rb +5 -2
  28. data/lib/cli/command/service/exec_sync.rb +4 -1
  29. data/lib/cli/command/service/{list_dependent_modules.rb → list_dependencies.rb} +3 -3
  30. data/lib/cli/command/service/uninstall.rb +11 -4
  31. data/lib/cli/command/service.rb +1 -1
  32. data/lib/cli/command/token.rb +3 -0
  33. data/lib/cli/command.rb +1 -1
  34. data/lib/cli/context/attributes.rb +1 -1
  35. data/lib/cli/context/type/account.rb +42 -0
  36. data/lib/cli/context/type/module.rb +2 -1
  37. data/lib/cli/context/type/service.rb +2 -1
  38. data/lib/cli/context.rb +82 -12
  39. data/lib/cli/version.rb +18 -2
  40. data/lib/client/git_repo/adapter/git_gem.rb +62 -4
  41. data/lib/client/git_repo.rb +33 -2
  42. data/lib/client/load_source/component_info.rb +44 -0
  43. data/lib/client/load_source/service_info.rb +47 -0
  44. data/lib/client/load_source.rb +148 -0
  45. data/lib/client/{util/module_ref.rb → module_ref.rb} +19 -0
  46. data/lib/client/operation/account/add_ssh_key.rb +47 -0
  47. data/lib/client/operation/account/delete_ssh_key.rb +41 -0
  48. data/lib/client/operation/account/list_ssh_keys.rb +28 -0
  49. data/lib/client/operation/account/register_catalog_user.rb +49 -0
  50. data/lib/client/operation/account/set_catalog_credentials.rb +32 -0
  51. data/lib/client/operation/account/set_password.rb +59 -0
  52. data/lib/client/operation/account.rb +7 -4
  53. data/lib/client/operation/client_module_dir/git_repo/internal/dtkn.rb +83 -0
  54. data/lib/client/operation/client_module_dir/git_repo/internal.rb +328 -0
  55. data/lib/client/operation/client_module_dir/git_repo.rb +73 -249
  56. data/lib/client/operation/client_module_dir.rb +2 -2
  57. data/lib/client/operation/module/clone_module.rb +41 -25
  58. data/lib/client/operation/module/delete_from_remote.rb +79 -0
  59. data/lib/client/operation/module/install/common_module.rb +10 -21
  60. data/lib/client/operation/module/install/dependent_modules/component_dependency_tree/cache.rb +47 -0
  61. data/lib/client/operation/module/install/dependent_modules/component_dependency_tree/resolve_modules.rb +69 -0
  62. data/lib/client/operation/module/install/dependent_modules/component_dependency_tree.rb +143 -0
  63. data/lib/client/operation/module/install/dependent_modules/component_module.rb +103 -0
  64. data/lib/client/operation/module/install/dependent_modules/prompt_helper.rb +54 -0
  65. data/lib/client/operation/module/install/dependent_modules.rb +65 -0
  66. data/lib/client/operation/module/install/mixin.rb +42 -0
  67. data/lib/client/operation/module/install/module_ref.rb +48 -0
  68. data/lib/client/operation/module/install/print_helper.rb +129 -0
  69. data/lib/client/operation/module/install.rb +68 -25
  70. data/lib/client/operation/module/install_from_catalog.rb +23 -32
  71. data/lib/client/operation/module/list.rb +4 -1
  72. data/lib/client/operation/module/publish.rb +78 -0
  73. data/lib/client/operation/module/pull_dtkn.rb +76 -0
  74. data/lib/client/operation/module/push.rb +16 -2
  75. data/lib/client/operation/module/push_dtkn/convert_source/component_info.rb +42 -0
  76. data/lib/client/operation/module/push_dtkn/convert_source/service_info.rb +47 -0
  77. data/lib/client/operation/module/push_dtkn/convert_source.rb +155 -0
  78. data/lib/client/operation/module/push_dtkn.rb +79 -0
  79. data/lib/client/operation/module/stage.rb +3 -2
  80. data/lib/client/operation/module/uninstall.rb +36 -0
  81. data/lib/client/operation/module.rb +23 -4
  82. data/lib/client/operation/service/converge.rb +3 -2
  83. data/lib/client/operation/service/delete.rb +2 -1
  84. data/lib/client/operation/service/destroy.rb +1 -1
  85. data/lib/client/operation/service/exec.rb +4 -0
  86. data/lib/client/operation/service/{list_dependent_modules.rb → list_dependencies.rb} +1 -1
  87. data/lib/client/operation/service/stage.rb +1 -1
  88. data/lib/client/operation/service/uninstall.rb +3 -3
  89. data/lib/client/operation/service.rb +1 -1
  90. data/lib/client/service_and_component_info/transform_from/info/component.rb +57 -0
  91. data/lib/client/service_and_component_info/transform_from/info/service.rb +53 -0
  92. data/lib/client/service_and_component_info/transform_from/info.rb +84 -0
  93. data/lib/client/service_and_component_info/transform_from.rb +47 -0
  94. data/lib/client/service_and_component_info/transform_to/info/component.rb +53 -0
  95. data/lib/client/service_and_component_info/transform_to/info/service.rb +49 -0
  96. data/lib/client/service_and_component_info/transform_to/info.rb +111 -0
  97. data/lib/client/service_and_component_info/transform_to.rb +49 -0
  98. data/lib/client/service_and_component_info.rb +26 -0
  99. data/lib/client/util/console.rb +22 -0
  100. data/lib/client/util/interactive_wizard.rb +90 -0
  101. data/lib/client/util.rb +18 -2
  102. data/lib/dtk_client.rb +5 -2
  103. metadata +63 -15
  104. data/lib/client/content_generator.rb +0 -189
  105. data/lib/client/operation/module/install/external_module.rb +0 -205
@@ -0,0 +1,59 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK::Client
19
+ class Operation::Account
20
+ class SetPassword < self
21
+ def self.execute(args = Args.new)
22
+ old_pass_prompt, old_pass, new_pass_prompt, confirm_pass_prompt = nil
23
+ cred_file = Configurator::CRED_FILE
24
+ old_pass = DTK::Client::Configurator.parse_key_value_file(cred_file)[:password]
25
+ username = DTK::Client::Configurator.parse_key_value_file(cred_file)[:username]
26
+
27
+ if old_pass.nil?
28
+ OsUtil.print("Unable to retrieve your current password!", :yellow)
29
+ return
30
+ end
31
+
32
+ 3.times do
33
+ old_pass_prompt = DTK::Client::Console.password_prompt("Enter old password: ")
34
+
35
+ break if (old_pass.eql?(old_pass_prompt) || old_pass_prompt.nil?)
36
+ OsUtil.print("Incorrect old password!", :yellow)
37
+ end
38
+ return unless old_pass.eql?(old_pass_prompt)
39
+
40
+ new_pass_prompt = DTK::Client::Console.password_prompt("Enter new password: ")
41
+ return if new_pass_prompt.nil?
42
+ confirm_pass_prompt = DTK::Client::Console.password_prompt("Confirm new password: ")
43
+
44
+ if new_pass_prompt.eql?(confirm_pass_prompt)
45
+ post_body = {:new_password => new_pass_prompt}
46
+ response = rest_post("#{RoutePrefix}/set_password", post_body)
47
+ return response unless response.ok?
48
+
49
+ Configurator.regenerate_conf_file(cred_file, [['username', "#{username.to_s}"], ['password', "#{new_pass_prompt.to_s}"]], '')
50
+ OsUtil.print("Password changed successfully!", :yellow)
51
+ else
52
+ OsUtil.print("Entered passwords don't match!", :yellow)
53
+ return
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -19,13 +19,16 @@ module DTK::Client
19
19
  class Operation
20
20
  class Account < self
21
21
  RoutePrefix = 'account'
22
+ OPERATIONS = [:list_ssh_keys, :delete_ssh_key, :add_ssh_key, :set_password, :set_catalog_credentials, :register_catalog_user]
23
+ OPERATIONS.each { |operation| require_relative("#{RoutePrefix}/#{operation}") }
22
24
 
25
+
26
+ extend ModuleServiceCommon::ClassMixin
23
27
  # opts can have keys
24
28
  # :first_registration - Booelan (default: false)
25
29
  # :name - (default: 'dtk-client')
26
30
  def self.add_key(path_to_key, opts = {})
27
31
  match, matched_username = nil, nil
28
-
29
32
  unless File.file?(path_to_key)
30
33
  raise Error,"[ERROR] No ssh key file found at (#{path_to_key}). Path is wrong or it is necessary to generate the public rsa key (e.g., run `ssh-keygen -t rsa`)."
31
34
  end
@@ -51,13 +54,13 @@ module DTK::Client
51
54
  name = opts[:name] || 'dtk-client'
52
55
 
53
56
  rsa_pub_key = SSHUtil.read_and_validate_pub_key(path_to_key)
54
-
57
+
55
58
  post_body = {
56
59
  :rsa_pub_key => rsa_pub_key.chomp,
57
- :username? => name && name.chomp,
60
+ :username => name && name.chomp,
58
61
  :first_registration => first_registration,
59
62
  }
60
- rest_post "#{RoutePrefix}/add_user_direct_access", PostBody.new(post_body)
63
+ response = rest_post("#{RoutePrefix}/add_user_direct_access", post_body)
61
64
  end
62
65
  end
63
66
  end
@@ -0,0 +1,83 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK::Client
19
+ class Operation::ClientModuleDir::GitRepo
20
+ class Internal
21
+ class Dtkn
22
+ def initialize(info_type, repo_dir)
23
+ @info_type = validate_info_type(info_type)
24
+ @repo = Internal.create_empty_git_repo?(repo_dir, :branch => local_branch)
25
+ end
26
+ private :initialize
27
+
28
+ # returns object of type self
29
+ # opts can have keys
30
+ # :add_remote - if set has the remote url
31
+ def self.repo_with_remote(info_type, repo_dir, opts = {})
32
+ remote_url = opts[:add_remote]
33
+
34
+ repo_with_remote = new(info_type, repo_dir)
35
+ repo_with_remote.add_remote(remote_url) if remote_url
36
+ repo_with_remote
37
+ end
38
+
39
+ def add_remote(remote_url)
40
+ Internal.add_remote(@repo, remote_name, remote_url)
41
+ end
42
+
43
+ def fetch
44
+ Internal.fetch(@repo, remote_name)
45
+ end
46
+
47
+ # opts can have keys
48
+ # :no_commit
49
+ def merge_from_remote(remote_branch, opts = {})
50
+ merge_from_ref = "#{remote_name}/#{remote_branch}"
51
+ Internal.merge(@repo, merge_from_ref, :no_commit => opts[:no_commit])
52
+ end
53
+
54
+ private
55
+
56
+ # TODO: These constants used in Internal; Deprecate GIT_REMOTE amd LOCAL_BRANCH for remote_name and local_branch
57
+ GIT_REMOTE = 'dtkn'
58
+ LOCAL_BRANCH = 'master'
59
+
60
+ GIT_REMOTES = {
61
+ :service_info => GIT_REMOTE,
62
+ :component_info => 'dtkn-component-info'
63
+ }
64
+ def remote_name
65
+ GIT_REMOTES[@info_type]
66
+ end
67
+
68
+ def self.local_branch
69
+ LOCAL_BRANCH
70
+ end
71
+ def local_branch
72
+ self.class.local_branch
73
+ end
74
+
75
+ def validate_info_type(info_type)
76
+ raise Error, "Bad info_type '#{info_type}'" unless GIT_REMOTES.keys.include?(info_type)
77
+ info_type
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,328 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK::Client
19
+ class Operation::ClientModuleDir
20
+ class GitRepo
21
+ # All Internal methods do not have wrap_operation and can only be accessed by a method that wraps it
22
+ class Internal < self
23
+ require_relative('internal/dtkn')
24
+
25
+ # TODO: move dtkn methods to Internal::Dtkn; might make also Internal::DtkServer class
26
+
27
+ # Git Params for dtk server
28
+ module Dtk_Server
29
+ GIT_REMOTE = 'dtk-server'
30
+ end
31
+
32
+ # opts can have keys
33
+ # :branch
34
+ # returns object of type DTK::Client::GitRepo
35
+ def self.create_empty_git_repo?(repo_dir, opts = {})
36
+ git_repo.new(repo_dir, :branch => opts[:branch])
37
+ end
38
+
39
+ # returns head_sha
40
+ def self.empty_commit(repo, commit_msg = nil)
41
+ repo.empty_commit(commit_msg)
42
+ repo.head_commit_sha
43
+ end
44
+
45
+ def self.add_remote(repo, remote_name, remote_url)
46
+ repo.add_remote(remote_name, remote_url)
47
+ remote_name
48
+ end
49
+
50
+ def self.fetch(repo, remote_name)
51
+ repo.fetch(remote_name)
52
+ end
53
+
54
+ # opts can have keys
55
+ # :no_commit
56
+ def self.merge(repo, merge_from_ref, opts = {})
57
+ base_sha = repo.head_commit_sha
58
+ repo.merge(merge_from_ref)
59
+ # the git gem does not take no_commit as merge argument; so doing it with soft reset
60
+ repo.reset_soft(base_sha) if opts[:no_commit]
61
+ repo.head_commit_sha
62
+ end
63
+
64
+ def self.checkout_branch__return_repo(repo_dir, local_branch, opts = {})
65
+ repo = create_empty_git_repo?(repo_dir, :branch => local_branch)
66
+ repo.checkout(local_branch)
67
+ repo
68
+ end
69
+
70
+ # opts can have keys:
71
+ # :commit_msg
72
+ # returns head_sha
73
+ def self.stage_and_commit(repo_dir,local_branch_type, opts = {})
74
+ local_branch = branch_from_local_branch_type(local_branch_type)
75
+ repo = create_empty_git_repo?(repo_dir, :branch => local_branch)
76
+ repo.stage_and_commit(opts[:commit_msg])
77
+ repo.head_commit_sha
78
+ end
79
+
80
+ # returns head_sha
81
+ def self.commit_and_push_to_service_repo(args)
82
+ branch = args.required(:branch)
83
+ remote_branch = args[:remote_branch] || branch
84
+ service_instance = args.required(:service_instance)
85
+ commit_message = args[:commit_message]
86
+
87
+ repo_dir = ret_base_path(:service, service_instance)
88
+ repo = git_repo.new(repo_dir, :branch => branch)
89
+ repo.stage_and_commit
90
+ # TODO: want to switch over to using Dtk_Server::GIT_REMOTE rather than 'origin'
91
+ dtk_server_remote = 'origin'
92
+ repo.push(dtk_server_remote, remote_branch)
93
+ repo.head_commit_sha
94
+ end
95
+
96
+ def self.clone_service_repo(args)
97
+ repo_url = args.required(:repo_url)
98
+ branch = args.required(:branch)
99
+ service_instance = args.required(:service_instance)
100
+ remove_existing = args[:remove_existing]
101
+ repo_dir = args[:repo_dir]
102
+
103
+ target_repo_dir = create_service_dir(service_instance, :remove_existing => remove_existing, :path => repo_dir)
104
+ begin
105
+ git_repo.clone(repo_url, target_repo_dir, branch)
106
+ rescue => e
107
+ #cleanup by deleting directory
108
+
109
+ FileUtils.rm_rf(target_repo_dir) if File.directory?(target_repo_dir)
110
+ # Log error details
111
+ Logger.instance.error_pp(e.message, e.backtrace)
112
+
113
+ # User-friendly error
114
+ raise Error::Usage, "Clone to directory '#{target_repo_dir}' failed"
115
+ end
116
+ target_repo_dir
117
+ end
118
+
119
+ def self.clone_module_repo(args)
120
+ module_type = args.required(:module_type)
121
+ repo_url = args.required(:repo_url)
122
+ branch = args.required(:branch)
123
+ module_name = args.required(:module_name)
124
+ remove_existing = args[:remove_existing]
125
+ repo_dir = args[:repo_dir]
126
+
127
+ target_repo_dir = create_module_dir(module_type, module_name, :remove_existing => remove_existing, :path => repo_dir)
128
+ begin
129
+ git_repo.clone(repo_url, target_repo_dir, branch)
130
+ rescue => e
131
+ FileUtils.rm_rf(target_repo_dir) if File.directory?(target_repo_dir)
132
+ Logger.instance.error_pp(e.message, e.backtrace)
133
+
134
+ raise Error::Usage, "Clone to directory '#{target_repo_dir}' failed"
135
+ end
136
+
137
+ target_repo_dir
138
+ end
139
+
140
+ # opts can have keys:
141
+ # :with_diffs (Boolean)
142
+ def self.modified(args, opts = {})
143
+ repo_url = args.required(:path)
144
+ branch = args.required(:branch)
145
+ repo = git_repo.new(repo_url, :branch => branch)
146
+
147
+ original_path = Dir.pwd
148
+ Dir.chdir(args[:path])
149
+ changed = repo.changed?
150
+ repo.print_status(:with_diffs => opts[:with_diffs]) if changed
151
+ Dir.chdir(original_path)
152
+ changed
153
+ end
154
+
155
+ def self.fetch_merge_and_push(args)
156
+ repo_dir = args.required(:repo_dir)
157
+ repo_url = args.required(:repo_url)
158
+ remote_branch = args.required(:branch)
159
+
160
+ head_sha =
161
+ if git_repo.is_git_repo?(repo_dir)
162
+ init_and_push_from_existing_repo(repo_dir, repo_url, remote_branch)
163
+ else
164
+ create_repo_from_remote_and_push(repo_dir, repo_url, remote_branch)
165
+ end
166
+
167
+ head_sha
168
+ end
169
+
170
+ def self.create_add_remote_and_push(repo_dir, repo_url, remote_branch)
171
+ repo = git_repo.new(repo_dir)
172
+ add_remote_and_push(repo, repo_url, remote_branch)
173
+ repo.head_commit_sha
174
+ end
175
+
176
+ # TODO: DTK-2765: see what this does and subsume by create_add_remote_and_push
177
+ # For this and other methods in Internal that use Dtk_Server::GIT_REMOTE
178
+ # put a version in Internal taht takes remote_name as param and then have
179
+ # method with same name in Dtk, that calss this with appropriate remote name
180
+ def self.init_and_push_from_existing_repo(repo_dir, repo_url, remote_branch)
181
+ repo = git_repo.new(repo_dir)
182
+
183
+ if repo.is_there_remote?(Dtk_Server::GIT_REMOTE)
184
+ push_when_there_is_dtk_remote(repo, repo_dir, repo_url, remote_branch)
185
+ else
186
+ add_remote_and_push(repo, repo_url, remote_branch)
187
+ end
188
+
189
+ repo.head_commit_sha
190
+ end
191
+
192
+ def self.pull_from_remote(args)
193
+ repo_url = args.required(:repo_url)
194
+ remote_branch = args.required(:branch)
195
+ repo_dir = args.required(:repo_dir)
196
+
197
+ repo = git_repo.new(repo_dir, :branch => remote_branch)
198
+ repo.pull(repo.remotes.first, remote_branch)
199
+ end
200
+
201
+ # returns the repo
202
+ def self.pull_from_service_repo(args)
203
+ repo_url = args.required(:repo_url)
204
+ remote_branch = args.required(:branch)
205
+ service_instance = args.required(:service_instance)
206
+
207
+ repo_dir = ret_base_path(:service, service_instance)
208
+ repo = git_repo.new(repo_dir, :branch => remote_branch)
209
+
210
+ repo.pull(repo.remotes.first, remote_branch)
211
+ repo
212
+ end
213
+
214
+ def self.push_when_there_is_dtk_remote(repo, repo_dir, repo_url, remote_branch)
215
+ # if there is only one remote and it is dtk-server; remove .git and initialize and push as new repo to dtk-server remote
216
+ # else if multiple remotes and dtk-server being one of them; remove dtk-server; add new dtk-server remote and push
217
+ if repo.remotes.size == 1
218
+ git_repo.unlink_local_clone?(repo_dir)
219
+ create_repo_from_remote_and_push(repo_dir, repo_url, remote_branch)
220
+ else
221
+ repo.remove_remote(Dtk_Server::GIT_REMOTE)
222
+ add_remote_and_push(repo, repo_url, remote_branch)
223
+ end
224
+ end
225
+
226
+ def self.create_repo_from_server_remote(repo_dir, repo_url, remote_branch)
227
+ repo = git_repo.new(repo_dir, :branch => Dtkn::LOCAL_BRANCH)
228
+ repo.checkout(Dtkn::LOCAL_BRANCH, :new_branch => true)
229
+ repo.add_remote(Dtk_Server::GIT_REMOTE, repo_url)
230
+ repo
231
+ end
232
+
233
+ def self.create_repo_from_remote_and_push(repo_dir, repo_url, remote_branch)
234
+ repo = create_repo_from_server_remote(repo_dir, repo_url, remote_branch)
235
+ # repo = git_repo.new(repo_dir, :branch => Dtkn::LOCAL_BRANCH)
236
+ # repo.checkout(Dtkn::LOCAL_BRANCH, :new_branch => true)
237
+ # repo.add_remote(Dtk_Server::GIT_REMOTE, repo_url)
238
+ repo.stage_and_commit
239
+ repo.push(Dtk_Server::GIT_REMOTE, remote_branch, { :force => true })
240
+ repo.head_commit_sha
241
+ end
242
+
243
+ def self.add_remote_and_push(repo, repo_url, remote_branch)
244
+ repo.add_remote(Dtk_Server::GIT_REMOTE, repo_url)
245
+ repo.stage_and_commit
246
+ repo.push(Dtk_Server::GIT_REMOTE, remote_branch, { :force => true })
247
+ end
248
+
249
+ def self.add_service_repo_file(args)
250
+ branch = args.required(:branch)
251
+ service_instance = args.required(:service_instance)
252
+ path = args.required(:path)
253
+ content = args.required(:content)
254
+ checkout_branch(service_instance, branch) do
255
+ File.open(qualified_path(service_instance, path), 'w') { |f| f.write(content) }
256
+ end
257
+ end
258
+
259
+ # returns content if file exists
260
+ def self.get_service_repo_file_content(args)
261
+ branch = args.required(:branch)
262
+ service_instance = args.required(:service_instance)
263
+ path = args.required(:path)
264
+ checkout_branch(service_instance, branch) do
265
+ qualified_path = qualified_path(service_instance, path)
266
+ if File.exists?(qualified_path)
267
+ File.open(qualified_path, 'r').read
268
+ end
269
+ end
270
+ end
271
+
272
+ def self.all_branches(args)
273
+ repo_url = args.required(:path)
274
+ repo = git_repo.new(repo_url)
275
+ repo.all_branches
276
+ end
277
+
278
+ def self.current_branch(args)
279
+ repo_url = args.required(:path)
280
+ repo = git_repo.new(repo_url)
281
+ repo.current_branch.name
282
+ end
283
+
284
+ def self.git_repo
285
+ ::DTK::Client::GitRepo
286
+ end
287
+
288
+ private
289
+
290
+ def self.branch_from_local_branch_type(local_branch_type)
291
+ case local_branch_type
292
+ when :dtkn then Dtkn.local_branch
293
+ else
294
+ raise Error, "Illegal local_branch_type '#{local_branch_type}'"
295
+ end
296
+ end
297
+
298
+ # relative_path is relative to top-leel repo directory
299
+ def self.qualified_path(service_instance, relative_path)
300
+ repo_dir = ret_base_path(:service, service_instance)
301
+ "#{repo_dir}/#{relative_path}"
302
+ end
303
+
304
+ CHECKOUT_LOCK = Mutex.new
305
+ def self.checkout_branch(service_instance, branch, &body)
306
+ ret = nil
307
+ CHECKOUT_LOCK.synchronize do
308
+ repo = git_repo.new(ret_base_path(:service, service_instance), :branch => branch)
309
+ current_branch = repo.current_branch.name
310
+ if current_branch == branch
311
+ ret = yield
312
+ else
313
+ begin
314
+ repo.checkout(branch)
315
+ ret = yield
316
+ ensure
317
+ repo.checkout(current_branch)
318
+ end
319
+ end
320
+ end
321
+ ret
322
+ end
323
+
324
+ end
325
+ end
326
+ end
327
+ end
328
+