dtk-network-client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +201 -0
  5. data/README.md +2 -0
  6. data/dtk-network-client.gemspec +24 -0
  7. data/lib/client/args.rb +19 -0
  8. data/lib/client/client_args.rb +23 -0
  9. data/lib/client/command/add_to_group.rb +20 -0
  10. data/lib/client/command/chmod.rb +21 -0
  11. data/lib/client/command/create_namespace.rb +19 -0
  12. data/lib/client/command/delete.rb +25 -0
  13. data/lib/client/command/delete_namespace.rb +19 -0
  14. data/lib/client/command/info.rb +32 -0
  15. data/lib/client/command/install/installer.rb +9 -0
  16. data/lib/client/command/install.rb +190 -0
  17. data/lib/client/command/list.rb +13 -0
  18. data/lib/client/command/list_namespaces.rb +10 -0
  19. data/lib/client/command/publish.rb +120 -0
  20. data/lib/client/command/pull.rb +53 -0
  21. data/lib/client/command/push.rb +63 -0
  22. data/lib/client/command/remove_from_group.rb +20 -0
  23. data/lib/client/command/unpublish.rb +27 -0
  24. data/lib/client/command/update.rb +18 -0
  25. data/lib/client/command.rb +31 -0
  26. data/lib/client/config.rb +54 -0
  27. data/lib/client/conn.rb +132 -0
  28. data/lib/client/dependency_tree/activated.rb +35 -0
  29. data/lib/client/dependency_tree/cache.rb +28 -0
  30. data/lib/client/dependency_tree/candidates.rb +19 -0
  31. data/lib/client/dependency_tree/resolver.rb +16 -0
  32. data/lib/client/dependency_tree.rb +272 -0
  33. data/lib/client/error.rb +22 -0
  34. data/lib/client/file_helper.rb +8 -0
  35. data/lib/client/git_adapter/git_gem.rb +246 -0
  36. data/lib/client/git_client.rb +136 -0
  37. data/lib/client/git_repo.rb +221 -0
  38. data/lib/client/module_dir.rb +38 -0
  39. data/lib/client/module_ref/dependency/local.rb +47 -0
  40. data/lib/client/module_ref/dependency/remote.rb +18 -0
  41. data/lib/client/module_ref/dependency.rb +21 -0
  42. data/lib/client/module_ref/version/source.rb +18 -0
  43. data/lib/client/module_ref/version.rb +87 -0
  44. data/lib/client/module_ref.rb +21 -0
  45. data/lib/client/response/response_types.rb +42 -0
  46. data/lib/client/response.rb +27 -0
  47. data/lib/client/rest_wrapper.rb +43 -0
  48. data/lib/client/s3_helper.rb +23 -0
  49. data/lib/client/session.rb +54 -0
  50. data/lib/client/storage/adapters/s3.rb +25 -0
  51. data/lib/client/storage.rb +29 -0
  52. data/lib/client/util/os_util.rb +77 -0
  53. data/lib/client/util/permissions_util.rb +12 -0
  54. data/lib/client/util/tar.rb +104 -0
  55. data/lib/client/util.rb +7 -0
  56. data/lib/client/version.rb +8 -0
  57. data/lib/dtk_network_client.rb +27 -0
  58. metadata +183 -0
