Module: GitTools

Includes:
Thor::Actions
Included in:
Rain::Deployer
Defined in:
lib/rain/git_tools.rb,
lib/rain/git_tools/release_tag.rb

Overview

A collection of methods and a class, ReleaseTag, for querying the local Git repository. Originally part of the Thor binary, it was extracted to its own module after Rain::Deployer got too large.

Defined Under Namespace

Classes: ReleaseTag

Instance Method Summary collapse

Instance Method Details

#git_nameObject Also known as: deployer

Display name as set in ~/.gitconfig



43
44
45
# File 'lib/rain/git_tools.rb', line 43

def git_name
  %x(git config --get user.name).split("\n")[0]
end

#last_release_tagObject

Moved code to ReleaseTag. Basically returns a ReleaseTag with a version equal to the latest Git tag.



38
39
40
# File 'lib/rain/git_tools.rb', line 38

def last_release_tag
  ReleaseTag.latest
end

#no_changes_pending?Boolean

Test whether there are any uncommitted changes in the working directory.

Returns:



32
33
34
# File 'lib/rain/git_tools.rb', line 32

def no_changes_pending?
  %x(git status --porcelain).split("\n").length == 0
end

#on_master?Boolean

Test whether we are currently using the master branch. All deployment activity should take place on the master branch.

Returns:



25
26
27
28
# File 'lib/rain/git_tools.rb', line 25

def on_master?
  out = %x(git symbolic-ref -q HEAD)
  out.strip == "refs/heads/master"
end

#push_tag(tag) ⇒ Object

Push a given ReleaseTag to origin. You must have a Git remote set up for this to work.



78
79
80
81
82
83
# File 'lib/rain/git_tools.rb', line 78

def push_tag(tag)
  unless tag.nil?
    run_cmd "git push origin #{tag}"
    raise "Error: Push failed and deploy has been cancelled" if $?.exitstatus > 0
  end
end

#run_cmd(cmd) ⇒ Object

Execute any shell commnad, unless we’re testing. But always print what is/what would have been executed onto stdout.



87
88
89
90
# File 'lib/rain/git_tools.rb', line 87

def run_cmd(cmd)
  puts "executing... #{cmd}"
  %x(#{cmd}) unless ENV['RAILS_ENV'] == "test"
end

#tagged_latest_version?Boolean

Compares the latest Git tag with the latest version name in YAML. If both of those are equal, this returns true, because the Git tags are in sync with versions.yml

Returns:



51
52
53
# File 'lib/rain/git_tools.rb', line 51

def tagged_latest_version?
  ReleaseTag.latest == ReleaseTag.current
end

#update_release_tag(environment, tag) ⇒ Object

Write the newest ReleaseTag’s version number to versions.yml, save it, and commit/push it to origin/master.



108
109
110
111
112
113
114
# File 'lib/rain/git_tools.rb', line 108

def update_release_tag(environment, tag)
  hsh = versions_hash
  hsh[environment] = tag.to_s
  File.write(versions_path, hsh.to_yaml.to_s)
  run_cmd "git commit -m '[RELEASE][#{environment}] Update release tag for #{environment} to #{tag}' #{versions_path}"
  run_cmd "git push origin master"
end

#versions_hashObject

A YAML-parsed Hash of the versions.yml file.



102
103
104
# File 'lib/rain/git_tools.rb', line 102

def versions_hash
  YAML.load_file(versions_path)
end

#versions_pathObject

Full path of the versions.yml file in the Rails app.



93
94
95
96
97
98
99
# File 'lib/rain/git_tools.rb', line 93

def versions_path
  if ENV['RAILS_ENV'] == 'test'
    File.expand_path "./test/dummy/config/versions.yml"
  else
    File.expand_path "./config/versions.yml" # stage, prod, etc.
  end
end

#working_directory_copasetic?(options = {}) ⇒ Boolean

A short user prompt if there are uncommitted changes in the repo, in case the user forgets before they deploy. Naturally, one may cancel this process effectively cancelling the entire deploy cleanly. This occurs before any hard changes (e.g., writing changes, pushes, command execution, etc.) are made.

Returns:



16
17
18
19
20
21
# File 'lib/rain/git_tools.rb', line 16

def working_directory_copasetic?(options={})
  return true if options[:force]
  return false unless no_changes_pending? || yes?("There are currently uncommitted changes.  Are you sure you want to continue? [y/N]")
  return false unless on_master? || yes?("You are not currently on the master branch.  Are you sure you want to continue? [y/N]")
  true
end