Class: SafeDb::GitFlow
- Inherits:
-
Object
- Object
- SafeDb::GitFlow
- Defined in:
- lib/utils/git/gitflow.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.
Class Method Summary collapse
-
.add_file(repo_path, file_path) ⇒ Object
Add a specific file that exists in the working copy to the git version controller.
-
.add_origin_url(repo_path, origin_url) ⇒ Object
Add the parameter remote origin URL to the git repository at the stated path.
-
.commit(repo_path, commit_msg) ⇒ Object
Commit all changes to the local git repo at the stated folder path with the parameter commit message.
-
.config(repo_path, user_email, user_name) ⇒ Object
Configure the user.email and user.name properties for the git software to use alongside its other commands.
-
.del_file(repo_path, file_path) ⇒ Object
Remove a specific file from git management and also delete the working copy version of the file.
-
.do_clone_repo(repo_url, non_existent_path) ⇒ Object
– – Clone a remote repository at the specified [url] into – a [NON-EXISTENT] folder path.
-
.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.
-
.do_clone_wc(path_to_dot_git, path_to_new_dir) ⇒ Object
– ————————————————– – # – Clone the branch of a local git repo working copy.
-
.file_names(repo_url) ⇒ Object
– ————————————————- – # – Return an array of simple file names in the repo.
-
.git2zip(repo_url, path_offset, target_dir, zip_basename) ⇒ Object
– ———————————————— – # – Move assets from a git repo to a local zip file.
-
.init(repo_path) ⇒ Object
Make the folder at the given path a git repository if it is not one already.
-
.list(repo_path, by_line = false) ⇒ Object
Log the files (names and/or content) that either do not come under the wing of git or have been added to git repository management but are yet to be committed into the repository.
-
.push(repo_path) ⇒ Object
Push the commit bundles to the remote git repository.
-
.set_push_origin_url(repo_path, push_origin_url) ⇒ Object
Set only the origin url to push to.
-
.stage(repo_path) ⇒ Object
Stage all files that evoke some kind of difference between the working copy and the local git repository so that they can all be committed.
-
.wc_branch_name(path_to_dot_git) ⇒ Object
– ————————————————- – # – Return the branch name of a local git repository.
-
.wc_origin_url(path_to_dot_git) ⇒ Object
– ————————————————- – # – Get the remote origin url of a git working copy.
-
.wc_revision(path_to_dot_git) ⇒ Object
– ————————————————– – # – Get brief revision of repo from working copy path.
-
.wc_revision_uncut(path_to_dot_git) ⇒ Object
– ————————————————– – # – Get the uncut revision of a git repo working copy.
Class Method Details
.add_file(repo_path, file_path) ⇒ Object
Add a specific file that exists in the working copy to the git version controller.
145 146 147 148 149 150 151 152 153 |
# File 'lib/utils/git/gitflow.rb', line 145 def self.add_file( repo_path, file_path ) path_to_dot_git = File.join( repo_path, ".git" ) git_add_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} add #{file_path}" log.info(x) { "[git] single file add command => #{git_add_cmd}" } %x[#{git_add_cmd}]; log.info(x) { "[git] has added #{file_path} into the git repository." } end |
.add_origin_url(repo_path, origin_url) ⇒ Object
Add the parameter remote origin URL to the git repository at the stated path. This method assumes the origin url is non-sensitive and logs it. No passwords or access tokens expected in the url.
Use in conjunction with set_push_origin_url to create a push url that is different from the fetch url.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/utils/git/gitflow.rb', line 167 def self.add_origin_url repo_path, origin_url path_to_dot_git = File.join( repo_path, ".git" ) git_add_origin_loggable_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} remote add origin" git_add_origin_cmd = "#{git_add_origin_loggable_cmd} #{origin_url}" log.info(x) { "[git] add origin command without url => #{git_add_origin_loggable_cmd}" } %x[#{git_add_origin_cmd}]; log.info(x) { "[git] has added a remote origin url." } end |
.commit(repo_path, commit_msg) ⇒ Object
Commit all changes to the local git repo at the stated folder path with the parameter commit message.
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/utils/git/gitflow.rb', line 85 def self.commit( repo_path, commit_msg ) log.info(x) { "[git] commit msg => #{commit_msg}" } path_to_dot_git = File.join( repo_path, ".git" ) git_commit_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} commit -m \"#{commit_msg}\";" log.info(x) { "[git] commit command => #{git_commit_cmd}" } %x[#{git_commit_cmd}]; log.info(x) { "[git] has committed resources into the local repository." } end |
.config(repo_path, user_email, user_name) ⇒ Object
Configure the user.email and user.name properties for the git software to use alongside its other commands. This must always be done before a git commit command is issued.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/utils/git/gitflow.rb', line 105 def self.config( repo_path, user_email, user_name ) log.info(x) { "[git] local config for user.email => #{user_email}" } log.info(x) { "[git] local config for user.name => #{user_name}" } path_to_dot_git = File.join( repo_path, ".git" ) git_config_email_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} config --local user.email \"#{user_email}\";" git_config_name_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} config --local user.name \"#{user_name}\";" log.info(x) { "[git] configure user.email command => #{git_config_email_cmd}" } log.info(x) { "[git] configure user.name command => #{git_config_name_cmd}" } %x[#{git_config_email_cmd}]; %x[#{git_config_name_cmd}]; log.info(x) { "[git] has locally configured the user.email and user.name properties." } end |
.del_file(repo_path, file_path) ⇒ Object
Remove a specific file from git management and also delete the working copy version of the file.
127 128 129 130 131 132 133 134 135 |
# File 'lib/utils/git/gitflow.rb', line 127 def self.del_file( repo_path, file_path ) path_to_dot_git = File.join( repo_path, ".git" ) git_rm_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} rm #{file_path}" log.info(x) { "[git] file remove command => #{git_rm_cmd}" } %x[#{git_rm_cmd}]; log.info(x) { "[git] has removed #{file_path} from repo and working copy." } end |
.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 –
405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'lib/utils/git/gitflow.rb', line 405 def self.do_clone_repo repo_url, non_existent_path cmd = "git clone #{repo_url} #{non_existent_path}" clone_output = %x[#{cmd}]; log.info(x) { "[gitflow] cloning remote repository" } log.info(x) { "[gitflow] git repository url : #{repo_url}" } log.info(x) { "[gitflow] git clone dir path : #{nickname non_existent_path}" } log.info(x) { "[gitflow] git clone command : #{cmd}" } log.info(x) { "[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 – # – —————————————————– – #
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/utils/git/gitflow.rb', line 435 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(x) { "[clone repos] proj [index] => #{repo_index}" } log.info(x) { "[clone repos] repo url 1st => #{repo_url}" } log.info(x) { "[clone repos] repo url 2nd => #{git_url}" } log.info(x) { "[clone repos] project name => #{base_names[repo_index]}" } log.info(x) { "[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 – # – ————————————————– – #
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
# File 'lib/utils/git/gitflow.rb', line 338 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(x) { "[gitflow] cloning working copy" } log.info(x) { "[gitflow] repo branch name : #{branch_name}" } log.info(x) { "[gitflow] src dot git path : #{path_to_dot_git}" } log.info(x) { "[gitflow] new wc dir path : #{path_to_new_dir}" } log.info(x) { "[gitflow] git clone command : #{cmd}" } log.info(x) { "[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 – # – ————————————————- – #
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/utils/git/gitflow.rb', line 529 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(x) { "[git2files] ----------------------------------------------" } log.info(x) { "[git2files] [#{names_list.length}] files in [#{repo_url}]" } log.info(x) { "[git2files] ----------------------------------------------" } log.info(x) { "[git2files] Random Text : #{random_text}" } log.info(x) { "[git2files] Cloned Name : #{cloned_name}" } log.info(x) { "[git2files] Cloned Path : #{cloned_path}" } log.info(x) { "[git2files] Repo Folder : #{dot_git_path}" } log.info(x) { "[git2files] Reading Cmd : #{cmd}" } log.info(x) { "[git2files] ----------------------------------------------" } pp names_list log.info(x) { "[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 – # – – # – ———————————————— – #
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
# File 'lib/utils/git/gitflow.rb', line 485 def self.git2zip repo_url, path_offset, target_dir, zip_basename log.info(x) { "[git2zip] ------------------------------------------- -- #" } log.info(x) { "[git2zip] archiving repo assets at path offset -- #" } log.info(x) { "[git2zip] ------------------------------------------- -- #" } log.info(x) { "[git2zip] git repository url : #{repo_url}" } log.info(x) { "[git2zip] slash tail dir offset : #{path_offset}" } log.info(x) { "[git2zip] target zip directory : #{target_dir}" } log.info(x) { "[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(x) { "[git2zip] tmp clone src folder : #{clone_dir}" } log.info(x) { "[git2zip] cloned dot git path : #{dot_git_path}" } log.info(x) { "[git2zip] target zip full path : #{dst_zip_path}" } log.info(x) { "[git2zip] git archive command : #{cmd}" } log.info(x) { "[git2zip] ------------------------------------------- -- #" } log.info(x) { "#{clone_output}" } log.info(x) { "[git2zip] ------------------------------------------- -- #" } return dst_zip_path end |
.init(repo_path) ⇒ Object
Make the folder at the given path a git repository if it is not one already. If the folder is already under git management then this call has no effect.
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/utils/git/gitflow.rb', line 17 def self.init repo_path git_init_cmd = "git init #{repo_path}" log.info(x) { "[git] add command => #{git_init_cmd}" } cmd_output = %x[#{git_init_cmd}]; log.info(x) { "[git] initializing git repository at path #{repo_path}" } log.info(x) { "[git] init command output : #{cmd_output}" } end |
.list(repo_path, by_line = false) ⇒ Object
Log the files (names and/or content) that either do not come under the wing of git or have been added to git repository management but are yet to be committed into the repository. Also an files are logged that have either been updated, deleted or moved.
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/utils/git/gitflow.rb', line 39 def self.list( repo_path, by_line=false ) path_to_dot_git = File.join( repo_path, ".git" ) line_by_line = by_line ? "-v" : "" git_log_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} status #{line_by_line}" log.info(x) { "[git] status command => #{git_log_cmd}" } git_log_output = %x[#{git_log_cmd}] git_log_output.log_debug if by_line git_log_output.log_info unless by_line end |
.push(repo_path) ⇒ Object
Push the commit bundles to the remote git repository.
205 206 207 208 209 210 211 212 213 |
# File 'lib/utils/git/gitflow.rb', line 205 def self.push repo_path path_to_dot_git = File.join( repo_path, ".git" ) git_push_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} push origin master" log.info(x) { "[git] push command => #{git_push_cmd}" } system git_push_cmd log.info(x) { "[git] has pushed outstanding commit bundles to the remote backend repository." } end |
.set_push_origin_url(repo_path, push_origin_url) ⇒ Object
Set only the origin url to push to. This command leaves the fetch url as is. The push_origin_url is assumed sensitive as it may contain either passwords or access tokens. As such it is not logged.
The remote origin must be set before calling this method. If no origin is set this will throw a “no origin” error.
189 190 191 192 193 194 195 196 197 198 |
# File 'lib/utils/git/gitflow.rb', line 189 def self.set_push_origin_url repo_path, push_origin_url path_to_dot_git = File.join( repo_path, ".git" ) git_loggable_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} remote set-url --push origin" git_set_push_origin_url_cmd = "#{git_loggable_cmd} #{push_origin_url}" log.info(x) { "[git] set push origin url command without url => #{git_loggable_cmd}" } %x[#{git_set_push_origin_url_cmd}]; log.info(x) { "[git] has set the remote origin url for pushing." } end |
.stage(repo_path) ⇒ Object
Stage all files that evoke some kind of difference between the working copy and the local git repository so that they can all be committed.
Files that will be staged by this method can be
-
newly created files (that do not match gitignore patterns)
-
modified files that are already under git version management
-
files deleted in the working copy but not removed from the repository
-
files renamed in the same folder or with their path changed too
-
all the above but found recursively under the root repository path
68 69 70 71 72 73 74 75 76 |
# File 'lib/utils/git/gitflow.rb', line 68 def self.stage repo_path path_to_dot_git = File.join( repo_path, ".git" ) git_add_cmd = "git --git-dir=#{path_to_dot_git} --work-tree=#{repo_path} add -A" log.info(x) { "[git] add command => #{git_add_cmd}" } %x[#{git_add_cmd}]; log.info(x) { "[git] has recursively added resources to version management." } 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 – # – ————————————————- – #
232 233 234 235 236 237 238 239 240 241 |
# File 'lib/utils/git/gitflow.rb', line 232 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 – # – ————————————————- – #
254 255 256 257 258 259 260 261 262 |
# File 'lib/utils/git/gitflow.rb', line 254 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 – # – ————————————————– – #
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/utils/git/gitflow.rb', line 309 def self.wc_revision path_to_dot_git log.info(x) { "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(x) { "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 – # – ————————————————– – #
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/utils/git/gitflow.rb', line 275 def self.wc_revision_uncut path_to_dot_git log.info(x) { "##### GitFlow path to dot git is => #{path_to_dot_git}" } repo_url = wc_origin_url path_to_dot_git log.info(x) { "##### 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(x) { "##### The GitFlow branch name is => #{branch_name}" } cmd = "git ls-remote #{repo_url} ls-remote -b #{branch_name}" log.info(x) { "##### The GitFlow get dirty rev command is => #{cmd}" } dirty_revision = %x[#{cmd}]; log.info(x) { "##### The dirty revision is => #{dirty_revision}" } return dirty_revision.partition("refs/heads").first.strip; end |