Class: Omnibus::BuildVersion

Inherits:
Object
  • Object
show all
Includes:
Logging, Util
Defined in:
lib/omnibus/build_version.rb

Overview

TODO:

Rename this class to reflect its absolute dependence on running in a Git repository.

Note:

Requires a Git repository

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

Constant Summary collapse

TIMESTAMP_FORMAT =

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

See Also:

'%Y%m%d%H%M%S'

Constants included from Util

Util::SHELLOUT_OPTIONS

Version Generator Methods collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util

#copy_file, #create_directory, #create_file, #create_link, included, #remove_directory, #remove_file, #shellout, #shellout!, #windows_safe_path

Methods included from Logging

included

Constructor Details

#initialize(path = Config.project_root) ⇒ BuildVersion

Create a new BuildVersion

Parameters:

  • path (String) (defaults to: Config.project_root)

    Path from which to read git version information


59
60
61
# File 'lib/omnibus/build_version.rb', line 59

def initialize(path = Config.project_root)
  @path = path
end

Class Method Details

.build_start_timeObject


50
51
52
# File 'lib/omnibus/build_version.rb', line 50

def build_start_time
  new.build_start_time
end

.git_describeObject

See Also:

  • (BuildVersion(BuildVersion#git_describe)

41
42
43
# File 'lib/omnibus/build_version.rb', line 41

def git_describe
  new.git_describe
end

.semverObject

See Also:

  • (BuildVersion(BuildVersion#semver)

46
47
48
# File 'lib/omnibus/build_version.rb', line 46

def semver
  new.semver
end

Instance Method Details

#build_start_timeObject

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.


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/omnibus/build_version.rb', line 130

def build_start_time
  @build_start_time ||= begin
                          if ENV['BUILD_ID']
                            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.strftime(TIMESTAMP_FORMAT)
end

#commits_since_tagFixnum

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

Returns:

  • (Fixnum)

242
243
244
245
246
# File 'lib/omnibus/build_version.rb', line 242

def commits_since_tag
  commits_regexp = /^.*-(\d+)\-g[0-9a-f]+$/
  match = commits_regexp.match(git_describe)
  match ? match[1].to_i : 0
end

#git_describeString

Generates a version string by running git describe in the root of the Omnibus project.

Produces a version string of the format

MOST_RECENT_TAG-COMMITS_SINCE-gGIT_SHA

Examples:

11.0.0-alpha.1-207-g694b062

Returns:

  • (String)

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/omnibus/build_version.rb', line 158

def git_describe
  @git_describe ||= begin
    cmd = shellout('git describe --tags', cwd: @path)

    if cmd.exitstatus == 0
      cmd.stdout.chomp
    else
      log.warn(log_key) do
        "Could not extract version information from 'git describe'! " \
        "Setting version to 0.0.0."
      end
      '0.0.0'
    end
  end
end

#git_sha_tagString?

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

Returns:

  • (String)

    the truncated SHA1

  • (nil)

    if no SHA1 is present in the output of #git_describe


225
226
227
228
229
# File 'lib/omnibus/build_version.rb', line 225

def git_sha_tag
  sha_regexp = /g([0-9a-f]+)$/
  match = sha_regexp.match(git_describe)
  match ? match[1] : nil
end

#prerelease_tagString?

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

Returns:

  • (String)

    if a pre-release tag was found

  • (nil)

    if no pre-release tag was found


204
205
206
207
208
209
210
211
212
# File 'lib/omnibus/build_version.rb', line 204

def prerelease_tag
  prerelease_regex = if commits_since_tag > 0
                       /^v?\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)-\d+-g[0-9a-f]+$/
                     else
                       /^v?\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)$/
                     end
  match = prerelease_regex.match(git_describe)
  match ? match[1] : nil
end

#prerelease_version?Boolean

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

Returns:

  • (Boolean)

See Also:


254
255
256
257
258
259
260
# File 'lib/omnibus/build_version.rb', line 254

def prerelease_version?
  if prerelease_tag
    true
  else
    false
  end
end

#semverString

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.

Generate a 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 TIMESTAMP_FORMAT). This option is configurable via the Config.

Examples:

11.0.0-alpha.1+20121218164140.git.207.694b062

Returns:

  • (String)

See Also:


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/omnibus/build_version.rb', line 88

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
  if Config.append_timestamp
    build_version_items << build_start_time
  end

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

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

Returns:

  • (String)

189
190
191
# File 'lib/omnibus/build_version.rb', line 189

def version_tag
  version_composition.join('.')
end