omnibus 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.yardopts +7 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +9 -0
  7. data/LICENSE +201 -0
  8. data/NOTICE +9 -0
  9. data/README.md +186 -0
  10. data/Rakefile +7 -0
  11. data/bin/makeself-header.sh +401 -0
  12. data/bin/makeself.sh +407 -0
  13. data/bin/omnibus +11 -0
  14. data/lib/omnibus.rb +280 -0
  15. data/lib/omnibus/build_version.rb +281 -0
  16. data/lib/omnibus/builder.rb +323 -0
  17. data/lib/omnibus/clean_tasks.rb +30 -0
  18. data/lib/omnibus/cli.rb +35 -0
  19. data/lib/omnibus/cli/application.rb +136 -0
  20. data/lib/omnibus/cli/base.rb +112 -0
  21. data/lib/omnibus/cli/build.rb +66 -0
  22. data/lib/omnibus/cli/cache.rb +60 -0
  23. data/lib/omnibus/config.rb +186 -0
  24. data/lib/omnibus/exceptions.rb +54 -0
  25. data/lib/omnibus/fetcher.rb +184 -0
  26. data/lib/omnibus/fetchers.rb +22 -0
  27. data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
  28. data/lib/omnibus/fetchers/net_fetcher.rb +191 -0
  29. data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
  30. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
  31. data/lib/omnibus/health_check.rb +260 -0
  32. data/lib/omnibus/library.rb +70 -0
  33. data/lib/omnibus/overrides.rb +69 -0
  34. data/lib/omnibus/project.rb +566 -0
  35. data/lib/omnibus/reports.rb +99 -0
  36. data/lib/omnibus/s3_cacher.rb +136 -0
  37. data/lib/omnibus/software.rb +430 -0
  38. data/lib/omnibus/templates/Berksfile.erb +3 -0
  39. data/lib/omnibus/templates/Gemfile.erb +4 -0
  40. data/lib/omnibus/templates/README.md.erb +102 -0
  41. data/lib/omnibus/templates/Vagrantfile.erb +95 -0
  42. data/lib/omnibus/templates/gitignore.erb +8 -0
  43. data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
  44. data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
  45. data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
  46. data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
  47. data/lib/omnibus/templates/project.rb.erb +21 -0
  48. data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
  49. data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
  50. data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
  51. data/lib/omnibus/util.rb +61 -0
  52. data/lib/omnibus/version.rb +20 -0
  53. data/omnibus.gemspec +34 -0
  54. data/spec/build_version_spec.rb +228 -0
  55. data/spec/data/overrides/bad_line.overrides +3 -0
  56. data/spec/data/overrides/good.overrides +5 -0
  57. data/spec/data/overrides/with_dupes.overrides +4 -0
  58. data/spec/data/software/erchef.rb +40 -0
  59. data/spec/overrides_spec.rb +114 -0
  60. data/spec/software_spec.rb +71 -0
  61. data/spec/spec_helper.rb +28 -0
  62. metadata +239 -0
