lib/roger/release/scm/git.rb in roger-1.1.3 vs lib/roger/release/scm/git.rb in roger-1.2.1

- old
+ new

@@ -1,106 +1,115 @@ -require 'pathname' +require "pathname" -module Roger::Release::Scm - class Git < Base - - # @option config [String] :ref Ref to use for current tag - # @option config [String, Pathname] :path Path to working dir - def initialize(config={}) - super(config) - @config[:ref] ||= "HEAD" - end - - # 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 - def version - get_scm_data if @_version.nil? - @_version - end - - # Date will be Time.now if it can't be determined from GIT repository - def date - get_scm_data if @_date.nil? - @_date - end - - def previous - self.class.new(@config.dup.update(:ref => get_previous_tag_name)) - end - - protected - - def get_previous_tag_name - # Get list of SHA1 that have a ref - begin - sha1s = `git --git-dir=#{safe_git_dir} log --pretty='%H' --simplify-by-decoration`.split("\n") - tags = [] - while tags.size < 2 && sha1s.any? - sha1 = sha1s.shift - tag = `git --git-dir=#{safe_git_dir} describe --tags --exact-match #{sha1} 2>/dev/null`.strip - tags << tag if !tag.empty? +module Roger + class Release + module Scm + # The GIT SCM implementation for Roger release + class Git < Base + # @option config [String] :ref Ref to use for current tag + # @option config [String, Pathname] :path Path to working dir + def initialize(config = {}) + super(config) + @config[:ref] ||= "HEAD" end - tags.last - rescue - raise "Could not get previous tag" - end - end - - def git_dir - @git_dir ||= find_git_dir(@config[:path]) - end - # Safely escaped git dir - def safe_git_dir - Shellwords.escape(self.git_dir.to_s) - end + # 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 + def version + get_scm_data if @_version.nil? + @_version + end - # Some hackery to determine if we're on a tagged version or not - def get_scm_data(ref = @config[:ref]) - @_version = "" - @_date = Time.now - begin - if File.exist?(git_dir) - @_version = `git --git-dir=#{safe_git_dir} describe --tags #{ref} 2>&1` - - if $?.to_i > 0 - # HEAD is not a tagged verison, get the short SHA1 instead - @_version = `git --git-dir=#{safe_git_dir} show #{ref} --format=format:"%h" -s 2>&1` + # Date will be Time.now if it can't be determined from GIT repository + def date + get_scm_data if @_date.nil? + @_date + end + + def previous + self.class.new(@config.dup.update(ref: get_previous_tag_name)) + end + + protected + + 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} 2>/dev/null` + tag = tag.strip + tags << tag unless tag.empty? + end + tags.last + rescue + raise "Could not get previous tag" + end + + def git_dir + @git_dir ||= find_git_dir(@config[:path]) + end + + # Safely escaped git dir + def safe_git_dir + Shellwords.escape(git_dir.to_s) + end + + # Preload version control data. + def get_scm_data(ref = @config[:ref]) + @_version = scm_version(ref) || "" + @_date = scm_date(ref) || Time.now + end + + # Some hackery to determine if ref is on a tagged version or not + # @return [String, nil] Will return version number if available, nil otherwise + def scm_version(ref) + return nil unless File.exist?(git_dir) + + version = `git --git-dir=#{safe_git_dir} describe --tags #{ref} 2>&1` + + if $CHILD_STATUS.to_i > 0 + # HEAD is not a tagged version, get the short SHA1 instead + version = `git --git-dir=#{safe_git_dir} show #{ref} --format=format:"%h" -s 2>&1` else # HEAD is a tagged version, if version is prefixed with "v" it will be stripped off - @_version.gsub!(/^v/,"") + version.gsub!(/^v/, "") end - @_version.strip! - + + version.strip! + rescue RuntimeError + nil + end + + # Get date of ref from git + # @return [Time, nil] Returns time if available and parseable, nil otherwise + 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 2>&1` - if date =~ /\d+/ - @_date = Time.at(date.to_i) - else - @_date = Time.now + Time.at(date.to_i) if date =~ /\d+/ + rescue RuntimeError + nil + end + + # Find the git dir + def find_git_dir(path) + path = Pathname.new(path).realpath + while path.parent != path && !(path + ".git").directory? + path = path.parent end - + + path += ".git" + + fail "Could not find suitable .git dir in #{path}" unless path.directory? + + path end - rescue RuntimeError => e end - end - - # Find the git dir - def find_git_dir(path) - path = Pathname.new(path).realpath - while path.parent != path && !(path + ".git").directory? - path = path.parent - end - - path = path + ".git" - - raise "Could not find suitable .git dir in #{path}" if !path.directory? - - path - end - end end -