Class: GitFlow

Inherits:
Object
  • Object
show all
Defined in:
lib/opensecret/plugins.io/git/git.flow.rb

Overview

– ——————————————————————- – # – Provision the git branch involved in our present working directory. – # – The [present directory] may not relate to version control at all or – # – it may relate to the master or other branch in the source mgt tool. – # – ——————————————————————- – #

Constant Summary collapse

@@url_postfix =
".git/"

Class Method Summary collapse

Class Method Details

.do_clone_repo(repo_url, non_existent_path) ⇒ Object

– – Clone a remote repository at the specified [url] into – a [NON-EXISTENT] folder path. – – ——————————— – What is a Non Existent Dir Path? – ——————————— – – The parent directory of a non existent folder path – must [exist] whilst the full path itself does not. – The clone operation will create the final folder in – the path and then it [puts] the repository contents – within it. – – ———– – Parameters – ———– – – repo_url : url ends in dot git f-slash – clone_dir : path to new non-existent dir – – —————————– – Dependencies and Assumptions – —————————– – – git is installed on the machine – repo exists and is publicly readable – the master branch is he one to clone – the current Dir.pwd() is writeable –



230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 230

def self.do_clone_repo repo_url, non_existent_path

  cmd = "git clone #{repo_url} #{non_existent_path}"
  clone_output = %x[#{cmd}];

  log.info(ere) { "[gitflow] cloning remote repository" }
  log.info(ere) { "[gitflow] git repository url : #{repo_url}" }
  log.info(ere) { "[gitflow] git clone dir path : #{nickname non_existent_path}" }
  log.info(ere) { "[gitflow] git clone command  : #{cmd}" }
  log.info(ere) { "[gitflow] git clone output   : #{clone_output}" }

end

.do_clone_repos(repo_urls, base_names, parent_dir) ⇒ Object

– —————————————————– – # – Clone [many] git repositories given an array of urls – # – along with a corresponding array of the working copy – # – folder names and a [parental] base (offset) folder. – # – —————————————————– – # – Parameter – # – repo_urls : array of git repository urls – # – base_names : array of cloned repo base names – # – parent_dir : path to local [parent] folder – # – – # – Dependencies and Assumptions – # – arrays have equiv corresponding entries – # – parent dir is created if not exists – # – repos exist and are publicly readable – # – master branches are the ones to clone – # – —————————————————– – #



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 260

def self.do_clone_repos repo_urls, base_names, parent_dir

  Dir.mkdir parent_dir unless File.exists? parent_dir
  Throw.if_not_found parent_dir, "clone repos"

  repo_urls.each_with_index do | repo_url, repo_index |

    git_url = repo_url if repo_url.end_with? @@url_postfix
    git_url = "#{repo_url}#{@@url_postfix}" unless repo_url.end_with? @@url_postfix

    proj_folder = File.join parent_dir, base_names[repo_index]

    log.info(ere) { "[clone repos] proj [index] => #{repo_index}" }
    log.info(ere) { "[clone repos] repo url 1st => #{repo_url}" }
    log.info(ere) { "[clone repos] repo url 2nd => #{git_url}" }
    log.info(ere) { "[clone repos] project name => #{base_names[repo_index]}" }
    log.info(ere) { "[clone repos] project path => #{proj_folder}" }

    GitFlow.do_clone_repo git_url, proj_folder

  end

end

.do_clone_wc(path_to_dot_git, path_to_new_dir) ⇒ Object

– ————————————————– – # – Clone the branch of a local git repo working copy. – # – ————————————————– – # – Parameter – # – src_gitpath : local path to .git folder – # – new_wc_path : path to new non-existent dir – # – – # – Dependencies and Assumptions – # – git is installed on the machine – # – working copy exists and has remote origin – # – ————————————————– – #



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 163

def self.do_clone_wc path_to_dot_git, path_to_new_dir

  # -- ----------------------------------------------------------- -- #
  # -- Why clone from a working copy (instead of a remote url).    -- #
  # -- ----------------------------------------------------------- -- #
  # --                                                             -- #
  # -- When actively [DEVELOPING] an eco plugin and you want to    -- #
  # --                                                             -- #
  # --   1 - [test] the behaviour without a git commit/git push    -- #
  # --   2 - test whatever [branch] the working copy is now at     -- #
  # --                                                             -- #
  # -- This use case requires us to clone from a working copy.     -- #
  # --                                                             -- #
  # -- ----------------------------------------------------------- -- #

###   Bug here - see getting branch name issue
###   Bug here - see getting branch name issue
###   Bug here - see getting branch name issue
###   Bug here - see getting branch name issue
###    branch_name = wc_branch_name path_to_dot_git
  branch_name = "master"
#####    cmd = "git clone #{path_to_dot_git} -b #{branch_name} #{path_to_new_dir}"
#####    cmd = "git clone #{path_to_dot_git} -b #{branch_name} #{path_to_new_dir}"
#####    cmd = "git clone #{path_to_dot_git} -b #{branch_name} #{path_to_new_dir}"
  cmd = "git clone #{path_to_dot_git} #{path_to_new_dir}"
  clone_output = %x[#{cmd}];

  log.info(ere) { "[gitflow] cloning working copy" }
  log.info(ere) { "[gitflow] repo branch name  : #{branch_name}" }
  log.info(ere) { "[gitflow] src dot git path  : #{path_to_dot_git}" }
  log.info(ere) { "[gitflow] new wc dir path   : #{path_to_new_dir}" }
  log.info(ere) { "[gitflow] git clone command : #{cmd}" }
  log.info(ere) { "[gitflow] git clone output  : #{clone_output}" }

end

.file_names(repo_url) ⇒ Object

– ————————————————- – # – Return an array of simple file names in the repo. – # – ————————————————- – # – Parameter – # – repo_url : the url of the repository to read – # – – # – Dependencies and Assumptions – # – we are not interested in folders – # – trawl is recursive (infinite depth) – # – git is installed on the machine – # – ————————————————- – #



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 354

def self.file_names repo_url

  random_text = SecureRandom.urlsafe_base64(12).delete("-_").downcase
  cloned_name = "eco.repo.clone.#{random_text}"
  cloned_path = File.join Dir.tmpdir(), cloned_name

  do_clone_repo repo_url, cloned_path
  dot_git_path = File.join cloned_path, ".git"

  cmd = "git --git-dir=#{dot_git_path} ls-tree -r master --name-only"
  filename_lines = %x[#{cmd}];
  names_list = Array.new
  filename_lines.each_line do |line|
    names_list.push line.strip
  end

  log.info(ere) { "[git2files] ----------------------------------------------" }
  log.info(ere) { "[git2files] [#{names_list.length}] files in [#{repo_url}]" }
  log.info(ere) { "[git2files] ----------------------------------------------" }
  log.info(ere) { "[git2files] Random Text : #{random_text}" }
  log.info(ere) { "[git2files] Cloned Name : #{cloned_name}" }
  log.info(ere) { "[git2files] Cloned Path : #{cloned_path}" }
  log.info(ere) { "[git2files] Repo Folder : #{dot_git_path}" }
  log.info(ere) { "[git2files] Reading Cmd : #{cmd}" }
  log.info(ere) { "[git2files] ----------------------------------------------" }
  pp names_list
  log.info(ere) { "[git2files] ----------------------------------------------" }

  return names_list

end

.git2zip(repo_url, path_offset, target_dir, zip_basename) ⇒ Object

– ———————————————— – # – Move assets from a git repo to a local zip file. – # – ———————————————— – # – – # – Parameter – # – repo_url : the url of the git repository – # – path_offset : FWD-SLASH ENDED PATH in repo – # – target_dir : the target folder for new zip – # – zip_filename : extensionless name of the zip – # – – # – Return – # – path to the zip file created in a tmp folder – # – – # – ———————————————— – # – Dependencies and Assumptions – # – ———————————————— – # – – # – END PATH OFFSET WITH A FORWARD SLASH – # – IF NO OFFSET SEND “/” for path_offset – # – git is installed on the machine – # – the repo exists with path offset – # – the master branch is archived – # – name is unique as used to create a dir – # – – # – ———————————————— – #



310
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
340
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 310

def self.git2zip repo_url, path_offset, target_dir, zip_basename

  log.info(ere) { "[git2zip] ------------------------------------------- -- #" }
  log.info(ere) { "[git2zip] archiving repo assets at path offset        -- #" }
  log.info(ere) { "[git2zip] ------------------------------------------- -- #" }
  log.info(ere) { "[git2zip] git repository url    : #{repo_url}" }
  log.info(ere) { "[git2zip] slash tail dir offset : #{path_offset}" }
  log.info(ere) { "[git2zip] target zip directory  : #{target_dir}" }
  log.info(ere) { "[git2zip] zip file [base] name  : #{zip_basename}" }

  clone_dir = File.join Dir.tmpdir(), zip_basename
  do_clone_repo repo_url, clone_dir
  dot_git_path = File.join clone_dir, ".git"
  dst_zip_path = File.join target_dir, "#{zip_basename}.zip"

  the_offset = path_offset
  the_offset = "" if path_offset.length == 1
  cmd = "git --git-dir=#{dot_git_path} archive -o #{dst_zip_path} HEAD:#{the_offset}"
  clone_output = %x[#{cmd}];

  log.info(ere) { "[git2zip] tmp clone src folder  : #{clone_dir}" }
  log.info(ere) { "[git2zip] cloned dot git path   : #{dot_git_path}" }
  log.info(ere) { "[git2zip] target zip full path  : #{dst_zip_path}" }
  log.info(ere) { "[git2zip] git archive command   : #{cmd}" }
  log.info(ere) { "[git2zip] ------------------------------------------- -- #" }
  log.info(ere) { "#{clone_output}" }
  log.info(ere) { "[git2zip] ------------------------------------------- -- #" }

  return dst_zip_path

end

.push(repo_root_dir, what_changed_string, time_stamp) ⇒ Object

– – Check in whatever has changed in the local repository – at the path stated in the first parameter. – – The text in the second parameter helps to distinguish – what was to be pushed up and forms part of the git – commit message. –



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 20

def self.push repo_root_dir, what_changed_string, time_stamp

  dot_git_path = File.join repo_root_dir, ".git"
  Throw.if_not_exists dot_git_path

  Dir.chdir repo_root_dir

  git_diff_cmd = "git status -vv; echo;"
  git_diff_output = %x[#{git_diff_cmd}]
  git_diff_output.log_lines

  git_add_cmd = "git add -A; echo;"
  git_add_output = %x[#{git_add_cmd}]
  git_add_output.log_lines

  git_commit_cmd = "git commit -m \"Writing #{what_changed_string} at #{time_stamp}.\";"
  git_commit_output = %x[#{git_commit_cmd}]
  git_commit_output.log_lines

  # --
  # -- This command may require input (username/password) from the
  # -- user hence we don't wrap inside output trapping executors.
  # --
  system "git push origin master"

end

.wc_branch_name(path_to_dot_git) ⇒ Object

– ————————————————- – # – Return the branch name of a local git repository. – # – ————————————————- – # – Parameter – # – path_to_dot_git : local path to the .git folder – # – – # – Dependencies and Assumptions – # – git is installed on the machine – # – ————————————————- – #



57
58
59
60
61
62
63
64
65
66
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 57

def self.wc_branch_name path_to_dot_git

  cmd = "git --git-dir=#{path_to_dot_git} branch";
  branch_names = %x[#{cmd}];
  branch_names.each_line do |line|
    return line[2, line.length].strip if line.start_with?('*')
  end
  raise ArgumentError.new "No branch name starts with asterix.\n#{cmd}\n#{branch_names}\n"

end

.wc_origin_url(path_to_dot_git) ⇒ Object

– ————————————————- – # – Get the remote origin url of a git working copy. – # – ————————————————- – # – Parameter – # – path_to_dot_git : local path to .git folder – # – – # – Dependencies and Assumptions – # – git is installed on the machine – # – working copy exists and has remote origin – # – ————————————————- – #



79
80
81
82
83
84
85
86
87
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 79

def self.wc_origin_url path_to_dot_git

  cmd = "git --git-dir=#{path_to_dot_git} config --get remote.origin.url"
  url = %x[#{cmd}];
  raise ArgumentError.new "No remote origin url.\n#{cmd}\n" if url.nil?
  
  return url.strip

end

.wc_revision(path_to_dot_git) ⇒ Object

– ————————————————– – # – Get brief revision of repo from working copy path. – # – ————————————————– – # – Parameter – # – path_to_dot_git : local path to .git folder – # – – # – Dependencies and Assumptions – # – we return the first 7 revision chars – # – git is installed on the machine – # – working copy exists and has remote origin – # – ————————————————– – #



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 134

def self.wc_revision path_to_dot_git

  log.info(ere) { "GitFlow path to dot git is => #{path_to_dot_git}" }
  Throw.if_not_exists path_to_dot_git

  uncut_revision = wc_revision_uncut path_to_dot_git
  log.info(ere) { "GitFlow uncut full revision is => #{uncut_revision}" }

  # -- --------------------------------------------------------------------- -- #
  # -- Gits [short revision] hash has 7 chars. Note 4 is the usable minimum. -- #
  # -- For usage in stamps where space comes at a premium - 6 chars will do. -- #
  # -- --------------------------------------------------------------------- -- #
  ref_length = 7
  return "r" + uncut_revision[0..(ref_length - 1)];

end

.wc_revision_uncut(path_to_dot_git) ⇒ Object

– ————————————————– – # – Get the uncut revision of a git repo working copy. – # – ————————————————– – # – Parameter – # – path_to_dot_git : local path to .git folder – # – – # – Dependencies and Assumptions – # – git is installed on the machine – # – working copy exists and has remote origin – # – ————————————————– – #



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/opensecret/plugins.io/git/git.flow.rb', line 100

def self.wc_revision_uncut path_to_dot_git

  log.info(ere) { "##### GitFlow path to dot git is => #{path_to_dot_git}" }
  repo_url = wc_origin_url path_to_dot_git
  log.info(ere) { "##### The GitFlow repo url is => #{repo_url}" }

  ## Bug HERE - On Ubuntu the branch name is like => (HEAD detached at 067f9a3)
  ## Bug HERE - This creates a failure of => sh: 1: Syntax error: "(" unexpected
  ## Bug HERE - The unexpected failure occurs in the ls-remote command below
  ## Bug HERE - So hardcoding this to "master" for now
  # branch_name = wc_branch_name path_to_dot_git
  branch_name = "master"

  log.info(ere) { "##### The GitFlow branch name is => #{branch_name}" }
  cmd = "git ls-remote #{repo_url} ls-remote -b #{branch_name}"
  log.info(ere) { "##### The GitFlow get dirty rev command is => #{cmd}" }
  dirty_revision = %x[#{cmd}];
  log.info(ere) { "##### The dirty revision is => #{dirty_revision}" }
  return dirty_revision.partition("refs/heads").first.strip;

end