Class: DTK::Client::CommandHelper::GitRepo

Inherits:
DTK::Client::CommandHelper show all
Defined in:
lib/command_helpers/git_repo.rb,
lib/command_helpers/git_repo/merge.rb

Defined Under Namespace

Classes: DiffSummary, Merge

Class Method Summary collapse

Class Method Details

.add_file(repo_obj, path, content, msg = nil) ⇒ Object

TODO: this does not push; may make that an option



80
81
82
83
84
85
86
87
# File 'lib/command_helpers/git_repo.rb', line 80

def add_file(repo_obj,path,content,msg=nil)
  Response.wrap_helper_actions() do
    ret = Hash.new
    repo_obj.add_file(path,content)
    ret["message"] = msg if msg
    ret
  end
end

.check_local_dir_exists_with_content(type, module_name, version = nil, module_namespace = nil) ⇒ Object



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/command_helpers/git_repo.rb', line 194

def check_local_dir_exists_with_content(type, module_name, version=nil, module_namespace=nil)
  full_module_name = ModuleUtil.join_name(module_name, module_namespace)
  Response.wrap_helper_actions() do
    ret = Hash.new
    local_repo_dir = local_repo_dir(type,full_module_name,version)

    unless File.directory?(local_repo_dir)
      raise ErrorUsage.new("The content for module (#{full_module_name}) should be put in directory (#{local_repo_dir})",:log_error=>false)
    end

    # transfered this part to initialize_client_clone_and_push because if we remove .git folder and
    # if create on server fails we will lose this .git folder and will not be able to push local changes to server
    # if File.directory?("#{local_repo_dir}/.git")
    #   response =  unlink_local_clone?(type,module_name,version)
    #   unless response.ok?
    #     # in case delete went wrong, we raise usage error
    #     raise ErrorUsage.new("Directory (#{local_repo_dir} is set as a git repo; to continue it must be a non git repo; this can be handled by shell command 'rm -rf #{local_repo_dir}/.git'")
    #   end

    #   # we return to normal flow, since .git dir is removed
    # end

    if Dir["#{local_repo_dir}/*"].empty?
      raise ErrorUsage.new("Directory (#{local_repo_dir}) must have ths initial content for module (#{full_module_name})")
    end
    {"module_directory" => local_repo_dir}
  end
end

.cp_r_to_new_namespace(type, module_name, src_namespace, dest_namespace, version = nil) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/command_helpers/git_repo.rb', line 223

def cp_r_to_new_namespace(type, module_name, src_namespace, dest_namespace, version = nil)
  full_name_src  = ModuleUtil.join_name(module_name, src_namespace)
  full_name_dest = ModuleUtil.join_name(module_name, dest_namespace)

  local_src_dir  = local_repo_dir(type, full_name_src, version)
  local_dest_dir = local_repo_dir(type, full_name_dest, version)

  Response.wrap_helper_actions() do
    if File.directory?(local_src_dir) && !(Dir["#{local_src_dir}/*"].empty?)
      raise ErrorUsage.new("Directory (#{local_dest_dir}) already exist with content.",:log_error=>false) if File.directory?(local_dest_dir) && !(Dir["#{local_dest_dir}/*"].empty?)

      # create namespace directory if does not exist, and copy source to destination module directory
      namespace_dir = local_repo_dir(type, dest_namespace, version)
      FileUtils.mkdir_p(namespace_dir)
      FileUtils.cp_r(local_src_dir, local_dest_dir)
    else
      raise ErrorUsage.new("The content for module (#{full_name_src}) should be put in directory (#{local_src_dir})",:log_error=>false)
    end
    {"module_directory" => local_dest_dir}
  end
end

.create(repo_dir, branch = nil, opts = {}) ⇒ Object



29
30
31
# File 'lib/command_helpers/git_repo.rb', line 29

def create(repo_dir,branch=nil,opts={})
  GitAdapter.new(repo_dir, branch)
end

.create_clone_from_optional_branch(type, module_name, repo_url, opts = {}) ⇒ Object



