omnibus 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +9 -0
- data/LICENSE +201 -0
- data/NOTICE +9 -0
- data/README.md +186 -0
- data/Rakefile +7 -0
- data/bin/makeself-header.sh +401 -0
- data/bin/makeself.sh +407 -0
- data/bin/omnibus +11 -0
- data/lib/omnibus.rb +280 -0
- data/lib/omnibus/build_version.rb +281 -0
- data/lib/omnibus/builder.rb +323 -0
- data/lib/omnibus/clean_tasks.rb +30 -0
- data/lib/omnibus/cli.rb +35 -0
- data/lib/omnibus/cli/application.rb +136 -0
- data/lib/omnibus/cli/base.rb +112 -0
- data/lib/omnibus/cli/build.rb +66 -0
- data/lib/omnibus/cli/cache.rb +60 -0
- data/lib/omnibus/config.rb +186 -0
- data/lib/omnibus/exceptions.rb +54 -0
- data/lib/omnibus/fetcher.rb +184 -0
- data/lib/omnibus/fetchers.rb +22 -0
- data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
- data/lib/omnibus/fetchers/net_fetcher.rb +191 -0
- data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
- data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
- data/lib/omnibus/health_check.rb +260 -0
- data/lib/omnibus/library.rb +70 -0
- data/lib/omnibus/overrides.rb +69 -0
- data/lib/omnibus/project.rb +566 -0
- data/lib/omnibus/reports.rb +99 -0
- data/lib/omnibus/s3_cacher.rb +136 -0
- data/lib/omnibus/software.rb +430 -0
- data/lib/omnibus/templates/Berksfile.erb +3 -0
- data/lib/omnibus/templates/Gemfile.erb +4 -0
- data/lib/omnibus/templates/README.md.erb +102 -0
- data/lib/omnibus/templates/Vagrantfile.erb +95 -0
- data/lib/omnibus/templates/gitignore.erb +8 -0
- data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
- data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
- data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
- data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
- data/lib/omnibus/templates/project.rb.erb +21 -0
- data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
- data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
- data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
- data/lib/omnibus/util.rb +61 -0
- data/lib/omnibus/version.rb +20 -0
- data/omnibus.gemspec +34 -0
- data/spec/build_version_spec.rb +228 -0
- data/spec/data/overrides/bad_line.overrides +3 -0
- data/spec/data/overrides/good.overrides +5 -0
- data/spec/data/overrides/with_dupes.overrides +4 -0
- data/spec/data/software/erchef.rb +40 -0
- data/spec/overrides_spec.rb +114 -0
- data/spec/software_spec.rb +71 -0
- data/spec/spec_helper.rb +28 -0
- metadata +239 -0
@@ -0,0 +1,566 @@
|
|
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
|
+
require 'omnibus/exceptions'
|
18
|
+
|
19
|
+
module Omnibus
|
20
|
+
|
21
|
+
# Omnibus project DSL reader
|
22
|
+
#
|
23
|
+
# @todo It seems like there's a bit of a conflation between a
|
24
|
+
# "project" and a "package" in this class... perhaps the
|
25
|
+
# package-building portions should be extracted to a separate
|
26
|
+
# class.
|
27
|
+
# @todo: Reorder DSL methods to fit in the same YARD group
|
28
|
+
# @todo: Generate the DSL methods via metaprogramming... they're all so similar
|
29
|
+
class Project
|
30
|
+
include Rake::DSL
|
31
|
+
|
32
|
+
# @todo Why not just use `nil`?
|
33
|
+
NULL_ARG = Object.new
|
34
|
+
|
35
|
+
# Convenience method to initialize a Project from a DSL file.
|
36
|
+
#
|
37
|
+
# @param filename [String] the filename of the Project DSL file to load.
|
38
|
+
def self.load(filename)
|
39
|
+
new(IO.read(filename), filename)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# Create a new Project from the contents of a DSL file. Prefer
|
44
|
+
# calling {Omnibus::Project#load} instead of using this method
|
45
|
+
# directly.
|
46
|
+
#
|
47
|
+
# @param io [String] the contents of a Project DSL (_not_ the filename!)
|
48
|
+
# @param filename [String] unused!
|
49
|
+
#
|
50
|
+
# @see Omnibus::Project#load
|
51
|
+
#
|
52
|
+
# @todo Remove filename parameter, as it is unused.
|
53
|
+
def initialize(io, filename)
|
54
|
+
@exclusions = Array.new
|
55
|
+
@conflicts = Array.new
|
56
|
+
@dependencies = Array.new
|
57
|
+
@runtime_dependencies = Array.new
|
58
|
+
instance_eval(io)
|
59
|
+
validate
|
60
|
+
render_tasks
|
61
|
+
end
|
62
|
+
|
63
|
+
# Ensures that certain project information has been set
|
64
|
+
#
|
65
|
+
# @raise [MissingProjectConfiguration] if a required parameter has
|
66
|
+
# not been set
|
67
|
+
# @return [void]
|
68
|
+
def validate
|
69
|
+
name && install_path && maintainer && homepage
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!group DSL methods
|
73
|
+
# Here is some broad documentation for the DSL methods as a whole.
|
74
|
+
|
75
|
+
# Set or retrieve the name of the project
|
76
|
+
#
|
77
|
+
# @param val [String] the name to set
|
78
|
+
# @return [String]
|
79
|
+
#
|
80
|
+
# @raise [MissingProjectConfiguration] if a value was not set
|
81
|
+
# before being subsequently retrieved (i.e., a name
|
82
|
+
# must be set in order to build a project)
|
83
|
+
def name(val=NULL_ARG)
|
84
|
+
@name = val unless val.equal?(NULL_ARG)
|
85
|
+
@name || raise(MissingProjectConfiguration.new("name", "my_project"))
|
86
|
+
end
|
87
|
+
|
88
|
+
# Set or retrieve the package name of the project. Unless
|
89
|
+
# explicitly set, the package name defaults to the project name
|
90
|
+
#
|
91
|
+
# @param val [String] the package name to set
|
92
|
+
# @return [String]
|
93
|
+
def package_name(val=NULL_ARG)
|
94
|
+
@package_name = val unless val.equal?(NULL_ARG)
|
95
|
+
@package_name.nil? ? @name : @package_name
|
96
|
+
end
|
97
|
+
|
98
|
+
# Set or retrieve the path at which the project should be
|
99
|
+
# installed by the generated package.
|
100
|
+
#
|
101
|
+
# @param val [String]
|
102
|
+
# @return [String]
|
103
|
+
#
|
104
|
+
# @raise [MissingProjectConfiguration] if a value was not set
|
105
|
+
# before being subsequently retrieved (i.e., an install_path
|
106
|
+
# must be set in order to build a project)
|
107
|
+
def install_path(val=NULL_ARG)
|
108
|
+
@install_path = val unless val.equal?(NULL_ARG)
|
109
|
+
@install_path || raise(MissingProjectConfiguration.new("install_path", "/opt/opscode"))
|
110
|
+
end
|
111
|
+
|
112
|
+
# Set or retrieve the the package maintainer.
|
113
|
+
#
|
114
|
+
# @param val [String]
|
115
|
+
# @return [String]
|
116
|
+
#
|
117
|
+
# @raise [MissingProjectConfiguration] if a value was not set
|
118
|
+
# before being subsequently retrieved (i.e., a maintainer must
|
119
|
+
# be set in order to build a project)
|
120
|
+
def maintainer(val=NULL_ARG)
|
121
|
+
@maintainer = val unless val.equal?(NULL_ARG)
|
122
|
+
@maintainer || raise(MissingProjectConfiguration.new("maintainer", "Opscode, Inc."))
|
123
|
+
end
|
124
|
+
|
125
|
+
# Set or retrive the package homepage.
|
126
|
+
#
|
127
|
+
# @param val [String]
|
128
|
+
# @return [String]
|
129
|
+
#
|
130
|
+
# @raise [MissingProjectConfiguration] if a value was not set
|
131
|
+
# before being subsequently retrieved (i.e., a homepage must be
|
132
|
+
# set in order to build a project)
|
133
|
+
def homepage(val=NULL_ARG)
|
134
|
+
@homepage = val unless val.equal?(NULL_ARG)
|
135
|
+
@homepage || raise(MissingProjectConfiguration.new("homepage", "http://www.opscode.com"))
|
136
|
+
end
|
137
|
+
|
138
|
+
# Defines the iteration for the package to be generated. Adheres
|
139
|
+
# to the conventions of the platform for which the package is
|
140
|
+
# being built.
|
141
|
+
#
|
142
|
+
# All iteration strings begin with the value set in {#build_iteration}
|
143
|
+
#
|
144
|
+
# @return [String]
|
145
|
+
def iteration
|
146
|
+
case platform_family
|
147
|
+
when 'rhel'
|
148
|
+
platform_version =~ /^(\d+)/
|
149
|
+
maj = $1
|
150
|
+
"#{build_iteration}.el#{maj}"
|
151
|
+
when 'windows'
|
152
|
+
"#{build_iteration}.windows"
|
153
|
+
else
|
154
|
+
"#{build_iteration}.#{platform}.#{platform_version}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Set or retrieve the project description. Defaults to `"The full
|
159
|
+
# stack of #{name}"`
|
160
|
+
#
|
161
|
+
# Corresponds to the `--description` flag of
|
162
|
+
# {https://github.com/jordansissel/fpm fpm}.
|
163
|
+
#
|
164
|
+
# @param val [String] the project description
|
165
|
+
# @return [String]
|
166
|
+
#
|
167
|
+
# @see #name
|
168
|
+
def description(val=NULL_ARG)
|
169
|
+
@description = val unless val.equal?(NULL_ARG)
|
170
|
+
@description || "The full stack of #{name}"
|
171
|
+
end
|
172
|
+
|
173
|
+
# Set or retrieve the name of the package this package will replace.
|
174
|
+
#
|
175
|
+
# Ultimately used as the value for the `--replaces` flag in
|
176
|
+
# {https://github.com/jordansissel/fpm fpm}.
|
177
|
+
#
|
178
|
+
# @param val [String] the name of the package to replace
|
179
|
+
# @return [String]
|
180
|
+
#
|
181
|
+
# @todo Consider having this default to {#package_name}; many uses of this
|
182
|
+
# method effectively do this already.
|
183
|
+
def replaces(val=NULL_ARG)
|
184
|
+
@replaces = val unless val.equal?(NULL_ARG)
|
185
|
+
@replaces
|
186
|
+
end
|
187
|
+
|
188
|
+
# Add to the list of packages this one conflicts with.
|
189
|
+
#
|
190
|
+
# Specifying conflicts is optional. See the `--conflicts` flag in
|
191
|
+
# {https://github.com/jordansissel/fpm fpm}.
|
192
|
+
#
|
193
|
+
# @param val [String]
|
194
|
+
# @return [void]
|
195
|
+
def conflict(val)
|
196
|
+
@conflicts << val
|
197
|
+
end
|
198
|
+
|
199
|
+
# Set or retrieve the version of the project.
|
200
|
+
#
|
201
|
+
# @param val [String] the version to set
|
202
|
+
# @return [String]
|
203
|
+
#
|
204
|
+
# @see Omnibus::BuildVersion
|
205
|
+
def build_version(val=NULL_ARG)
|
206
|
+
@build_version = val unless val.equal?(NULL_ARG)
|
207
|
+
@build_version
|
208
|
+
end
|
209
|
+
|
210
|
+
# Set or retrieve the build iteration of the project. Defaults to
|
211
|
+
# `1` if not otherwise set.
|
212
|
+
#
|
213
|
+
# @param val [Fixnum]
|
214
|
+
# @return [Fixnum]
|
215
|
+
#
|
216
|
+
# @todo Is there a better name for this than "build_iteration"?
|
217
|
+
# Would be nice to cut down confusiton with {#iteration}.
|
218
|
+
def build_iteration(val=NULL_ARG)
|
219
|
+
@build_iteration = val unless val.equal?(NULL_ARG)
|
220
|
+
@build_iteration || 1
|
221
|
+
end
|
222
|
+
|
223
|
+
# Add an Omnibus software dependency.
|
224
|
+
#
|
225
|
+
# Note that this is a *build time* dependency. If you need to
|
226
|
+
# specify an external dependency that is required at runtime, see
|
227
|
+
# {#runtime_dependency} instead.
|
228
|
+
#
|
229
|
+
# @param val [String] the name of a Software dependency
|
230
|
+
# @return [void]
|
231
|
+
def dependency(val)
|
232
|
+
@dependencies << val
|
233
|
+
end
|
234
|
+
|
235
|
+
# Add a package that is a runtime dependency of this
|
236
|
+
# project.
|
237
|
+
#
|
238
|
+
# This is distinct from a build-time dependency, which should
|
239
|
+
# correspond to an Omnibus software definition.
|
240
|
+
#
|
241
|
+
# Corresponds to the `--depends` flag of
|
242
|
+
# {https://github.com/jordansissel/fpm fpm}.
|
243
|
+
#
|
244
|
+
# @param val [String] the name of the runtime dependency
|
245
|
+
# @return [void]
|
246
|
+
def runtime_dependency(val)
|
247
|
+
@runtime_dependencies << val
|
248
|
+
end
|
249
|
+
|
250
|
+
# Set or retrieve the list of software dependencies for this
|
251
|
+
# project. As this is a DSL method, only pass the names of
|
252
|
+
# software components, not {Omnibus::Software} objects.
|
253
|
+
#
|
254
|
+
# These is the software that comprises your project, and is
|
255
|
+
# distinct from runtime dependencies.
|
256
|
+
#
|
257
|
+
# @note This will reinitialize the internal depdencies Array
|
258
|
+
# and overwrite any dependencies that may have been set using
|
259
|
+
# {#dependency}.
|
260
|
+
#
|
261
|
+
# @param val [Array<String>] a list of names of Software components
|
262
|
+
# @return [Array<String>]
|
263
|
+
def dependencies(val=NULL_ARG)
|
264
|
+
@dependencies = val unless val.equal?(NULL_ARG)
|
265
|
+
@dependencies
|
266
|
+
end
|
267
|
+
|
268
|
+
# Add a new exclusion pattern.
|
269
|
+
#
|
270
|
+
# Corresponds to the `--exclude` flag of {https://github.com/jordansissel/fpm fpm}.
|
271
|
+
#
|
272
|
+
# @param pattern [String]
|
273
|
+
# @return void
|
274
|
+
def exclude(pattern)
|
275
|
+
@exclusions << pattern
|
276
|
+
end
|
277
|
+
|
278
|
+
# Returns the platform version of the machine on which Omnibus is
|
279
|
+
# running, as determined by Ohai.
|
280
|
+
#
|
281
|
+
# @return [String]
|
282
|
+
def platform_version
|
283
|
+
OHAI.platform_version
|
284
|
+
end
|
285
|
+
|
286
|
+
# Returns the platform of the machine on which Omnibus is running,
|
287
|
+
# as determined by Ohai.
|
288
|
+
#
|
289
|
+
# @return [String]
|
290
|
+
def platform
|
291
|
+
OHAI.platform
|
292
|
+
end
|
293
|
+
|
294
|
+
# Returns the platform family of the machine on which Omnibus is
|
295
|
+
# running, as determined by Ohai.
|
296
|
+
#
|
297
|
+
# @return [String]
|
298
|
+
def platform_family
|
299
|
+
OHAI.platform_family
|
300
|
+
end
|
301
|
+
|
302
|
+
# Convenience method for accessing the global Omnibus configuration object.
|
303
|
+
#
|
304
|
+
# @return Omnibus::Config
|
305
|
+
#
|
306
|
+
# @see Omnibus::Config
|
307
|
+
def config
|
308
|
+
Omnibus.config
|
309
|
+
end
|
310
|
+
|
311
|
+
# The path to the package scripts directory for this project.
|
312
|
+
# These are optional scripts that can be bundled into the
|
313
|
+
# resulting package for running at various points in the package
|
314
|
+
# management lifecycle.
|
315
|
+
#
|
316
|
+
# Currently supported scripts include:
|
317
|
+
#
|
318
|
+
# * postinst
|
319
|
+
#
|
320
|
+
# A post-install script
|
321
|
+
# * prerm
|
322
|
+
#
|
323
|
+
# A pre-uninstall script
|
324
|
+
# * postrm
|
325
|
+
#
|
326
|
+
# A post-uninstall script
|
327
|
+
#
|
328
|
+
# Any scripts with these names that are present in the package
|
329
|
+
# scripts directory will be incorporated into the package that is
|
330
|
+
# built. This only applies to fpm-built packages.
|
331
|
+
#
|
332
|
+
# Additionally, there may be a `makeselfinst` script.
|
333
|
+
#
|
334
|
+
# @return [String]
|
335
|
+
#
|
336
|
+
# @todo This documentation really should be up at a higher level,
|
337
|
+
# particularly since the user has no way to change the path.
|
338
|
+
def package_scripts_path
|
339
|
+
"#{Omnibus.project_root}/package-scripts/#{name}"
|
340
|
+
end
|
341
|
+
|
342
|
+
# Determine the package type(s) to be built, based on the platform
|
343
|
+
# family for which the package is being built.
|
344
|
+
#
|
345
|
+
# If specific types cannot be determined, default to `["makeself"]`.
|
346
|
+
#
|
347
|
+
# @return [Array<(String)>]
|
348
|
+
#
|
349
|
+
# @todo Why does this only ever return a single-element array,
|
350
|
+
# instead of just a string, or symbol?
|
351
|
+
def package_types
|
352
|
+
case platform_family
|
353
|
+
when 'debian'
|
354
|
+
[ "deb" ]
|
355
|
+
when 'fedora', 'rhel'
|
356
|
+
[ "rpm" ]
|
357
|
+
when 'solaris2'
|
358
|
+
[ "solaris" ]
|
359
|
+
when 'windows'
|
360
|
+
[ "msi" ]
|
361
|
+
else
|
362
|
+
[ "makeself" ]
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# Indicates whether `software` is defined as a software component
|
367
|
+
# of this project.
|
368
|
+
#
|
369
|
+
# @param software [String, Omnibus::Software, #name]
|
370
|
+
# @return [Boolean]
|
371
|
+
#
|
372
|
+
# @see #dependencies
|
373
|
+
def dependency?(software)
|
374
|
+
name = if software.respond_to?(:name)
|
375
|
+
software.send(:name)
|
376
|
+
elsif
|
377
|
+
software
|
378
|
+
end
|
379
|
+
@dependencies.include?(name)
|
380
|
+
end
|
381
|
+
|
382
|
+
# @!endgroup
|
383
|
+
|
384
|
+
private
|
385
|
+
|
386
|
+
# The command to generate an MSI package on Windows platforms.
|
387
|
+
#
|
388
|
+
# Does not execute the command, only assembles it.
|
389
|
+
#
|
390
|
+
# @return [Array<(String, Hash)>] The complete MSI command, plus a
|
391
|
+
# Hash of options to be passed on to Mixlib::ShellOut
|
392
|
+
#
|
393
|
+
# @see Mixlib::ShellOut
|
394
|
+
#
|
395
|
+
# @todo For this and all the *_command methods, just return a
|
396
|
+
# Mixlib::ShellOut object ready for execution. Using Arrays
|
397
|
+
# makes downstream processing needlessly complicated.
|
398
|
+
def msi_command
|
399
|
+
msi_command = ["light.exe",
|
400
|
+
"-nologo",
|
401
|
+
"-ext WixUIExtension",
|
402
|
+
"-cultures:en-us",
|
403
|
+
"-loc #{install_path}\\msi-tmp\\#{package_name}-en-us.wxl",
|
404
|
+
"#{install_path}\\msi-tmp\\#{package_name}-Files.wixobj",
|
405
|
+
"#{install_path}\\msi-tmp\\#{package_name}.wixobj",
|
406
|
+
"-out #{config.package_dir}\\#{package_name}-#{build_version}-#{iteration}.msi"]
|
407
|
+
|
408
|
+
# Don't care about the 204 return code from light.exe since it's
|
409
|
+
# about some expected warnings...
|
410
|
+
[msi_command.join(" "), {:returns => [0, 204]}]
|
411
|
+
end
|
412
|
+
|
413
|
+
# The {https://github.com/jordansissel/fpm fpm} command to
|
414
|
+
# generate a package for RedHat, Ubuntu, Solaris, etc. platforms.
|
415
|
+
#
|
416
|
+
# Does not execute the command, only assembles it.
|
417
|
+
#
|
418
|
+
# In contrast to {#msi_command}, command generated by
|
419
|
+
# {#fpm_command} does not require any Mixlib::Shellout options.
|
420
|
+
#
|
421
|
+
# @return [Array<String>] the components of the fpm command; need
|
422
|
+
# to be joined with " " first.
|
423
|
+
#
|
424
|
+
# @todo Just make this return a String instead of an Array
|
425
|
+
# @todo Use the long option names (i.e., the double-dash ones) in
|
426
|
+
# the fpm command for maximum clarity.
|
427
|
+
def fpm_command(pkg_type)
|
428
|
+
command_and_opts = ["fpm",
|
429
|
+
"-s dir",
|
430
|
+
"-t #{pkg_type}",
|
431
|
+
"-v #{build_version}",
|
432
|
+
"-n #{package_name}",
|
433
|
+
"--iteration #{iteration}",
|
434
|
+
install_path,
|
435
|
+
"-m '#{maintainer}'",
|
436
|
+
"--description '#{description}'",
|
437
|
+
"--url #{homepage}"]
|
438
|
+
if File.exist?("#{package_scripts_path}/postinst")
|
439
|
+
command_and_opts << "--post-install '#{package_scripts_path}/postinst'"
|
440
|
+
end
|
441
|
+
# solaris packages don't support --pre-uninstall
|
442
|
+
if File.exist?("#{package_scripts_path}/prerm") && pkg_type != "solaris"
|
443
|
+
command_and_opts << "--pre-uninstall '#{package_scripts_path}/prerm'"
|
444
|
+
end
|
445
|
+
# solaris packages don't support --post-uninstall
|
446
|
+
if File.exist?("#{package_scripts_path}/postrm") && pkg_type != "solaris"
|
447
|
+
command_and_opts << "--post-uninstall '#{package_scripts_path}/postrm'"
|
448
|
+
end
|
449
|
+
|
450
|
+
@exclusions.each do |pattern|
|
451
|
+
command_and_opts << "--exclude '#{pattern}'"
|
452
|
+
end
|
453
|
+
|
454
|
+
@runtime_dependencies.each do |runtime_dep|
|
455
|
+
command_and_opts << "--depends '#{runtime_dep}'"
|
456
|
+
end
|
457
|
+
|
458
|
+
@conflicts.each do |conflict|
|
459
|
+
command_and_opts << "--conflicts '#{conflict}'"
|
460
|
+
end
|
461
|
+
|
462
|
+
command_and_opts << " --replaces #{@replaces}" if @replaces
|
463
|
+
command_and_opts
|
464
|
+
end
|
465
|
+
|
466
|
+
# TODO: what's this do?
|
467
|
+
def makeself_command
|
468
|
+
command_and_opts = [ File.expand_path(File.join(Omnibus.source_root, "bin", "makeself.sh")),
|
469
|
+
"--gzip",
|
470
|
+
install_path,
|
471
|
+
"#{package_name}-#{build_version}_#{iteration}.sh",
|
472
|
+
"'The full stack of #{@name}'"
|
473
|
+
]
|
474
|
+
command_and_opts << "./makeselfinst" if File.exists?("#{package_scripts_path}/makeselfinst")
|
475
|
+
command_and_opts
|
476
|
+
end
|
477
|
+
|
478
|
+
# Dynamically generate Rake tasks to build projects and all the software they depend on.
|
479
|
+
#
|
480
|
+
# @note Much Rake magic ahead!
|
481
|
+
#
|
482
|
+
# @return void
|
483
|
+
def render_tasks
|
484
|
+
directory config.package_dir
|
485
|
+
directory "pkg"
|
486
|
+
|
487
|
+
namespace :projects do
|
488
|
+
|
489
|
+
package_types.each do |pkg_type|
|
490
|
+
namespace @name do
|
491
|
+
desc "package #{@name} into a #{pkg_type}"
|
492
|
+
task pkg_type => (@dependencies.map {|dep| "software:#{dep}"}) do
|
493
|
+
|
494
|
+
package_commands = []
|
495
|
+
if pkg_type == "makeself"
|
496
|
+
# copy the makeself installer into package
|
497
|
+
if File.exists?("#{package_scripts_path}/makeselfinst")
|
498
|
+
package_commands << "cp #{package_scripts_path}/makeselfinst #{install_path}/"
|
499
|
+
end
|
500
|
+
|
501
|
+
# run the makeself program
|
502
|
+
package_commands << makeself_command.join(" ")
|
503
|
+
|
504
|
+
# rm the makeself installer (for incremental builds)
|
505
|
+
package_commands << "rm -f #{install_path}/makeselfinst"
|
506
|
+
elsif pkg_type == "msi"
|
507
|
+
package_commands << msi_command
|
508
|
+
else # pkg_type == "fpm"
|
509
|
+
package_commands << fpm_command(pkg_type).join(" ")
|
510
|
+
end
|
511
|
+
|
512
|
+
# run the commands
|
513
|
+
package_commands.each do |cmd|
|
514
|
+
cmd_options = {
|
515
|
+
:live_stream => STDOUT,
|
516
|
+
:timeout => 3600,
|
517
|
+
:cwd => config.package_dir
|
518
|
+
}
|
519
|
+
|
520
|
+
if cmd.is_a?(Array)
|
521
|
+
command = cmd[0]
|
522
|
+
cmd_options.merge!(cmd[1])
|
523
|
+
else
|
524
|
+
command = cmd
|
525
|
+
end
|
526
|
+
|
527
|
+
shell = Mixlib::ShellOut.new(command, cmd_options)
|
528
|
+
shell.run_command
|
529
|
+
shell.error!
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
# TODO: why aren't these dependencies just added in at the
|
534
|
+
# initial creation of the 'pkg_type' task?
|
535
|
+
task pkg_type => config.package_dir
|
536
|
+
task pkg_type => "#{@name}:health_check"
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
task "#{@name}:copy" => (package_types.map {|pkg_type| "#{@name}:#{pkg_type}"}) do
|
541
|
+
if OHAI.platform == "windows"
|
542
|
+
cp_cmd = "xcopy #{config.package_dir}\\*.msi pkg\\ /Y"
|
543
|
+
else
|
544
|
+
cp_cmd = "cp #{config.package_dir}/* pkg/"
|
545
|
+
end
|
546
|
+
shell = Mixlib::ShellOut.new(cp_cmd)
|
547
|
+
shell.run_command
|
548
|
+
shell.error!
|
549
|
+
end
|
550
|
+
task "#{@name}:copy" => "pkg"
|
551
|
+
|
552
|
+
desc "package #{@name}"
|
553
|
+
task @name => "#{@name}:copy"
|
554
|
+
|
555
|
+
desc "run the health check on the #{@name} install path"
|
556
|
+
task "#{@name}:health_check" do
|
557
|
+
if OHAI.platform == "windows"
|
558
|
+
puts "Skipping health check on windows..."
|
559
|
+
else
|
560
|
+
Omnibus::HealthCheck.run(install_path)
|
561
|
+
end
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|