class Omnibus::BuildVersion

Provides methods for generating Omnibus project build version strings automatically from Git repository information.

@see Omnibus::Project#build_version

@note Requires a Git repository @todo Add class method shortcuts for semver and git_describe

versions e.g., Omnibus::BuildVersion.semver.

@todo Rename this class to reflect its absolute dependence on running in a

Git repository.

Constants

TIMESTAMP_FORMAT

Formatting string for the timestamp component of our SemVer build specifier.

@see Omnibus::BuildVersion#semver @see Time#strftime

Public Class Methods

full() click to toggle source

@deprecated Use {#semver} or {#git_describe} instead

# File lib/omnibus/build_version.rb, line 43
def self.full
  puts "#{self.name}.full is deprecated. Use #{self.name}.new.semver or #{self.name}.new.git_describe."
  Omnibus::BuildVersion.new.git_describe
end
new(path=Omnibus.root) click to toggle source

Create a new BuildVersion

@param [String] path Path from which to read git version information

# File lib/omnibus/build_version.rb, line 51
def initialize(path=Omnibus.root)
  @path = path
end

Public Instance Methods

commits_since_tag() click to toggle source

Extracts the number of commits since the most recent Git tag, as determined by {#git_describe}.

Here are some illustrative examples:

1.2.7-208-ge908a52 -> 208
11.0.0-alpha-59-gf55b180 -> 59
11.0.0-alpha2 -> 0
10.16.2.rc.1 -> 0

@return [Fixnum]

# File lib/omnibus/build_version.rb, line 216
def commits_since_tag
  commits_regexp = /^.*-(\d+)\-g[0-9a-f]+$/
  match = commits_regexp.match(git_describe)
  match ? match[1].to_i : 0
end
development_version?() click to toggle source

@todo This method is never called in Omnibus. Is this even used

(e.g., in the DSL files)?
# File lib/omnibus/build_version.rb, line 224
def development_version?
  patch = version_composition.last
  patch.to_i.odd?
end
git_describe() click to toggle source

Generates a version string by running {www.kernel.org/pub/software/scm/git/docs/git-describe.html git describe} in the root of the Omnibus project.

Produces a version string of the format

MOST_RECENT_TAG-COMMITS_SINCE-gGIT_SHA

@example

11.0.0-alpha.1-207-g694b062

@return [String]

# File lib/omnibus/build_version.rb, line 131
def git_describe
  @git_describe ||= begin
                      git_cmd = "git describe"
                      cmd = shellout(git_cmd,
                                     :live_stream => nil,
                                     :cwd => @path)
                      if cmd.exitstatus == 0
                        cmd.stdout.chomp
                      else
                        msg =  "Could not extract version information from `git describe`. "
                        msg << "Setting version to 0.0.0"
                        puts msg
                        "0.0.0"
                      end
                    end
end
git_sha_tag() click to toggle source

Extracts the 7-character truncated Git SHA1 from the output of {#git_describe}.

Here are some illustrative examples:

1.2.7-208-ge908a52 -> e908a52
11.0.0-alpha-59-gf55b180 -> f55b180
11.0.0-alpha2 -> nil
10.16.2.rc.1 -> nil

@return [String] the truncated SHA1 @return [nil] if no SHA1 is present in the output of #{git_describe}

# File lib/omnibus/build_version.rb, line 199
def git_sha_tag
  sha_regexp = /g([0-9a-f]+)$/
  match = sha_regexp.match(git_describe)
  match ? match[1] : nil
end
prerelease_tag() click to toggle source

Return a prerelease tag string (if it exists), as extracted from {#git_describe}.

Here are some illustrative examples:

1.2.7-208-ge908a52 -> nil
11.0.0-alpha-59-gf55b180 -> alpha
11.0.0-alpha2 -> alpha2
10.16.2.rc.1 -> rc.1

@return [String] if a pre-release tag was found @return [nil] if no pre-release tag was found

# File lib/omnibus/build_version.rb, line 178
def prerelease_tag
  prerelease_regex = if commits_since_tag > 0
                       /^\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)-\d+-g[0-9a-f]+$/
                     else
                       /^\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)$/
                     end
  match = prerelease_regex.match(git_describe)
  match ? match[1] : nil
end
prerelease_version?() click to toggle source

Indicates whether the version represents a pre-release or not, as signalled by the presence of a pre-release tag in the version string.

@return [Boolean] @see prerelease_tag

# File lib/omnibus/build_version.rb, line 235
def prerelease_version?
  !!(prerelease_tag)
end
semver() click to toggle source

Generate a {semver.org/ SemVer 2.0.0-rc.1 compliant} version string for an Omnibus project.

This relies on the Omnibus project being a Git repository, as well as having tags named according to SemVer conventions (specifically, the ‘MAJOR.MINOR.PATCH-PRERELEASE` aspects)

The specific format of the version string is:

MAJOR.MINOR.PATCH-PRERELEASE+TIMESTAMP.git.COMMITS_SINCE.GIT_SHA

By default, a timestamp is incorporated into the build component of version string (see {Omnibus::BuildVersion::TIMESTAMP_FORMAT}). This can be disabled by setting the environment variable ‘OMNIBUS_APPEND_TIMESTAMP` to a “falsey” value (e.g. “false”, “f”, “no”, “n”, “0”)

@example 11.0.0-alpha.1+20121218164140.git.207.694b062 @return [String] @see git_describe @todo Issue a warning or throw an exception if the tags of the

repository are not themselves SemVer-compliant?

@todo Consider making the {#build_start_time} method public, as

its function influences how build timestamps are generated,
and can be influenced by users.
# File lib/omnibus/build_version.rb, line 83
def semver
  build_tag = version_tag

  # PRERELEASE VERSION
  if prerelease_version?
    # ensure all dashes are dots per precedence rules (#12) in Semver
    # 2.0.0-rc.1
    prerelease = prerelease_tag.gsub("-", ".")
    build_tag << "-" << prerelease
  end

  # BUILD VERSION
  # Follows SemVer conventions and the build version begins with a '+'.
  build_version_items = []

  # By default we will append a timestamp to every build. This behavior can
  # be overriden by setting the OMNIBUS_APPEND_TIMESTAMP environment
  # variable to a 'falsey' value (ie false, f, no, n or 0).
  #
  # format: YYYYMMDDHHMMSS example: 20130131123345
  build_version_items << build_start_time.strftime(TIMESTAMP_FORMAT) if append_timestamp?

  # We'll append the git describe information unless we are sitting right
  # on an annotated tag.
  #
  # format: git.COMMITS_SINCE_TAG.GIT_SHA example: git.207.694b062
  unless commits_since_tag == 0
    build_version_items << ["git", commits_since_tag, git_sha_tag].join(".")
  end

  unless build_version_items.empty?
    build_tag << "+" << build_version_items.join(".")
  end

  build_tag
end
version_tag() click to toggle source

Return a ‘MAJOR.MINOR.PATCH` version string, as extracted from {#git_describe}.

Here are some illustrative examples:

1.2.7-208-ge908a52 -> 1.2.7
11.0.0-alpha-59-gf55b180 -> 11.0.0
11.0.0-alpha2 -> 11.0.0
10.16.2.rc.1 -> 10.16.2

@return [String]

# File lib/omnibus/build_version.rb, line 163
def version_tag
  version_composition.join(".")
end

Private Instance Methods

append_timestamp?() click to toggle source
# File lib/omnibus/build_version.rb, line 275
def append_timestamp?
  if ENV['OMNIBUS_APPEND_TIMESTAMP'] && (ENV['OMNIBUS_APPEND_TIMESTAMP'] =~ (/^(false|f|no|n|0)$/i))
    false
  elsif ENV['OMNIBUS_APPEND_TIMESTAMP'] && (ENV['OMNIBUS_APPEND_TIMESTAMP'] =~ (/^(true|t|yes|y|1)$/i))
    true
  else
    Omnibus::Config.append_timestamp
  end
end
build_start_time() click to toggle source

We’ll attempt to retrive the timestamp from the Jenkin’s set BUILD_ID environment variable. This will ensure platform specfic packages for the same build will share the same timestamp.

# File lib/omnibus/build_version.rb, line 244
def build_start_time
  @build_start_time ||= begin
                          if !ENV['BUILD_ID'].nil?
                            begin
                              Time.strptime(ENV['BUILD_ID'], "%Y-%m-%d_%H-%M-%S")
                            rescue ArgumentError
                              error_message =  "BUILD_ID environment variable "
                              error_message << "should be in YYYY-MM-DD_hh-mm-ss "
                              error_message << "format."
                              raise ArgumentError, error_message
                            end
                          else
                            Time.now.utc
                          end
                        end
end
version_composition() click to toggle source

Pulls out the major, minor, and patch components from the output of {#git_describe}.

Relies on the most recent Git tag being SemVer compliant (i.e., starting with a ‘MAJOR.MINOR.PATCH` string)

@return [Array<(String, String, String)>]

@todo Compute this once and store the result in an instance variable

# File lib/omnibus/build_version.rb, line 270
def version_composition
  version_regexp = /^(\d+)\.(\d+)\.(\d+)/
  version_regexp.match(git_describe)[1..3]
end