class Roger::Release::Scm::Git

The GIT SCM implementation for Roger release

Public Class Methods

find_git_dir(path) click to toggle source

Find the .git dir in path and all it's parents

# File lib/roger/release/scm/git.rb, line 10
def self.find_git_dir(path)
  path = Pathname.new(path).realpath
  while path.parent != path && !(path + ".git").directory?
    path = path.parent
  end

  path += ".git"

  raise "Could not find suitable .git dir in #{path}" unless path.directory?

  path
end
new(config = {}) click to toggle source

@option config [String] :ref Ref to use for current tag @option config [String, Pathname] :path Path to working dir

Calls superclass method Roger::Release::Scm::Base::new
# File lib/roger/release/scm/git.rb, line 25
def initialize(config = {})
  super(config)
  @config[:ref] ||= "HEAD"
end

Public Instance Methods

date() click to toggle source

Date will be Time.now if it can't be determined from GIT repository

# File lib/roger/release/scm/git.rb, line 40
def date
  get_scm_data if @_date.nil?
  @_date
end
previous() click to toggle source
# File lib/roger/release/scm/git.rb, line 45
def previous
  self.class.new(@config.dup.update(ref: get_previous_tag_name))
end
version() click to toggle source

Version is either:

  • the tagged version number (first “v” will be stripped) or

  • the return value of “git describe –tags HEAD”

  • the short SHA1 if there hasn't been a previous tag

# File lib/roger/release/scm/git.rb, line 34
def version
  get_scm_data if @_version.nil?
  @_version
end

Protected Instance Methods

get_previous_tag_name() click to toggle source
# File lib/roger/release/scm/git.rb, line 51
def get_previous_tag_name
  # Get list of SHA1 that have a ref
  sha1s = `git --git-dir=#{safe_git_dir} log --pretty="%H" --simplify-by-decoration`
  sha1s = sha1s.split("\n")
  tags = []
  while tags.size < 2 && sha1s.any?
    sha1 = sha1s.shift
    tag = `git --git-dir=#{safe_git_dir} describe --tags --exact-match #{sha1}`
    tag = tag.strip
    tags << tag unless tag.empty?
  end
  tags.last
rescue
  raise "Could not get previous tag"
end
get_scm_data(ref = @config[:ref]) click to toggle source

Preload version control data.

# File lib/roger/release/scm/git.rb, line 77
def get_scm_data(ref = @config[:ref])
  @_version = scm_version(ref) || ""
  @_date = scm_date(ref) || Time.now
end
git_dir() click to toggle source
# File lib/roger/release/scm/git.rb, line 67
def git_dir
  @git_dir ||= self.class.find_git_dir(@config[:path])
end
safe_git_dir() click to toggle source

Safely escaped git dir

# File lib/roger/release/scm/git.rb, line 72
def safe_git_dir
  Shellwords.escape(git_dir.to_s)
end
scm_date(ref) click to toggle source

Get date of ref from git @return [Time, nil] Returns time if available and parseable, nil otherwise

# File lib/roger/release/scm/git.rb, line 104
def scm_date(ref)
  return nil unless File.exist?(git_dir)

  # Get the date in epoch time
  date = `git --git-dir=#{safe_git_dir} show #{ref} --format=format:"%ct" -s`
  Time.at(date.to_i) if date =~ /\d+/
rescue RuntimeError
  nil
end
scm_version(ref) click to toggle source

Some hackery to determine if ref is on a tagged version or not @return [String, nil] Will return version number if available, nil otherwise

# File lib/roger/release/scm/git.rb, line 84
def scm_version(ref)
  return nil unless File.exist?(git_dir)

  version = `git --git-dir=#{safe_git_dir} describe --tags #{ref}`

  if $CHILD_STATUS.to_i.positive?
    # HEAD is not a tagged version, get the short SHA1 instead
    version = `git --git-dir=#{safe_git_dir} show #{ref} --format=format:"%h" -s`
  else
    # HEAD is a tagged version, if version is prefixed with "v" it will be stripped off
    version.gsub!(/^v/, "")
  end

  version.strip!
rescue RuntimeError
  nil
end