data/bin/omnibus ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Trap interrupts to quit cleanly. See
4
+ # https://twitter.com/mitchellh/status/283014103189053442
5
+ Signal.trap("INT") { exit 1 }
6
+
7
+ $:.unshift File.expand_path("../../lib", __FILE__)
8
+
9
+ require 'omnibus/cli'
10
+
11
+ Omnibus::CLI::Application.start
data/lib/omnibus.rb ADDED
@@ -0,0 +1,280 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'ohai'
19
+ o = Ohai::System.new
20
+ o.require_plugin('os')
21
+ o.require_plugin('platform')
22
+ o.require_plugin('linux/cpu') if o.os == 'linux'
23
+ o.require_plugin('kernel')
24
+ OHAI = o
25
+
26
+ require 'omnibus/library'
27
+ require 'omnibus/reports'
28
+ require 'omnibus/config'
29
+ require 'omnibus/software'
30
+ require 'omnibus/project'
31
+ require 'omnibus/fetchers'
32
+ require 'omnibus/health_check'
33
+ require 'omnibus/build_version'
34
+ require 'omnibus/overrides'
35
+ require 'omnibus/version'
36
+
37
+ require 'pathname'
38
+
39
+ module Omnibus
40
+
41
+ DEFAULT_CONFIG_FILENAME = 'omnibus.rb'.freeze
42
+
43
+ # Configure Omnibus.
44
+ #
45
+ # After this has been called, the {Omnibus::Config} object is
46
+ # available as `Omnibus.config`.
47
+ #
48
+ # @return [void]
49
+ #
50
+ # @deprecated Use {#load_configuration} if you need to process a
51
+ # config file, followed by {#process_configuration} to act upon it.
52
+ def self.configure
53
+ load_configuration
54
+ process_configuration
55
+ end
56
+
57
+ # Convenience method for access to the Omnibus::Config object.
58
+ # Provided for backward compatibility.
59
+ #
60
+ # @ return [Omnibus::Config]
61
+ #
62
+ # @deprecated Just refer to {Omnibus::Config} directly.
63
+ def self.config
64
+ Config
65
+ end
66
+
67
+ # Load in an Omnibus configuration file. Values will be merged with
68
+ # and override the defaults defined in {Omnibus::Config}.
69
+ #
70
+ # @param file [String] path to a configuration file to load
71
+ #
72
+ # @return [void]
73
+ def self.load_configuration(file=nil)
74
+ if file
75
+ Config.from_file(file)
76
+ end
77
+ end
78
+
79
+ # Processes the configuration to construct the dependency tree of
80
+ # projects and software.
81
+ #
82
+ # @return [void]
83
+ def self.process_configuration
84
+ Config.validate
85
+ process_dsl_files
86
+ generate_extra_rake_tasks
87
+ end
88
+
89
+ # All {Omnibus::Project} instances that have been created.
90
+ #
91
+ # @return [Array<Omnibus::Project>]
92
+ def self.projects
93
+ @projects ||= []
94
+ end
95
+
96
+ # Names of all the {Omnibus::Project} instances that have been created.
97
+ #
98
+ # @return [Array<String>]
99
+ def self.project_names
100
+ projects.map{|p| p.name}
101
+ end
102
+
103
+ # Load the {Omnibus::Project} instance with the given name.
104
+ #
105
+ # @param name [String]
106
+ # @return {Omnibus::Project}
107
+ def self.project(name)
108
+ projects.find{ |p| p.name == name}
109
+ end
110
+
111
+ # The absolute path to the Omnibus project/repository directory.
112
+ #
113
+ # @return [String]
114
+ #
115
+ # @deprecated Call {Omnibus::Config.project_root} instead. We need
116
+ # to be able to easily tweak this at runtime via the CLI tool.
117
+ def self.project_root
118
+ Config.project_root
119
+ end
120
+
121
+ # The source root is the path to the root directory of the `omnibus` gem.
122
+ #
123
+ # @return [Pathname]
124
+ def self.source_root
125
+ @source_root ||= Pathname.new(File.expand_path("../..", __FILE__))
126
+ end
127
+
128
+ # The source root is the path to the root directory of the `omnibus-software`
129
+ # gem.
130
+ #
131
+ # @return [Pathname]
132
+ def self.omnibus_software_root
133
+ @omnibus_software_root ||= begin
134
+ if spec = Gem::Specification.find_all_by_name('omnibus-software').first
135
+ Pathname.new(spec.gem_dir)
136
+ else
137
+ nil
138
+ end
139
+ end
140
+ end
141
+
142
+ # Return paths to all configured {Omnibus::Project} DSL files.
143
+ #
144
+ # @return [Array<String>]
145
+ def self.project_files
146
+ ruby_files(File.join(project_root, Config.project_dir))
147
+ end
148
+
149
+ # Return paths to all configured {Omnibus::Software} DSL files.
150
+ #
151
+ # @return [Array<String>]
152
+ def self.software_files
153
+ ruby_files(File.join(project_root, Config.software_dir))
154
+ end
155
+
156
+ # Backward compat alias
157
+ #
158
+ # @todo print a deprecation message
159
+ class << self
160
+ alias :root :project_root
161
+ end
162
+
163
+ private
164
+
165
+ # Generates {Omnibus::Project}s for each project DSL file in
166
+ # `project_specs`. All projects are then accessible at
167
+ # {Omnibus#projects}
168
+ #
169
+ # @return [void]
170
+ #
171
+ # @see Omnibus::Project
172
+ def self.expand_projects
173
+ project_files.each do |spec|
174
+ Omnibus.projects << Omnibus::Project.load(spec)
175
+ end
176
+ end
177
+
178
+ # Generate {Omnibus::Software} objects for all software DSL files in
179
+ # `software_specs`.
180
+ #
181
+ # @param overrides [Hash] a hash of version override information.
182
+ # @param software_files [Array<String>]
183
+ # @return [void]
184
+ #
185
+ # @see Omnibus::Overrides#overrides
186
+ def self.expand_software(overrides, software_files)
187
+ unless overrides.is_a? Hash
188
+ raise ArgumentError, "Overrides argument must be a hash! You passed #{overrides.inspect}."
189
+ end
190
+
191
+ # TODO: Why are we doing a full Cartesian product of (projects x
192
+ # software) without regard for the actual dependencies of the
193
+ # projects?
194
+ software_files.each do |f|
195
+ Omnibus.projects.each do |p|
196
+ s = Omnibus::Software.load(f, p, overrides)
197
+ Omnibus.component_added(s) if p.dependency?(s)
198
+ end
199
+ end
200
+ end
201
+
202
+ # Processes all configured {Omnibus::Project} and
203
+ # {Omnibus::Software} DSL files.
204
+ #
205
+ # @return [void]
206
+ def self.process_dsl_files
207
+ # Do projects first
208
+ expand_projects
209
+
210
+ # Then do software
211
+ final_software_files = prefer_local_software(omnibus_software_files,
212
+ software_files)
213
+
214
+ overrides = Config.override_file ? Omnibus::Overrides.overrides : {}
215
+
216
+ expand_software(overrides, final_software_files)
217
+ end
218
+
219
+ # Creates some additional Rake tasks beyond those generated in the
220
+ # process of reading in the DSL files.
221
+ #
222
+ # @return [void]
223
+ #
224
+ # @todo Not so sure I like how this is being done, but at least it
225
+ # isolates the Rake stuff.
226
+ def self.generate_extra_rake_tasks
227
+ require 'omnibus/clean_tasks'
228
+ end
229
+
230
+ # Return a list of all the Ruby files (i.e., those with an "rb"
231
+ # extension) in the given directory
232
+ #
233
+ # @param dir [String]
234
+ # @return [Array<String>]
235
+ def self.ruby_files(dir)
236
+ Dir.glob("#{dir}/*.rb")
237
+ end
238
+
239
+ # Retrieve the fully-qualified paths to every software definition
240
+ # file bundled in the {https://github.com/opscode/omnibus-software omnibus-software} gem.
241
+ #
242
+ # @return [Array<String>] the list of paths. Will be empty if the
243
+ # `omnibus-software` gem is not in the gem path.
244
+ def self.omnibus_software_files
245
+ if omnibus_software_root
246
+ Dir.glob(File.join(omnibus_software_root, 'config', 'software', '*.rb'))
247
+ else
248
+ []
249
+ end
250
+ end
251
+
252
+ # Given a list of software definitions from `omnibus-software` itself, and a
253
+ # list of software files local to the current project, create a
254
+ # single list of software definitions. If the software was defined
255
+ # in both sets, the locally-defined one ends up in the final list.
256
+ #
257
+ # The base name of the software file determines what software it
258
+ # defines.
259
+ #
260
+ # @param omnibus_files [Array<String>]
261
+ # @param local_files [Array<String>]
262
+ # @return [Array<String>]
263
+ def self.prefer_local_software(omnibus_files, local_files)
264
+ base = software_map(omnibus_files)
265
+ local = software_map(local_files)
266
+ base.merge(local).values
267
+ end
268
+
269
+ # Given a list of file paths, create a map of the basename (without
270
+ # extension) to the complete path.
271
+ #
272
+ # @param files [Array<String>]
273
+ # @return [Hash<String, String>]
274
+ def self.software_map(files)
275
+ files.each_with_object({}) do |file, collection|
276
+ software_name = File.basename(file, ".*")
277
+ collection[software_name] = file
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,281 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'time'
19
+ require 'omnibus/util'
20
+
21
+ module Omnibus
22
+
23
+ # Provides methods for generating Omnibus project build version
24
+ # strings automatically from Git repository information.
25
+ #
26
+ # @see Omnibus::Project#build_version
27
+ #
28
+ # @note Requires a Git repository
29
+ # @todo Add class method shortcuts for semver and git_describe
30
+ # versions e.g., Omnibus::BuildVersion.semver.
31
+ # @todo Rename this class to reflect its absolute dependence on running in a
32
+ # Git repository.
33
+ class BuildVersion
34
+ include Omnibus::Util
35
+
36
+ # Formatting string for the timestamp component of our SemVer build specifier.
37
+ #
38
+ # @see Omnibus::BuildVersion#semver
39
+ # @see Time#strftime
40
+ TIMESTAMP_FORMAT = "%Y%m%d%H%M%S"
41
+
42
+ # @deprecated Use {#semver} or {#git_describe} instead
43
+ def self.full
44
+ puts "#{self.name}.full is deprecated. Use #{self.name}.new.semver or #{self.name}.new.git_describe."
45
+ Omnibus::BuildVersion.new.git_describe
46
+ end
47
+
48
+ # @todo Remove this... it does nothing
49
+ def initialize
50
+ end
51
+
52
+ # @!group Version Generator Methods
53
+
54
+ # Generate a {http://semver.org/ SemVer 2.0.0-rc.1 compliant}
55
+ # version string for an Omnibus project.
56
+ #
57
+ # This relies on the Omnibus project being a Git repository, as
58
+ # well as having tags named according to SemVer conventions
59
+ # (specifically, the `MAJOR.MINOR.PATCH-PRERELEASE` aspects)
60
+ #
61
+ # The specific format of the version string is:
62
+ #
63
+ # MAJOR.MINOR.PATCH-PRERELEASE+TIMESTAMP.git.COMMITS_SINCE.GIT_SHA
64
+ #
65
+ # By default, a timestamp is incorporated into the build component
66
+ # of version string (see
67
+ # {Omnibus::BuildVersion::TIMESTAMP_FORMAT}). This can be
68
+ # disabled by setting the environment variable
69
+ # `OMNIBUS_APPEND_TIMESTAMP` to a "falsey" value (e.g. "false",
70
+ # "f", "no", "n", "0")
71
+ #
72
+ # @example 11.0.0-alpha.1+20121218164140.git.207.694b062
73
+ # @return [String]
74
+ # @see #git_describe
75
+ # @todo Issue a warning or throw an exception if the tags of the
76
+ # repository are not themselves SemVer-compliant?
77
+ # @todo Consider making the {#build_start_time} method public, as
78
+ # its function influences how build timestamps are generated,
79
+ # and can be influenced by users.
80
+ def semver
81
+ build_tag = version_tag
82
+
83
+ # PRERELEASE VERSION
84
+ if prerelease_version?
85
+ # ensure all dashes are dots per precedence rules (#12) in Semver
86
+ # 2.0.0-rc.1
87
+ prerelease = prerelease_tag.gsub("-", ".")
88
+ build_tag << "-" << prerelease
89
+ end
90
+
91
+ # BUILD VERSION
92
+ # Follows SemVer conventions and the build version begins with a '+'.
93
+ build_version_items = []
94
+
95
+ # By default we will append a timestamp to every build. This behavior can
96
+ # be overriden by setting the OMNIBUS_APPEND_TIMESTAMP environment
97
+ # variable to a 'falsey' value (ie false, f, no, n or 0).
98
+ #
99
+ # format: YYYYMMDDHHMMSS example: 20130131123345
100
+ build_version_items << build_start_time.strftime(TIMESTAMP_FORMAT) if append_timestamp?
101
+
102
+ # We'll append the git describe information unless we are sitting right
103
+ # on an annotated tag.
104
+ #
105
+ # format: git.COMMITS_SINCE_TAG.GIT_SHA example: git.207.694b062
106
+ unless commits_since_tag == 0
107
+ build_version_items << ["git", commits_since_tag, git_sha_tag].join(".")
108
+ end
109
+
110
+ unless build_version_items.empty?
111
+ build_tag << "+" << build_version_items.join(".")
112
+ end
113
+
114
+ build_tag
115
+ end
116
+
117
+ # Generates a version string by running
118
+ # {https://www.kernel.org/pub/software/scm/git/docs/git-describe.html
119
+ # git describe} in the root of the Omnibus project.
120
+ #
121
+ # Produces a version string of the format
122
+ #
123
+ # MOST_RECENT_TAG-COMMITS_SINCE-gGIT_SHA
124
+ #
125
+ # @example
126
+ # 11.0.0-alpha.1-207-g694b062
127
+ # @return [String]
128
+ def git_describe
129
+ @git_describe ||= begin
130
+ git_cmd = "git describe"
131
+ cmd = shellout(git_cmd,
132
+ :live_stream => nil,
133
+ :cwd => Omnibus.project_root)
134
+ if cmd.exitstatus == 0
135
+ cmd.stdout.chomp
136
+ else
137
+ msg = "Could not extract version information from `git describe`. "
138
+ msg << "Setting version to 0.0.0"
139
+ puts msg
140
+ "0.0.0"
141
+ end
142
+ end
143
+ end
144
+
145
+ # @!endgroup
146
+
147
+ # Note: The remaining methods could just as well be private
148
+
149
+ # Return a `MAJOR.MINOR.PATCH` version string, as extracted from
150
+ # {#git_describe}.
151
+ #
152
+ # Here are some illustrative examples:
153
+ #
154
+ # 1.2.7-208-ge908a52 -> 1.2.7
155
+ # 11.0.0-alpha-59-gf55b180 -> 11.0.0
156
+ # 11.0.0-alpha2 -> 11.0.0
157
+ # 10.16.2.rc.1 -> 10.16.2
158
+ #
159
+ # @return [String]
160
+ def version_tag
161
+ version_composition.join(".")
162
+ end
163
+
164
+ # Return a prerelease tag string (if it exists), as extracted from {#git_describe}.
165
+ #
166
+ # Here are some illustrative examples:
167
+ #
168
+ # 1.2.7-208-ge908a52 -> nil
169
+ # 11.0.0-alpha-59-gf55b180 -> alpha
170
+ # 11.0.0-alpha2 -> alpha2
171
+ # 10.16.2.rc.1 -> rc.1
172
+ #
173
+ # @return [String] if a pre-release tag was found
174
+ # @return [nil] if no pre-release tag was found
175
+ def prerelease_tag
176
+ prerelease_regex = if commits_since_tag > 0
177
+ /^\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)-\d+-g[0-9a-f]+$/
178
+ else
179
+ /^\d+\.\d+\.\d+(?:-|\.)([0-9A-Za-z.-]+)$/
180
+ end
181
+ match = prerelease_regex.match(git_describe)
182
+ match ? match[1] : nil
183
+ end
184
+
185
+ # Extracts the 7-character truncated Git SHA1 from the output of {#git_describe}.
186
+ #
187
+ # Here are some illustrative examples:
188
+ #
189
+ # 1.2.7-208-ge908a52 -> e908a52
190
+ # 11.0.0-alpha-59-gf55b180 -> f55b180
191
+ # 11.0.0-alpha2 -> nil
192
+ # 10.16.2.rc.1 -> nil
193
+ #
194
+ # @return [String] the truncated SHA1
195
+ # @return [nil] if no SHA1 is present in the output of #{git_describe}
196
+ def git_sha_tag
197
+ sha_regexp = /g([0-9a-f]+)$/
198
+ match = sha_regexp.match(git_describe)
199
+ match ? match[1] : nil
200
+ end
201
+
202
+ # Extracts the number of commits since the most recent Git tag, as
203
+ # determined by {#git_describe}.
204
+ #
205
+ # Here are some illustrative examples:
206
+ #
207
+ # 1.2.7-208-ge908a52 -> 208
208
+ # 11.0.0-alpha-59-gf55b180 -> 59
209
+ # 11.0.0-alpha2 -> 0
210
+ # 10.16.2.rc.1 -> 0
211
+ #
212
+ # @return [Fixnum]
213
+ def commits_since_tag
214
+ commits_regexp = /^.*-(\d+)\-g[0-9a-f]+$/
215
+ match = commits_regexp.match(git_describe)
216
+ match ? match[1].to_i : 0
217
+ end
218
+
219
+ # @todo This method is never called in Omnibus. Is this even used
220
+ # (e.g., in the DSL files)?
221
+ def development_version?
222
+ patch = version_composition.last
223
+ patch.to_i.odd?
224
+ end
225
+
226
+ # Indicates whether the version represents a pre-release or not, as
227
+ # signalled by the presence of a pre-release tag in the version
228
+ # string.
229
+ #
230
+ # @return [Boolean]
231
+ # @see #prerelease_tag
232
+ def prerelease_version?
233
+ !!(prerelease_tag)
234
+ end
235
+
236
+ private
237
+
238
+ # We'll attempt to retrive the timestamp from the Jenkin's set BUILD_ID
239
+ # environment variable. This will ensure platform specfic packages for the
240
+ # same build will share the same timestamp.
241
+ def build_start_time
242
+ @build_start_time ||= begin
243
+ if !ENV['BUILD_ID'].nil?
244
+ begin
245
+ Time.strptime(ENV['BUILD_ID'], "%Y-%m-%d_%H-%M-%S")
246
+ rescue ArgumentError
247
+ error_message = "BUILD_ID environment variable "
248
+ error_message << "should be in YYYY-MM-DD_hh-mm-ss "
249
+ error_message << "format."
250
+ raise ArgumentError, error_message
251
+ end
252
+ else
253
+ Time.now.utc
254
+ end
255
+ end
256
+ end
257
+
258
+ # Pulls out the major, minor, and patch components from the output
259
+ # of {#git_describe}.
260
+ #
261
+ # Relies on the most recent Git tag being SemVer compliant (i.e.,
262
+ # starting with a `MAJOR.MINOR.PATCH` string)
263
+ #
264
+ # @return [Array<(String, String, String)>]
265
+ #
266
+ # @todo Compute this once and store the result in an instance variable
267
+ def version_composition
268
+ version_regexp = /^(\d+)\.(\d+)\.(\d+)/
269
+ version_regexp.match(git_describe)[1..3]
270
+ end
271
+
272
+
273
+ def append_timestamp?
274
+ append_timestamp = true
275
+ if ENV['OMNIBUS_APPEND_TIMESTAMP'] && (ENV['OMNIBUS_APPEND_TIMESTAMP'] =~ (/(false|f|no|n|0)$/i))
276
+ append_timestamp = false
277
+ end
278
+ append_timestamp
279
+ end
280
+ end
281
+ end