33
34
35
36
37
38
# File 'lib/command_helpers/git_repo.rb', line 33

def create_clone_from_optional_branch(type, module_name, repo_url, opts={})
  branch = opts[:branch]
  version = opts[:version]
  namespace =  opts[:namespace]
  create_clone_with_branch(type,module_name,repo_url,branch,version,namespace,{:track_remote_branch => true}.merge(opts))
end

.create_clone_with_branch(type, module_name, repo_url, branch = nil, version = nil, module_namespace = nil, opts = {}) ⇒ Object

TODO: should we deprecate below for above, subsituting the body of below for above ?



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/command_helpers/git_repo.rb', line 41

def create_clone_with_branch(type, module_name, repo_url, branch=nil, version=nil, module_namespace=nil, opts={})
  Response.wrap_helper_actions do
    full_name = module_namespace ? ModuleUtil.resolve_name(module_name, module_namespace) : module_name

    modules_dir = modules_dir(type,full_name,version,opts)
    FileUtils.mkdir_p(modules_dir) unless File.directory?(modules_dir)

    target_repo_dir = local_repo_dir(type,full_name,version,opts)
    if File.exists?(target_repo_dir)
      # if local copy of module exists then move that module to backups location
      if opts[:backup_if_exist]
        backup_dir = backup_dir(type, full_name)
        FileUtils.mv(target_repo_dir, backup_dir)
        puts "Backup of existing module directory moved to '#{backup_dir}'"
      else
        raise ErrorUsage.new("Directory '#{target_repo_dir}' is not empty; it must be deleted or removed before retrying the command", :log_error => false)
      end
    end

    begin
      opts_clone = (opts[:track_remote_branch] ? {:track_remote_branch => true} : {})
      GitAdapter.clone(repo_url, target_repo_dir, branch, opts_clone)
    rescue => e
      # Handling Git error messages with more user friendly messages
      e = GitErrorHandler.handle(e)

      #cleanup by deleting directory
      FileUtils.rm_rf(target_repo_dir) if File.directory?(target_repo_dir)
      error_msg = "Clone to directory (#{target_repo_dir}) failed"

      DtkLogger.instance.error_pp(e.message, e.backtrace)

      raise ErrorUsage.new(error_msg, :log_error => false)
    end
    {"module_directory" => target_repo_dir}
  end
end

.create_new_version(type, src_branch, module_name, src_namespace, version, repo_url, opts = {}) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/command_helpers/git_repo.rb', line 245

def create_new_version(type, src_branch, module_name, src_namespace, version, repo_url, opts = {})
  full_name_src  = ModuleUtil.join_name(module_name, src_namespace)
  full_name_dest = "#{full_name_src}-#{version}"

  local_src_dir  = local_repo_dir(type, full_name_src)
  local_dest_dir = local_repo_dir(type, full_name_dest)
  branch         = "#{src_branch}-v#{version}"
  exist_already  = false

  if File.directory?(local_src_dir) && !(Dir["#{local_src_dir}/*"].empty?)
    if File.directory?(local_dest_dir) && !(Dir["#{local_dest_dir}/*"].empty?)
      # raise ErrorUsage.new("Directory (#{local_dest_dir}) already exist with content.",:log_error=>false)
      exist_already = true
    else
      FileUtils.cp_r(local_src_dir, local_dest_dir)
    end
  else
    raise ErrorUsage.new("The content for module (#{full_name_src}) should be put in directory (#{local_src_dir})",:log_error=>false)
  end

  unless exist_already
    Response.wrap_helper_actions() do
      repo_dir = local_dest_dir
      remote_branch = local_branch = branch
      repo = create(repo_dir, branch, :no_initial_commit => true)
      repo.add_remote(remote(branch), repo_url)
      repo.checkout(branch, { :new_branch => true })
      repo.push_with_remote(remote(), remote_branch)
      repo.delete_branch(src_branch)
      repo.fetch()
    end
  end

  {'module_directory' => local_dest_dir, 'version' => version, 'branch' => branch, 'exist_already' => exist_already}
