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
@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
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
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
@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
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
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
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
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
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
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
# 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
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
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