@@ -0,0 +1,272 @@
1
+ require 'semverly'
2
+
3
+ module DTK::Network
4
+ module Client
5
+ class DependencyTree
6
+ require_relative('dependency_tree/activated')
7
+ require_relative('dependency_tree/cache')
8
+ require_relative('dependency_tree/candidates')
9
+
10
+ include RestWrapper
11
+ extend RestWrapper
12
+
13
+ LOCK_FILE = "dtk.module.lock"
14
+
15
+ def initialize(module_ref, opts = {})
16
+ @module_ref = module_ref
17
+ @module_directory = opts[:module_directory] || module_ref.repo_dir
18
+ @parsed_module = opts[:parsed_module]
19
+ @cache = Cache.new
20
+ @activated = Activated.new
21
+ @candidates = Candidates.new
22
+ @development_mode = opts[:development_mode]
23
+ end
24
+
25
+ def self.get_or_create(module_ref, opts = {})
26
+ content = nil
27
+ module_ref = convert_to_module_ref(module_ref) unless module_ref.is_a?(ModuleRef)
28
+ update_lock_file = opts[:update_lock_file]
29
+ yaml_content = FileHelper.get_content?("#{module_ref.repo_dir}/#{LOCK_FILE}")
30
+
31
+ if yaml_content && !update_lock_file
32
+ content = YAML.load(yaml_content)
33
+ raise_error_if_dependencies_changed!(content, opts[:parsed_module])
34
+ elsif opts[:save_to_file] || update_lock_file
35
+ content = compute_and_save_to_file(module_ref, opts)
36
+ else
37
+ content = compute(module_ref, opts)
38
+ end
39
+
40
+ ret_required_format(content, opts[:format])
41
+ end
42
+
43
+ def self.compute_and_save_to_file(module_ref, opts = {})
44
+ activated = compute(module_ref, opts)
45
+ ModuleDir.create_file_with_content("#{module_ref.repo_dir}/#{LOCK_FILE}", YAML.dump(activated.to_h))
46
+ activated
47
+ end
48
+
49
+ def self.compute(module_ref, opts = {})
50
+ new(module_ref, opts).compute
51
+ end
52
+
53
+ def compute
54
+ dependencies = (ret_dependencies || []).map do |pm_ref|
55
+ ModuleRef::Dependency.create_local_or_remote(pm_ref)
56
+ # ModuleRef::Dependency.new({ name: pm_ref['module'], namespace: pm_ref['namespace'], version: pm_ref['version'] })
57
+ end
58
+
59
+ activate_dependencies(dependencies)
60
+ @activated
61
+ end
62
+
63
+ private
64
+
65
+ def activate_dependencies(dependencies, opts = {})
66
+ dependencies.each do |dependency|
67
+ next if @activated.module_activated?(dependency)
68
+
69
+ puts "Calculating dependencies for module: #{dependency.full_name}(#{dependency.version.str_version})" if @development_mode
70
+
71
+ check_for_conflicts(dependency)
72
+
73
+ # dtkn_versions_w_deps_hash = dtkn_versions_with_dependencies(dependency)
74
+ dtkn_versions_w_deps_hash = dependency.dtkn_versions_with_dependencies
75
+ dtkn_versions_w_deps = dtkn_versions_w_deps_hash.map { |v| v['version'] }
76
+
77
+ version_obj = dependency.version
78
+ versions_in_range = version_obj.versions_in_range(dtkn_versions_w_deps)
79
+
80
+ raise "No version matching requirement '#{version_obj.full_version}'" if versions_in_range.empty?
81
+
82
+ versions_in_range.sort!
83
+ latest_version = versions_in_range.last
84
+
85
+ if dependency.is_a?(ModuleRef::Dependency::Local)
86
+ latest_version_dep = dependency
87
+ else
88
+ latest_version_dep = ModuleRef::Dependency::Remote.new({ name: dependency.name, namespace: dependency.namespace, version: latest_version })
89
+ end
90
+
91
+ @activated.add!(latest_version_dep)
92
+ @candidates.add!(dependency, versions_in_range)
93
+
94
+ dtkn_deps_of_deps = dtkn_versions_w_deps_hash.find {|dep| dep['version'].eql?(latest_version) }
95
+ add_nested_modules(dependency, dtkn_deps_of_deps)
96
+
97
+ dtkn_deps_of_deps_objs = (dtkn_deps_of_deps['dependencies'] || {}).map do |dtkn_dep|
98
+ ModuleRef::Dependency.create_local_or_remote({ name: dtkn_dep['module'], namespace: dtkn_dep['namespace'], version: dtkn_dep['version'] })
99
+ end
100
+
101
+ activate_dependencies(dtkn_deps_of_deps_objs, opts)
102
+ end
103
+ end
104
+
105
+ def ret_dependencies
106
+ if @parsed_module
107
+ (@parsed_module.val(:DependentModules) || []).map do |parsed_mr|
108
+ { 'namespace' => parsed_mr.req(:Namespace), 'module' => parsed_mr.req(:ModuleName), 'version' => parsed_mr.val(:ModuleVersion) }
109
+ end
110
+ else
111
+ response = rest_get("modules/#{@module_ref.name}/dependencies", { name: @module_ref.name, namespace: @module_ref.namespace, version: @module_ref.version.str_version })
112
+ response['dependencies']
113
+ end
114
+ end
115
+
116
+ def dtkn_versions_with_dependencies(module_ref)
117
+ response = rest_get("modules/get_versions_with_dependencies", { name: module_ref.name, namespace: module_ref.namespace })
118
+ response['versions']
119
+ end
120
+
121
+ def check_for_conflicts(dependency)
122
+ if activated_mod = @activated.existing_name?(dependency.full_name)
123
+ raise "There is already activated version '#{activated_mod[:version] || activated_mod['version']}' for module '#{dependency.full_name}' and it does not match required version '#{dependency.version.full_version}'"
124
+ end
125
+ end
126
+
127
+ def add_nested_modules(dependency, dtkn_deps_of_deps)
128
+ if activated_module = @activated[dependency.full_name]
129
+ nested_deps = {}
130
+ (dtkn_deps_of_deps['dependencies'] || []).each{ |dtkn_dep| nested_deps.merge!("#{dtkn_dep['namespace']}/#{dtkn_dep['module']}" => simplify_version(dtkn_dep['version'])) }
131
+
132
+ unless nested_deps.empty?
133
+ activated_module.key?('modules') ? activated_module['modules'].merge!(nested_deps) : activated_module.merge!('modules' => nested_deps)
134
+ end
135
+ end
136
+ end
137
+
138
+ def simplify_version(version)
139
+ if version.is_a?(Hash)
140
+ # transform custom dtk hash into ruby hash to avoid strange output in yaml file
141
+ version.to_h
142
+ else
143
+ version
144
+ end
145
+ end
146
+
147
+ def self.ret_as_module_refs(dep_modules)
148
+ dep_modules.map { |k,v| create_module_ref(k, v) }
149
+ end
150
+
151
+ def self.create_module_ref(full_name, version_hash)
152
+ namespace, name = full_name.split('/')
153
+ version = version_hash[:version] || version_hash['version']
154
+ ModuleRef.new({ namespace: namespace, name: name, version: version })
155
+ end
156
+
157
+ def self.ret_as_hash(dep_modules)
158
+ dep_modules.map { |k,v| create_module_hash(k, v) }
159
+ end
160
+
161
+ def self.create_module_hash(full_name, version_hash)
162
+ namespace, name = full_name.split('/')
163
+ version = version_hash[:version] || version_hash['version']
164
+ ret = { namespace: namespace, name: name, version: version }
165
+
166
+ if source = version_hash[:source] || version_hash['source']
167
+ ret.merge!(source: source)
168
+ end
169
+
170
+ ret
171
+ end
172
+
173
+ def self.ret_required_format(content, format)
174
+ format ||= :module_ref
175
+ case format.to_sym
176
+ when :module_ref
177
+ ret_as_module_refs(content)
178
+ when :hash
179
+ ret_as_hash(content)
180
+ else
181
+ raise Error.new("Unsupported format '#{format}'. Valid formats are '#{ValidFormats.join(', ')}'")
182
+ end
183
+ end
184
+ ValidFormats = [:module_ref, :hash]
185
+
186
+ def self.convert_to_module_ref(module_ref)
187
+ ModuleRef.new(module_ref)
188
+ end
189
+
190
+ def self.raise_error_if_dependencies_changed!(lock_content, parsed_module)
191
+ return unless parsed_module
192
+
193
+ message = "Module dependencies have been changed, please use '-u' option to update '#{LOCK_FILE}' file accordingly."
194
+ dependencies = convert_to_modules_lock_format(parsed_module.val(:DependentModules))
195
+
196
+ lock_deps = filter_out_dependencies_of_dependencies(lock_content, dependencies)
197
+ raise Error.new(message) if dependencies.size != lock_deps.size
198
+
199
+ dependencies.each do |name, value|
200
+ if matching = lock_deps[name]
201
+ module_ref_version = ModuleRef::Version.new(value['version'])
202
+ matches_version = module_ref_version.satisfied_by?(matching['version'])
203
+ matches_source = (value['source'] == matching['source'])
204
+ raise Error.new(message) unless (matches_version && matches_source)
205
+ else
206
+ raise Error.new(message)
207
+ end
208
+ end
209
+ end
210
+
211
+ def self.convert_to_modules_lock_format(dependencies = {})
212
+ modules_hash = {}
213
+
214
+ (dependencies || {}).each do |dependency|
215
+ version = dependency[:version]
216
+ source = nil
217
+
218
+ if version.is_a?(Hash)
219
+ source = version['source'] || version[:source]
220
+ if matching_source = source && source.match(/(file:)(.*)/)
221
+ source = matching_source[2]
222
+ end
223
+ version = version['version'] || version[:version]
224
+ end
225
+
226
+ namespace_name = "#{dependency[:namespace]}/#{dependency[:module_name]}"
227
+ content_hash = {'version' => version}
228
+ content_hash['source'] = source if source
229
+ modules_hash.merge!(namespace_name => content_hash)
230
+ end
231
+
232
+ modules_hash
233
+ end
234
+
235
+ def self.filter_out_dependencies_of_dependencies(lock_content, module_yaml_dependencies)
236
+ top_level_dependencies = {}
237
+ nested_dependencies = {}
238
+
239
+ lock_content.each do |lock_name, lock_value|
240
+ nested_dependencies.merge!(lock_value['modules'] || lock_value[:modules] || {})
241
+ top_level_dependencies.merge!(lock_name => {'version' => lock_value['version'], 'source' => lock_value['source']})
242
+ end
243
+
244
+ nested_dependencies.each do |nd_name, version|
245
+ source = nil
246
+
247
+ if version.is_a?(Hash)
248
+ source = version['source'] || version[:source]
249
+ version = version['version'] || version[:version]
250
+ end
251
+
252
+ if top_level_dependency = top_level_dependencies[nd_name]
253
+ module_ref_version = ModuleRef::Version.new(version)
254
+ matches_version = module_ref_version.satisfied_by?(top_level_dependency['version'])
255
+ matches_source = (source == top_level_dependency['source'])
256
+
257
+ if yaml_dep = module_yaml_dependencies[nd_name]
258
+ matches_version_new = module_ref_version.satisfied_by?(yaml_dep['version'])
259
+ matches_source_new = (source == yaml_dep['source'])
260
+ next unless (matches_version_new && matches_source_new)
261
+ end
262
+
263
+ top_level_dependencies.delete(nd_name) if (matches_version && matches_source)
264
+ end
265
+ end
266
+
267
+ top_level_dependencies
268
+ end
269
+
270
+ end
271
+ end
272
+ end
@@ -0,0 +1,22 @@
1
+ module DTK::Network::Client
2
+ class Error < NameError
3
+ def initialize(msg = '')
4
+ if errors = msg['errors']
5
+ errors = [errors] unless errors.is_a?(Array)
6
+ error_msg = ''
7
+ # error_msg << "#{errors['code'].upcase} " if errors['code']
8
+ errors.each do |error|
9
+ if err_msg = error['message']
10
+ error_msg << "#{err_msg}\n"
11
+ elsif orig_exeption = error['original_exception']
12
+ error_msg << "#{orig_exeption}\n"
13
+ end
14
+ end
15
+ super(error_msg)
16
+ else
17
+ super(msg)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,8 @@
1
+ module DTK::Network::Client
2
+ class FileHelper
3
+ def self.get_content?(file_path)
4
+ File.open(file_path).read if file_path && File.exists?(file_path)
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,246 @@
1
+ require 'git'
2
+
3
+ module DTK::Network
4
+ module Client
5
+ class GitGem
6
+ attr_accessor :git_repo
7
+
8
+ # Monkey patch the git merge method
9
+ # to allow passing the --allow-unrelated-histories flag
10
+ # more info: http://stackoverflow.com/questions/37937984/git-refusing-to-merge-unrelated-histories
11
+ class ::Git::Base
12
+ def merge(branch, message = 'merge', opts = {})
13
+ self.lib.merge(branch, message, opts)
14
+ end
15
+
16
+ def rev_list(sha)
17
+ self.lib.rev_list(sha)
18
+ end
19
+
20
+ def name_status(branch1 = nil, branch2 = nil, opts = {})
21
+ self.lib.name_status(branch1, branch2, opts)
22
+ end
23
+ end
24
+
25
+ class ::Git::Lib
26
+ def merge(branch, message = nil, opts = {})
27
+ arr_opts = []
28
+ arr_opts << '--allow-unrelated-histories' if opts[:allow_unrelated_histories]
29
+ arr_opts << '-Xtheirs' if opts[:use_theirs]
30
+ arr_opts << '-m' << message if message
31
+ arr_opts += [branch]
32
+ command('merge', arr_opts)
33
+ end
34
+
35
+ def rev_list(sha)
36
+ arr_opts = [sha]
37
+ command('rev-list', arr_opts)
38
+ end
39
+
40
+ def name_status(branch1 = nil, branch2 = nil, opts = {})
41
+ arr_opts = []
42
+ arr_opts << '--name-status'
43
+ arr_opts << "--diff-filter=#{opts[:diff_filter]}" if opts[:diff_filter]
44
+ arr_opts << branch1 if branch1
45
+ arr_opts << branch2 if branch2
46
+
47
+ command_lines('diff', arr_opts).inject({}) do |memo, line|
48
+ status, path = line.split("\t")
49
+ memo[path] = status
50
+ memo
51
+ end
52
+ end
53
+
54
+ def command_lines(cmd, opts = [], chdir = true, redirect = '')
55
+ cmd_op = command(cmd, opts, chdir)
56
+ op = cmd_op.encode("UTF-8", "binary", {
57
+ :invalid => :replace,
58
+ :undef => :replace
59
+ })
60
+ op.split("\n")
61
+ end
62
+ end
63
+
64
+ # opts can have keys
65
+ # :branch
66
+ def initialize(repo_dir, opts = {})
67
+ @repo_dir = repo_dir
68
+ @git_repo = ::Git.init(repo_dir)
69
+ @local_branch_name = opts[:branch]
70
+ end
71
+
72
+ def self.clone(repo_url, target_path, branch)
73
+ git_base = ::Git.clone(repo_url, target_path)
74
+ begin
75
+ git_base.checkout(branch)
76
+ rescue => e
77
+ raise "The branch or tag '#{branch}' does not exist on repo '#{repo_url}'"
78
+ end
79
+ git_base
80
+ end
81
+
82
+ # opts can have keys
83
+ # :new_branch - Boolean
84
+ def checkout(branch, opts = {})
85
+ ret = @git_repo.checkout(branch, opts)
86
+ @local_branch_name = branch
87
+ ret
88
+ end
89
+
90
+ def fetch(remote = 'origin')
91
+ @git_repo.fetch(remote)
92
+ end
93
+
94
+ def add_remote(name, url)
95
+ @git_repo.remove_remote(name) if is_there_remote?(name)
96
+ @git_repo.add_remote(name, url)
97
+ end
98
+
99
+ def remove_remote(name)
100
+ @git_repo.remove_remote(name) if is_there_remote?(name)
101
+ end
102
+
103
+ def push(remote, branch, opts = {})
104
+ branch_name = current_branch ? current_branch.name : 'master'
105
+ branch_for_push = "#{branch_name}:refs/heads/#{branch || local_branch_name}"
106
+ @git_repo.push(remote, branch_for_push, opts)
107
+ end
108
+
109
+ def merge(branch_to_merge_from, opts = {})
110
+ @git_repo.merge(branch_to_merge_from, 'merge', :allow_unrelated_histories => allow_unrelated_histories?, :use_theirs => opts[:use_theirs])
111
+ end
112
+
113
+ def status
114
+ @git_repo.status
115
+ end
116
+
117
+ def changed
118
+ status.is_a?(Hash) ? status.changed().keys : status.changed().collect { |file| file.first }
119
+ end
120
+
121
+ def untracked
122
+ status.is_a?(Hash) ? status.untracked().keys : status.untracked().collect { |file| file.first }
123
+ end
124
+
125
+ def deleted
126
+ status.is_a?(Hash) ? status.deleted().keys : status.deleted().collect { |file| file.first }
127
+ end
128
+
129
+ def added
130
+ status.is_a?(Hash) ? status.added().keys : status.added().collect { |file| file.first }
131
+ end
132
+
133
+ def stage_and_commit(commit_msg = nil)
134
+ commit_msg ||= default_commit_message
135
+ add_all
136
+ begin
137
+ commit(commit_msg)
138
+ rescue
139
+ # do not raise if nothing to commit
140
+ end
141
+ end
142
+
143
+ def empty_commit(commit_msg = nil)
144
+ commit_msg ||= default_commit_message
145
+ commit(commit_msg, :allow_empty => true)
146
+ end
147
+
148
+ def reset_soft(sha)
149
+ @git_repo.reset(sha)
150
+ end
151
+
152
+ def reset_hard(sha)
153
+ @git_repo.reset_hard(sha)
154
+ end
155
+
156
+ def revparse(sha_or_string)
157
+ @git_repo.revparse(sha_or_string)
158
+ end
159
+
160
+ def rev_list(base_sha)
161
+ @git_repo.rev_list(base_sha)
162
+ end
163
+
164
+ def local_ahead(base_sha, remote_sha)
165
+ results = @git_repo.rev_list(base_sha)
166
+ !results.split("\n").grep(remote_sha).empty?
167
+ end
168
+
169
+ def stage_changes()
170
+ @git_repo.add(untracked())
171
+ @git_repo.add(added())
172
+ @git_repo.add(changed())
173
+
174
+ deleted().each do |file|
175
+ begin
176
+ @git_repo.remove(file)
177
+ rescue
178
+ # ignore this error means file has already been staged
179
+ # we cannot support status of file, in 1.8.7 so this is
180
+ # solution for that
181
+ end
182
+ end
183
+ end
184
+
185
+ # opts can have keys
186
+ # :allow_empty
187
+ def commit(commit_msg = "", opts = {})
188
+ @git_repo.commit(commit_msg, :allow_empty => opts[:allow_empty])
189
+ end
190
+
191
+ def add(*files)
192
+ @git_repo.add(files.flatten)
193
+ end
194
+
195
+ def add_all
196
+ # Cannot use '@git_repo.add(:all => true)' because this only works if pwd is base git repo
197
+ fully_qualified_repo_dir = (@repo_dir =~ /^\// ? @repo_dir : File.join(Dir.pwd, @repo_dir))
198
+ @git_repo.add(fully_qualified_repo_dir, :all => true )
199
+ end
200
+
201
+ def is_there_remote?(remote_name)
202
+ @git_repo.remotes.find { |r| r.name == remote_name }
203
+ end
204
+
205
+ def current_branch
206
+ @git_repo.branches.local.find { |b| b.current }
207
+ end
208
+
209
+ def remotes
210
+ @git_repo.remotes
211
+ end
212
+
213
+ def head_commit_sha
214
+ current_branch.gcommit.sha
215
+ end
216
+
217
+ def pull(remote, branch)
218
+ @git_repo.pull(remote, branch)
219
+ end
220
+
221
+ def diff
222
+ @git_repo.diff
223
+ end
224
+
225
+ def diff_name_status(branch_or_sha_1, branch_or_sha_2, opts = {})
226
+ @git_repo.name_status(branch_or_sha_1, branch_or_sha_2, opts)
227
+ end
228
+
229
+ def changed?
230
+ (!(changed().empty? && untracked().empty? && deleted().empty?))
231
+ end
232
+
233
+
234
+ def all_branches
235
+ @git_repo.branches
236
+ end
237
+
238
+ private
239
+
240
+ def default_commit_message
241
+ "DTK Commit from network client"
242
+ end
243
+
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,136 @@
1
+ module DTK::Network
2
+ module Client
3
+ class GitClient
4
+ require_relative('git_adapter/git_gem')
5
+
6
+ # opts can have keys
7
+ # :branch
8
+ def initialize(repo_dir, opts = {})
9
+ @repo_dir = repo_dir
10
+ @git_adapter = git_adapter_class.new(repo_dir, opts)
11
+ end
12
+
13
+ attr_reader :repo_dir
14
+
15
+ def self.clone(repo_url, target_path, branch)
16
+ git_adapter_class.clone(repo_url, target_path, branch)
17
+ end
18
+
19
+ def self.is_git_repo?(dir)
20
+ File.directory?("#{dir}/.git")
21
+ end
22
+
23
+ def add_remote(name, url)
24
+ @git_adapter.add_remote(name, url)
25
+ end
26
+
27
+ def changed?
28
+ @git_adapter.changed?
29
+ end
30
+
31
+ # opts can have keys
32
+ # :new_branch - Boolean
33
+ def checkout(branch, opts = {})
34
+ @git_adapter.checkout(branch, opts)
35
+ end
36
+
37
+ def current_branch
38
+ @git_adapter.current_branch
39
+ end
40
+
41
+ def diff
42
+ @git_adapter.diff
43
+ end
44
+
45
+ def diff_name_status(branch_or_sha_1 = nil, branch_or_sha_2 = nil, opts = {})
46
+ @git_adapter.diff_name_status(branch_or_sha_1, branch_or_sha_2, opts)
47
+ end
48
+
49
+ def fetch(remote = 'origin')
50
+ @git_adapter.fetch(remote)
51
+ end
52
+
53
+ def head_commit_sha
54
+ @git_adapter.head_commit_sha
55
+ end
56
+
57
+ def is_there_remote?(remote_name)
58
+ @git_adapter.is_there_remote?(remote_name)
59
+ end
60
+
61
+ def merge(branch_to_merge_from, opts = {})
62
+ @git_adapter.merge(branch_to_merge_from, opts)
63
+ end
64
+
65
+ def push(remote, branch, opts = {})
66
+ @git_adapter.push(remote, branch, opts)
67
+ end
68
+
69
+ def push_from_cached_branch(remote, branch, opts = {})
70
+ @git_adapter.push_from_cached_branch(remote, branch, opts)
71
+ end
72
+
73
+ def pull(remote, branch)
74
+ @git_adapter.pull(remote, branch)
75
+ end
76
+
77
+ def remotes
78
+ @git_adapter.remotes
79
+ end
80
+
81
+ def remove_remote(name)
82
+ @git_adapter.remove_remote(name)
83
+ end
84
+
85
+ def stage_and_commit(commit_msg = nil)
86
+ @git_adapter.stage_and_commit(commit_msg)
87
+ end
88
+
89
+ def empty_commit(commit_msg = nil)
90
+ @git_adapter.empty_commit(commit_msg)
91
+ end
92
+
93
+ def commit(commit_msg = "", opts = {})
94
+ @git_adapter.commit(commit_msg, opts)
95
+ end
96
+
97
+ def reset_soft(sha)
98
+ @git_adapter.reset_soft(sha)
99
+ end
100
+
101
+ def reset_hard(sha)
102
+ @git_adapter.reset_hard(sha)
103
+ end
104
+
105
+ def revparse(string)
106
+ @git_adapter.revparse(string)
107
+ end
108
+
109
+ def rev_list(base_sha)
110
+ @git_adapter.rev_list(base_sha)
111
+ end
112
+
113
+ def local_ahead(base_sha, remote_sha)
114
+ @git_adapter.local_ahead(base_sha, remote_sha)
115
+ end
116
+
117
+ def add_all
118
+ @git_adapter.add_all
119
+ end
120
+
121
+ def all_branches
122
+ @git_adapter.all_branches
123
+ end
124
+
125
+ private
126
+
127
+ def git_adapter_class
128
+ self.class.git_adapter_class
129
+ end
130
+
131
+ def self.git_adapter_class
132
+ GitGem
133
+ end
134
+ end
135
+ end
136
+ end