fpm-cookery 0.15.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +10 -0
- data/CHANGELOG.md +8 -0
- data/bin/fpm-cook +1 -1
- data/fpm-cookery.gemspec +2 -1
- data/lib/fpm/cookery/chain_packager.rb +58 -0
- data/lib/fpm/cookery/cli.rb +93 -104
- data/lib/fpm/cookery/config.rb +86 -0
- data/lib/fpm/cookery/dependency_inspector.rb +7 -3
- data/lib/fpm/cookery/exceptions.rb +11 -0
- data/lib/fpm/cookery/facts.rb +1 -0
- data/lib/fpm/cookery/log.rb +1 -1
- data/lib/fpm/cookery/package/dir.rb +11 -35
- data/lib/fpm/cookery/package/gem.rb +25 -0
- data/lib/fpm/cookery/package/maintainer.rb +39 -0
- data/lib/fpm/cookery/package/package.rb +100 -0
- data/lib/fpm/cookery/package/version.rb +48 -0
- data/lib/fpm/cookery/packager.rb +65 -97
- data/lib/fpm/cookery/path.rb +4 -0
- data/lib/fpm/cookery/recipe.rb +59 -19
- data/lib/fpm/cookery/shellout.rb +35 -0
- data/lib/fpm/cookery/source_handler/curl.rb +12 -2
- data/lib/fpm/cookery/version.rb +1 -1
- data/recipes/arr-pm/recipe.rb +4 -0
- data/recipes/backports/recipe.rb +4 -0
- data/recipes/cabin/recipe.rb +4 -0
- data/recipes/clamp/recipe.rb +4 -0
- data/recipes/facter/recipe.rb +4 -0
- data/recipes/fpm-cookery-gem/addressable.rb +4 -0
- data/recipes/fpm-cookery-gem/arr-pm.rb +4 -0
- data/recipes/fpm-cookery-gem/backports.rb +4 -0
- data/recipes/fpm-cookery-gem/cabin.rb +4 -0
- data/recipes/fpm-cookery-gem/childprocess.rb +7 -0
- data/recipes/fpm-cookery-gem/clamp.rb +4 -0
- data/recipes/fpm-cookery-gem/facter.rb +4 -0
- data/recipes/fpm-cookery-gem/ffi.rb +4 -0
- data/recipes/fpm-cookery-gem/fpm.rb +7 -0
- data/recipes/fpm-cookery-gem/ftw.rb +7 -0
- data/recipes/fpm-cookery-gem/hiera.rb +7 -0
- data/recipes/fpm-cookery-gem/http_parser.rb.rb +4 -0
- data/recipes/fpm-cookery-gem/json.rb +4 -0
- data/recipes/fpm-cookery-gem/json_pure.rb +4 -0
- data/recipes/fpm-cookery-gem/puppet.rb +7 -0
- data/recipes/fpm-cookery-gem/recipe.rb +7 -0
- data/recipes/fpm-cookery-gem/rgen.rb +4 -0
- data/recipes/fpm-cookery/recipe.rb +1 -1
- data/recipes/fpm-cookery/ruby.rb +20 -10
- data/recipes/fpm/recipe.rb +4 -0
- data/recipes/json/recipe.rb +4 -0
- data/recipes/open4/recipe.rb +4 -0
- data/spec/config_spec.rb +167 -0
- data/spec/facts_spec.rb +7 -0
- data/spec/fixtures/test-config-1.yml +2 -0
- data/spec/package_maintainer_spec.rb +79 -0
- data/spec/package_spec.rb +182 -0
- data/spec/package_version_spec.rb +119 -0
- data/spec/recipe_spec.rb +18 -0
- data/spec/spec_helper.rb +1 -0
- metadata +61 -6
data/lib/fpm/cookery/facts.rb
CHANGED
data/lib/fpm/cookery/log.rb
CHANGED
@@ -1,49 +1,25 @@
|
|
1
1
|
require 'fpm/package/dir'
|
2
|
-
require '
|
2
|
+
require 'fpm/cookery/package/package'
|
3
3
|
|
4
4
|
module FPM
|
5
5
|
module Cookery
|
6
6
|
module Package
|
7
|
-
class Dir <
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
self.name = recipe.name
|
12
|
-
self.url = recipe.homepage || recipe.source
|
13
|
-
self.category = recipe.section || 'optional'
|
14
|
-
self.description = recipe.description.strip if recipe.description
|
15
|
-
self.architecture = recipe.arch.to_s if recipe.arch
|
16
|
-
|
17
|
-
self.dependencies += recipe.depends
|
18
|
-
self.conflicts += recipe.conflicts
|
19
|
-
self.provides += recipe.provides
|
20
|
-
self.replaces += recipe.replaces
|
21
|
-
self.config_files += recipe.config_files
|
22
|
-
|
23
|
-
attributes[:prefix] = '/'
|
24
|
-
attributes[:chdir] = recipe.destdir.to_s
|
25
|
-
attributes[:deb_compression] = 'gzip'
|
26
|
-
attributes[:deb_user] = 'root'
|
27
|
-
attributes[:deb_group] = 'root'
|
28
|
-
attributes[:rpm_compression] = 'gzip'
|
29
|
-
attributes[:rpm_digest] = 'md5'
|
30
|
-
attributes[:rpm_user] = 'root'
|
31
|
-
attributes[:rpm_group] = 'root'
|
32
|
-
attributes[:rpm_defattrfile] = '-'
|
33
|
-
attributes[:rpm_defattrdir] = '-'
|
7
|
+
class Dir < FPM::Cookery::Package::Package
|
8
|
+
def fpm_object
|
9
|
+
FPM::Package::Dir.new
|
10
|
+
end
|
34
11
|
|
35
|
-
|
36
|
-
attributes[:
|
12
|
+
def package_setup
|
13
|
+
fpm.attributes[:prefix] = '/'
|
14
|
+
fpm.attributes[:chdir] = recipe.destdir.to_s
|
15
|
+
end
|
37
16
|
|
17
|
+
def package_input
|
38
18
|
inputs = config.fetch(:input, nil) || '.'
|
39
19
|
|
40
20
|
Array(inputs).each do |path|
|
41
|
-
input(path)
|
21
|
+
fpm.input(path)
|
42
22
|
end
|
43
|
-
|
44
|
-
# The call to input() overwrites the license and vendor attributes.
|
45
|
-
# XXX Needs to be fixed in fpm/package/dir.rb.
|
46
|
-
self.license = recipe.license if recipe.license
|
47
23
|
end
|
48
24
|
end
|
49
25
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'fpm/package/gem'
|
2
|
+
require 'fpm/cookery/package/package'
|
3
|
+
|
4
|
+
module FPM
|
5
|
+
module Cookery
|
6
|
+
module Package
|
7
|
+
class Gem < FPM::Cookery::Package::Package
|
8
|
+
def fpm_object
|
9
|
+
FPM::Package::Gem.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def package_setup
|
13
|
+
fpm.version = recipe.version
|
14
|
+
|
15
|
+
fpm.attributes[:gem_fix_name?] = true
|
16
|
+
fpm.attributes[:gem_fix_dependencies?] = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def package_input
|
20
|
+
fpm.input(recipe.name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'fpm/cookery/shellout'
|
2
|
+
|
3
|
+
module FPM
|
4
|
+
module Cookery
|
5
|
+
module Package
|
6
|
+
class Maintainer < Struct.new(:recipe, :config)
|
7
|
+
def maintainer
|
8
|
+
config_maintainer || recipe_maintainer || git_maintainer
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
maintainer
|
13
|
+
end
|
14
|
+
alias_method :to_str, :to_s
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def config_maintainer
|
19
|
+
config[:maintainer]
|
20
|
+
end
|
21
|
+
|
22
|
+
def recipe_maintainer
|
23
|
+
recipe.maintainer
|
24
|
+
end
|
25
|
+
|
26
|
+
def git_maintainer
|
27
|
+
username = git_config('user.name')
|
28
|
+
useremail = git_config('user.email')
|
29
|
+
|
30
|
+
username && useremail ? "#{username} <#{useremail}>" : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def git_config(key)
|
34
|
+
FPM::Cookery::Shellout.git_config_get(key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'fpm/cookery/exceptions'
|
2
|
+
|
3
|
+
module FPM
|
4
|
+
module Cookery
|
5
|
+
module Package
|
6
|
+
class Package
|
7
|
+
attr_reader :recipe, :config, :fpm
|
8
|
+
|
9
|
+
def initialize(recipe, config = {})
|
10
|
+
@recipe = recipe
|
11
|
+
@config = config
|
12
|
+
@fpm = fpm_object
|
13
|
+
|
14
|
+
@fpm.name = recipe.name
|
15
|
+
@fpm.url = recipe.homepage
|
16
|
+
@fpm.category = recipe.section || 'optional'
|
17
|
+
@fpm.description = recipe.description.strip if recipe.description
|
18
|
+
@fpm.architecture = recipe.arch.to_s if recipe.arch
|
19
|
+
|
20
|
+
@fpm.dependencies += recipe.depends
|
21
|
+
@fpm.conflicts += recipe.conflicts
|
22
|
+
@fpm.provides += recipe.provides
|
23
|
+
@fpm.replaces += recipe.replaces
|
24
|
+
@fpm.config_files += recipe.config_files
|
25
|
+
|
26
|
+
@fpm.attributes[:deb_compression] = 'gzip'
|
27
|
+
@fpm.attributes[:deb_user] = 'root'
|
28
|
+
@fpm.attributes[:deb_group] = 'root'
|
29
|
+
@fpm.attributes[:rpm_compression] = 'gzip'
|
30
|
+
@fpm.attributes[:rpm_digest] = 'md5'
|
31
|
+
@fpm.attributes[:rpm_user] = 'root'
|
32
|
+
@fpm.attributes[:rpm_group] = 'root'
|
33
|
+
@fpm.attributes[:rpm_defattrfile] = '-'
|
34
|
+
@fpm.attributes[:rpm_defattrdir] = '-'
|
35
|
+
|
36
|
+
# TODO replace remove_excluded_files() in packager with this.
|
37
|
+
@fpm.attributes[:excludes] = []
|
38
|
+
|
39
|
+
# Package type specific code should be called in package_setup.
|
40
|
+
package_setup
|
41
|
+
|
42
|
+
# The input for the FPM package will be set here.
|
43
|
+
package_input
|
44
|
+
|
45
|
+
# The call to input() overwrites the license and vendor attributes.
|
46
|
+
# XXX Needs to be fixed in fpm/package/dir.rb.
|
47
|
+
fpm.license = recipe.license if recipe.license
|
48
|
+
end
|
49
|
+
|
50
|
+
def fpm_object
|
51
|
+
# Has to be overwritten in a subclass.
|
52
|
+
raise Error::MethodNotImplemented, "The #fpm_object method has not been implemented in #{self.class}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def package_setup
|
56
|
+
# Can be overwritten in a subclass.
|
57
|
+
end
|
58
|
+
|
59
|
+
def package_input
|
60
|
+
# Has to be overwritten in a subclass.
|
61
|
+
raise Error::MethodNotImplemented, "The #package_input method has not been implemented in #{self.class}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def convert(output_class)
|
65
|
+
fpm.convert(output_class)
|
66
|
+
end
|
67
|
+
|
68
|
+
def cleanup
|
69
|
+
fpm.cleanup
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_script(type, content)
|
73
|
+
case type.to_sym
|
74
|
+
when :pre_install
|
75
|
+
fpm.scripts[:before_install] = content
|
76
|
+
when :post_install
|
77
|
+
fpm.scripts[:after_install] = content
|
78
|
+
when :pre_uninstall
|
79
|
+
fpm.scripts[:before_remove] = content
|
80
|
+
when :post_uninstall
|
81
|
+
fpm.scripts[:after_remove] = content
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# XXX should go away and set in initializer
|
86
|
+
def version=(value)
|
87
|
+
fpm.version = value
|
88
|
+
end
|
89
|
+
|
90
|
+
def maintainer=(value)
|
91
|
+
fpm.maintainer = value
|
92
|
+
end
|
93
|
+
|
94
|
+
def vendor=(value)
|
95
|
+
fpm.vendor = value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module FPM
|
2
|
+
module Cookery
|
3
|
+
module Package
|
4
|
+
class Version
|
5
|
+
VENDOR_DELIMITER = {
|
6
|
+
:deb => '+',
|
7
|
+
:rpm => '.',
|
8
|
+
:default => '-'
|
9
|
+
}
|
10
|
+
|
11
|
+
attr_reader :version, :epoch, :revision
|
12
|
+
|
13
|
+
def initialize(recipe, target, config)
|
14
|
+
@recipe = recipe
|
15
|
+
@target = target
|
16
|
+
@config = config
|
17
|
+
@revision = recipe.revision
|
18
|
+
@version, @epoch = split_version(@recipe.version)
|
19
|
+
end
|
20
|
+
|
21
|
+
def vendor
|
22
|
+
@config[:vendor] || @recipe.vendor
|
23
|
+
end
|
24
|
+
|
25
|
+
def vendor_delimiter
|
26
|
+
VENDOR_DELIMITER[@target.to_sym] || VENDOR_DELIMITER[:default]
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
if vendor
|
31
|
+
"#{version}#{vendor_delimiter}#{vendor}#{revision}"
|
32
|
+
else
|
33
|
+
"#{version}-#{revision}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias_method :to_str, :to_s
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def split_version(version)
|
41
|
+
epoch, version = version.split(':', 2)
|
42
|
+
|
43
|
+
version.nil? ? [epoch, nil] : [version, epoch]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/fpm/cookery/packager.rb
CHANGED
@@ -6,6 +6,8 @@ require 'fpm/cookery/source_integrity_check'
|
|
6
6
|
require 'fpm/cookery/path'
|
7
7
|
require 'fpm/cookery/log'
|
8
8
|
require 'fpm/cookery/package/dir'
|
9
|
+
require 'fpm/cookery/package/version'
|
10
|
+
require 'fpm/cookery/package/maintainer'
|
9
11
|
require 'fpm'
|
10
12
|
|
11
13
|
module FPM
|
@@ -62,66 +64,68 @@ module FPM
|
|
62
64
|
|
63
65
|
recipe.installing = false
|
64
66
|
|
65
|
-
|
67
|
+
if defined? recipe.source_handler()
|
68
|
+
source = recipe.source_handler
|
66
69
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
recipe.cachedir.mkdir
|
71
|
+
Dir.chdir(recipe.cachedir) do
|
72
|
+
Log.info "Fetching source: #{source.source_url}"
|
73
|
+
source.fetch
|
71
74
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
75
|
+
if source.checksum?
|
76
|
+
SourceIntegrityCheck.new(recipe).tap do |check|
|
77
|
+
if check.checksum_missing?
|
78
|
+
Log.warn 'Recipe does not provide a checksum. (sha256, sha1 or md5)'
|
79
|
+
Log.puts <<-__WARN
|
77
80
|
Digest: #{check.digest}
|
78
81
|
Checksum: #{check.checksum_actual}
|
79
82
|
Filename: #{check.filename}
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
__WARN
|
85
|
+
elsif check.error?
|
86
|
+
Log.error 'Integrity check failed!'
|
87
|
+
Log.puts <<-__ERROR
|
85
88
|
Digest: #{check.digest}
|
86
89
|
Checksum expected: #{check.checksum_expected}
|
87
90
|
Checksum actual: #{check.checksum_actual}
|
88
91
|
Filename: #{check.filename}
|
89
92
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
__ERROR
|
94
|
+
exit 1
|
95
|
+
end #end checksum missing
|
96
|
+
end #end check
|
97
|
+
end #end checksum
|
98
|
+
end #end chdir cachedir
|
96
99
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
recipe.builddir.mkdir
|
101
|
+
Dir.chdir(recipe.builddir) do
|
102
|
+
extracted_source = source.extract
|
100
103
|
|
101
|
-
|
102
|
-
|
104
|
+
Dir.chdir(extracted_source) do
|
105
|
+
#Source::Patches.new(recipe.patches).apply!
|
103
106
|
|
104
|
-
|
107
|
+
build_cookie = build_cookie_name(package_name)
|
105
108
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
if File.exists?(build_cookie)
|
110
|
+
Log.info 'Skipping build (`fpm-cook clean` to rebuild)'
|
111
|
+
else
|
112
|
+
Log.info "Building in #{File.expand_path(extracted_source, recipe.builddir)}"
|
113
|
+
recipe.build and FileUtils.touch(build_cookie)
|
114
|
+
end
|
112
115
|
|
113
|
-
|
114
|
-
|
116
|
+
FileUtils.rm_rf(recipe.destdir) unless keep_destdir?
|
117
|
+
recipe.destdir.mkdir unless File.exists?(recipe.destdir)
|
115
118
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
119
|
+
begin
|
120
|
+
recipe.installing = true
|
121
|
+
Log.info "Installing into #{recipe.destdir}"
|
122
|
+
recipe.install
|
123
|
+
ensure
|
124
|
+
recipe.installing = false
|
125
|
+
end
|
126
|
+
end #end chdir extracted_source
|
127
|
+
end #end chdir builddir
|
128
|
+
end #end defined source_handler
|
125
129
|
|
126
130
|
if skip_package?
|
127
131
|
Log.info "Package building disabled"
|
@@ -140,37 +144,15 @@ module FPM
|
|
140
144
|
def build_package(recipe, config)
|
141
145
|
recipe.pkgdir.mkdir
|
142
146
|
Dir.chdir(recipe.pkgdir) do
|
143
|
-
|
144
|
-
|
145
|
-
ver, epoch = epoch, nil
|
146
|
-
end
|
147
|
-
|
148
|
-
# Build a version including vendor and revision.
|
149
|
-
vendor = config[:vendor] || recipe.vendor
|
150
|
-
vendor_rev = "#{vendor}#{recipe.revision}"
|
151
|
-
case @target
|
152
|
-
when "deb"
|
153
|
-
vendor_delimiter = "+"
|
154
|
-
when "rpm"
|
155
|
-
vendor_delimiter = "."
|
156
|
-
else
|
157
|
-
vendor_delimiter = "-"
|
158
|
-
end
|
159
|
-
version = [ver, vendor_rev].join(vendor_delimiter)
|
160
|
-
|
161
|
-
maintainer = recipe.maintainer || begin
|
162
|
-
username = git_config('user.name')
|
163
|
-
useremail = git_config('user.email')
|
164
|
-
|
165
|
-
username && useremail ? "#{username} <#{useremail}>" : nil
|
166
|
-
end
|
147
|
+
version = FPM::Cookery::Package::Version.new(recipe, @target, config)
|
148
|
+
maintainer = FPM::Cookery::Package::Maintainer.new(recipe, config)
|
167
149
|
|
168
|
-
input =
|
150
|
+
input = recipe.input(config)
|
169
151
|
|
170
|
-
input.version = version
|
171
|
-
input.maintainer = maintainer
|
172
|
-
input.vendor = vendor if vendor
|
173
|
-
input.epoch = epoch if epoch
|
152
|
+
input.version = version.to_s
|
153
|
+
input.maintainer = maintainer.to_s
|
154
|
+
input.vendor = version.vendor if version.vendor
|
155
|
+
input.epoch = version.epoch if version.epoch
|
174
156
|
|
175
157
|
add_scripts(recipe, input)
|
176
158
|
remove_excluded_files(recipe)
|
@@ -195,16 +177,9 @@ module FPM
|
|
195
177
|
|
196
178
|
def add_scripts(recipe, input)
|
197
179
|
error = false
|
180
|
+
scripts = [:pre_install, :post_install, :pre_uninstall, :post_uninstall]
|
198
181
|
|
199
|
-
|
200
|
-
script_map = {
|
201
|
-
'pre_install' => :before_install,
|
202
|
-
'post_install' => :after_install,
|
203
|
-
'pre_uninstall' => :before_remove,
|
204
|
-
'post_uninstall' => :after_remove
|
205
|
-
}
|
206
|
-
|
207
|
-
script_map.each do |script, fpm_script|
|
182
|
+
scripts.each do |script|
|
208
183
|
unless recipe.send(script).nil?
|
209
184
|
script_file = FPM::Cookery::Path.new(recipe.send(script))
|
210
185
|
|
@@ -215,7 +190,7 @@ module FPM
|
|
215
190
|
end
|
216
191
|
|
217
192
|
if File.exists?(script_file)
|
218
|
-
input.
|
193
|
+
input.add_script(script, File.read(script_file.to_s))
|
219
194
|
else
|
220
195
|
Log.error "#{script} script '#{script_file}' is missing"
|
221
196
|
error = true
|
@@ -229,26 +204,19 @@ module FPM
|
|
229
204
|
# Remove all excluded files from the destdir so they do not end up in the
|
230
205
|
# package.
|
231
206
|
def remove_excluded_files(recipe)
|
232
|
-
|
233
|
-
Dir
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
207
|
+
if File.directory?(recipe.destdir)
|
208
|
+
Dir.chdir(recipe.destdir.to_s) do
|
209
|
+
Dir['**/*'].each do |file|
|
210
|
+
recipe.exclude.each do |ex|
|
211
|
+
if File.fnmatch(ex, file)
|
212
|
+
Log.info "Exclude file: #{file}"
|
213
|
+
FileUtils.rm_f(file)
|
214
|
+
end
|
238
215
|
end
|
239
216
|
end
|
240
217
|
end
|
241
218
|
end
|
242
219
|
end
|
243
|
-
|
244
|
-
private
|
245
|
-
|
246
|
-
def git_config(key)
|
247
|
-
%x(git config --get #{key}).strip
|
248
|
-
rescue
|
249
|
-
Log.warn "Git config command for key '#{key}' failed."
|
250
|
-
nil
|
251
|
-
end
|
252
220
|
end
|
253
221
|
end
|
254
222
|
end
|