end

.full_module_name(module_name, opts) ⇒ Object



173
174
175
# File 'lib/command_helpers/git_repo.rb', line 173

def full_module_name(module_name,opts)
  opts[:full_module_name] || ModuleUtil.resolve_name(module_name, opts[:namespace])
end

.get_diffs(type, module_name, version, opts = {}) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/command_helpers/git_repo.rb', line 106

def get_diffs(type, module_name, version, opts={})
  Response.wrap_helper_actions() do
    repo_dir = local_repo_dir(type,module_name,version)
    repo = create(repo_dir,opts[:local_branch])
    get_diffs_aux(repo,opts)
  end
end

.get_remote_diffs(type, module_name, version, opts = {}) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/command_helpers/git_repo.rb', line 114

def get_remote_diffs(type, module_name, version, opts={})
  Response.wrap_helper_actions() do
    repo_dir = local_repo_dir(type,module_name,version)
    repo = create(repo_dir,opts[:local_branch])
    get_remote_diffs_aux(repo,opts)
  end
end

.hard_reset_branch_to_sha(type, module_name, opts = {}) ⇒ Object



152
153
154
155
156
157
158
159
160
# File 'lib/command_helpers/git_repo.rb', line 152

def hard_reset_branch_to_sha(type, module_name, opts={})
  Response.wrap_helper_actions() do
    full_module_name   = full_module_name(module_name,opts)
    repo_dir           = local_repo_dir(type, full_module_name, opts[:version], opts)
    repo               = create(repo_dir, opts[:local_branch])
    current_branch_sha = opts[:current_branch_sha]
    repo.reset_hard(current_branch_sha)
  end
end

.initialize_client_clone_and_push(type, module_name, branch, repo_url, local_repo_dir, version = nil) ⇒ Object

makes repo_dir (determined from type and module_name) into a git dir, pulls, adds, content and then pushes



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/command_helpers/git_repo.rb', line 311

def initialize_client_clone_and_push(type, module_name, branch, repo_url, local_repo_dir, version=nil)
  # moved this part from 'check_local_dir_exists_with_content' to this method since this only deletes .git folder
  # which can cause us problems if import fails
  if File.directory?("#{local_repo_dir}/.git")
    response =  unlink_local_clone?(type,module_name,version)
    unless response.ok?
      # in case delete went wrong, we raise usage error
      raise DtkError.new("Directory (#{local_repo_dir} is set as a git repo; to continue it must be a non git repo; this can be handled by shell command 'rm -rf #{local_repo_dir}/.git'")
    end
    # we return to normal flow, since .git dir is removed
  end

  Response.wrap_helper_actions() do
    ret = Hash.new
    repo_dir = local_repo_dir(type,module_name)

    repo = create(repo_dir,branch,:init => true, :no_initial_commit => true)
    repo.add_remote(remote(),repo_url)
    remote_branch = local_branch = branch

    repo.pull_remote_to_local(remote_branch,local_branch,remote())
    repo.stage_changes()
    repo.commit("Adding files during initialization")
    repo.push_with_remote(remote(), remote_branch)

    commit_sha = repo.head_commit_sha()
    {"repo_obj" => repo,"commit_sha" => commit_sha}
  end
end

.local_clone_dir_exists?(type, module_name, opts = {}) ⇒ Boolean

opts can have the following keys

:version :full_module_name :namespace

Returns:

  • (Boolean)


167
168
169
170
171
# File 'lib/command_helpers/git_repo.rb', line 167

def local_clone_dir_exists?(type,module_name,opts={})
  full_module_name = full_module_name(module_name,opts)
  ret = local_repo_dir(type, full_module_name, opts[:version], opts)
  File.directory?(ret) && ret
end

.pull_changes(type, module_name, opts = {}) ⇒ Object

opts can have the following keys

:remote_repo :remote_branch :remote_repo_url :local_branch :version :commit_sha :full_module_name :namespace returns: { :diffs => , :commit_sha => }



134
135
136
137
138
139
140
141
142
143
# File 'lib/command_helpers/git_repo.rb', line 134

