omnibus 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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