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


55
56
57
# File 'lib/omnibus/build_version.rb', line 55

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

Class Method Details

.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

#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

218
219
220
221
222
# File 'lib/omnibus/build_version.rb', line 218

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

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/omnibus/build_version.rb', line 134

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

201
202
203
204
205
# File 'lib/omnibus/build_version.rb', line 201

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

180
181
182
183
184
185
186
187
188
# File 'lib/omnibus/build_version.rb', line 180

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?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.

See Also:


230
231
232
233
234
235
236
# File 'lib/omnibus/build_version.rb', line 230

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


See Also:


84
85
86
87
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
# File 'lib/omnibus/build_version.rb', line 84

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.strftime(TIMESTAMP_FORMAT)
  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

165
166
167
# File 'lib/omnibus/build_version.rb', line 165

def version_tag
  version_composition.join('.')
end