def pull_changes(type,module_name,opts={})
  Response.wrap_helper_actions() do
    full_module_name = full_module_name(module_name,opts)
    repo_dir = local_repo_dir(type,full_module_name,opts[:version],opts)
    repo = create(repo_dir,opts[:local_branch])
    opts.merge!(:full_module_name => full_module_name)
    response = pull_repo_changes_aux(repo,opts)
    response
  end
end

.pull_changes?(type, module_name, opts = {}) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
147
148
149
150
# File 'lib/command_helpers/git_repo.rb', line 144

def pull_changes?(type,module_name,opts={})
  if local_clone_dir_exists?(type,module_name,opts)
    pull_changes(type,module_name,opts)
  else
    Response.wrap_helper_actions()
  end
end

.push_changes(type, full_module_name, version, opts = {}) ⇒ Object

opts can have the following keys

:remote_repo :remote_branch :remote_repo_url :local_branch :override_repo_dir_location :no_fetch



98
99
100
101
102
103
104
# File 'lib/command_helpers/git_repo.rb', line 98

def push_changes(type, full_module_name, version, opts={})
  Response.wrap_helper_actions() do
    repo_dir = opts[:override_repo_dir_location] ? opts[:override_repo_dir_location] : local_repo_dir(type, full_module_name, version, opts)
    repo = create(repo_dir, opts[:local_branch])
    push_repo_changes_aux(repo, opts)
  end
end

.rename_and_initialize_clone_and_push(type, module_name, new_module_name, branch, repo_url, local_repo_dir, version = nil) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/command_helpers/git_repo.rb', line 281

def rename_and_initialize_clone_and_push(type, module_name, new_module_name, branch, repo_url, local_repo_dir, version = nil)
  # check to see if the new dir has proper naming e.g. (~/dtk/component_modules/dtk::java)
  unless local_repo_dir.match(/\/#{new_module_name.gsub(ModuleUtil::NAMESPACE_SEPERATOR,'/')}$/)
    old_dir = local_repo_dir
    new_dir = local_repo_dir.gsub(/#{module_name}$/, new_module_name.split(ModuleUtil::NAMESPACE_SEPERATOR).join('/'))

    # creates directory if missing
    parent_path = new_dir.gsub(/(\/\w+)$/,'')
    FileUtils::mkdir_p(parent_path) unless File.directory?(parent_path)
    # raise ErrorUsage.new("Destination folder already exists '#{new_dir}', aborting initialization.") if File.directory?(new_dir)
    if File.directory?(new_dir)
      # return empty response if user does not want to overwrite current directory
      return unless Console.confirmation_prompt("Destination directory #{new_dir} exists already. Do you want to overwrite it with content from #{old_dir}"+'?')
      FileUtils.rm_rf(new_dir)
    end
    # FileUtils.mv(old_dir, new_dir)
    FileUtils.cp_r(old_dir, new_dir)
  else
    new_dir = local_repo_dir
  end

  # Continue push
  response = initialize_client_clone_and_push(type, new_module_name, branch, repo_url, new_dir, version)
  return response unless response.ok?

  response.data.merge!(:old_dir => old_dir)
  response
end

.synchronize_clone(type, module_name, commit_sha, opts = {}) ⇒ Object



178
179
180
181
# File 'lib/command_helpers/git_repo.rb', line 178

def synchronize_clone(type,module_name,commit_sha,opts={})
  pull_changes?(type,module_name,{:commit_sha => commit_sha}.merge(opts))
  Response::Ok.new()
end

if local clone exists remove its .git directory

Returns:

  • (Boolean)


184
185
186
187
188
189
190
191
192
# File 'lib/command_helpers/git_repo.rb', line 184

def unlink_local_clone?(type,module_name,version=nil)
  Response.wrap_helper_actions() do
    local_repo_dir = local_repo_dir(type,module_name,version)
    git_dir = "#{local_repo_dir}/.git"
    if File.directory?(git_dir)
      FileUtils.rm_rf(git_dir)
    end
  end
end