fpm 0.3.11 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/CHANGELIST +15 -0
  2. data/bin/fpm +2 -15
  3. data/lib/fpm.rb +5 -12
  4. data/lib/fpm/command.rb +323 -0
  5. data/lib/fpm/errors.rb +1 -0
  6. data/lib/fpm/namespace.rb +2 -11
  7. data/lib/fpm/package.rb +255 -100
  8. data/lib/fpm/package/deb.rb +367 -0
  9. data/lib/fpm/package/dir.rb +86 -0
  10. data/lib/fpm/package/gem.rb +162 -0
  11. data/lib/fpm/{source → package}/npm.rb +3 -3
  12. data/lib/fpm/package/pear.rb +41 -0
  13. data/lib/fpm/{target → package}/puppet.rb +1 -3
  14. data/lib/fpm/{source → package}/pyfpm/__init__.py +0 -0
  15. data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
  16. data/lib/fpm/{source → package}/pyfpm/get_metadata.py +15 -3
  17. data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
  18. data/lib/fpm/package/python.rb +125 -0
  19. data/lib/fpm/package/rpm.rb +132 -0
  20. data/lib/fpm/{target → package}/solaris.rb +3 -2
  21. data/lib/fpm/package/tar.rb +62 -0
  22. data/lib/fpm/util.rb +56 -7
  23. data/templates/deb.erb +12 -12
  24. data/templates/rpm.erb +32 -38
  25. data/templates/solaris.erb +1 -1
  26. metadata +119 -78
  27. data/lib/fpm/builder.rb +0 -220
  28. data/lib/fpm/flags.rb +0 -20
  29. data/lib/fpm/program.rb +0 -273
  30. data/lib/fpm/rubyfixes.rb +0 -11
  31. data/lib/fpm/source.rb +0 -155
  32. data/lib/fpm/source/dir.rb +0 -59
  33. data/lib/fpm/source/gem.rb +0 -162
  34. data/lib/fpm/source/python.rb +0 -137
  35. data/lib/fpm/source/rpm.rb +0 -28
  36. data/lib/fpm/source/tar.rb +0 -50
  37. data/lib/fpm/target/deb.rb +0 -184
  38. data/lib/fpm/target/rpm.rb +0 -68
  39. data/lib/rpm/header.rb +0 -89
  40. data/lib/rpm/lead.rb +0 -48
  41. data/lib/rpm/namespace.rb +0 -1
  42. data/lib/rpm/rpmfile.rb +0 -81
  43. data/lib/rpm/tag.rb +0 -304
data/lib/fpm/builder.rb DELETED
@@ -1,220 +0,0 @@
1
- require "fileutils"
2
- require "fpm/util"
3
- require "pathname"
4
-
5
- class FPM::Builder
6
- # where is the package's root?
7
- def root
8
- @root ||= (@source.root || '.')
9
- end
10
-
11
- # where the package goes
12
- def output
13
- @output ||= begin
14
- o = @package.default_output
15
- if o[0,1] == "/"
16
- o
17
- else
18
- File.join(@working_dir, o)
19
- end
20
- end
21
- end
22
-
23
- # things to clean up afterwards
24
- def garbage
25
- @garbage ||= []
26
- end
27
-
28
- attr_reader :paths
29
- attr_reader :package
30
- attr_reader :source
31
-
32
- def initialize(settings, paths=[])
33
- @logger = Logger.new(STDERR)
34
- @logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
35
-
36
- @working_dir = Dir.pwd
37
- root = settings.chdir || '.'
38
- paths = ['.'] if paths.empty?
39
- @source = source_class_for(settings.source_type || 'dir').new(
40
- paths, root,
41
- :version => settings.version,
42
- :iteration => settings.iteration,
43
- :epoch => settings.epoch,
44
- :name => settings.package_name,
45
- :prefix => settings.prefix,
46
- :suffix => settings.suffix,
47
- :exclude => settings.exclude,
48
- :maintainer => settings.maintainer,
49
- :provides => [],
50
- :replaces => [],
51
- :conflicts => [],
52
- :description => settings.description,
53
- :url => settings.url,
54
- :settings => settings.source
55
- )
56
-
57
- @edit = !!settings.edit
58
-
59
- @paths = paths
60
- @package = package_class_for(settings.package_type).new(@source,
61
- :settings => settings.target
62
- )
63
- # Append dependencies given from settings (-d flag for fpm)
64
- @package.dependencies += settings.dependencies if settings.dependencies
65
- # Append provides given from settings (--provides flag for fpm)
66
- @package.provides += settings.provides if settings.provides
67
- @package.replaces += settings.replaces if settings.replaces
68
- @package.conflicts += settings.conflicts if settings.conflicts
69
- @package.architecture = settings.architecture if settings.architecture
70
- @package.category = settings.category if settings.category
71
- @package.scripts = settings.scripts
72
- @package.config_files = settings.config_files
73
-
74
- @output = settings.package_path
75
- @recurse_dependencies = settings.recurse_dependencies
76
- end # def initialize
77
-
78
- def tar_path
79
- @tar_path ||= "#{builddir}/data.tar"
80
- end
81
-
82
- # Assemble the package
83
- def assemble!
84
- version_a = [ @source[:version], @package.iteration ].compact
85
- if @package.epoch
86
- output.gsub!(/VERSION/, "#{@package.epoch}:" + version_a.join('-'))
87
- else
88
- output.gsub!(/VERSION/, version_a.join('-'))
89
- end
90
- output.gsub!(/ARCH/, @package.architecture)
91
-
92
- File.delete(output) if File.exists?(output) && !File.directory?(output)
93
-
94
- make_builddir!
95
-
96
- ::Dir.chdir root do
97
- @source.make_tarball!(tar_path, builddir)
98
-
99
- # Hack to unpack before generating the spec, etc.
100
- # Need to formalize this feature.
101
- # Perhaps something like @package.prepare
102
- if @package.respond_to?(:unpack_data_to)
103
- data_tarball = File.join(builddir, "data.tar.gz")
104
- Dir.chdir(builddir) do
105
- FileUtils.mkdir_p(@package.unpack_data_to)
106
- safesystem("gzip -d #{data_tarball}")
107
- Dir.chdir(@package.unpack_data_to) do
108
- @source.root = Dir.pwd
109
- safesystem("tar -xf #{data_tarball.gsub(/\.gz$/, "")}")
110
- end
111
- end
112
- end
113
-
114
- generate_md5sums if @package.needs_md5sums
115
- generate_specfile
116
- edit_specfile if @edit
117
- end
118
-
119
- ::Dir.chdir(builddir) do
120
- @package.build!({
121
- :tarball => tar_path,
122
- :output => output
123
- })
124
- end
125
-
126
- garbage << @source.garbage if @source.respond_to?(:garbage)
127
-
128
- cleanup!
129
- end # def assemble!
130
-
131
- private
132
- def builddir
133
- @builddir ||= File.expand_path(
134
- "#{Dir.pwd}/build-#{@package.type}-#{File.basename(output)}"
135
- )
136
- end
137
-
138
- private
139
- def make_builddir!
140
- FileUtils.rm_rf builddir
141
- garbage << builddir
142
- FileUtils.mkdir(builddir) if !File.directory?(builddir)
143
- end
144
-
145
- # TODO: [Jay] make this better.
146
- private
147
- def package_class_for(type)
148
- realtype = FPM::Target.constants.find { |c| c.downcase.to_s == type }
149
- if !realtype
150
- valid_types = FPM::Target.constants.collect { |c| c.downcase }
151
- @logger.fatal("No such package target type #{type.inspect}; " \
152
- "Valid types: #{valid_types.join(", ")}")
153
- raise ArgumentError, "unknown package type #{type.inspect}"
154
- end
155
-
156
- return FPM::Target.const_get(realtype)
157
- end
158
-
159
- # TODO: [Jay] make this better.
160
- private
161
- def source_class_for(type)
162
- realtype = FPM::Source::constants.find { |c| c.downcase.to_s == type }
163
- if !realtype
164
- valid_types = FPM::Source.constants.collect { |c| c.downcase }
165
- @logger.fatal("No such package source type #{type.inspect}; " \
166
- "Valid types: #{valid_types.join(", ")}")
167
- raise ArgumentError, "unknown package type #{type.inspect}"
168
- end
169
-
170
- return FPM::Source.const_get(realtype)
171
- end
172
-
173
- private
174
- def cleanup!
175
- return [] if garbage.empty?
176
- FileUtils.rm_rf(garbage) && garbage.clear
177
- end
178
-
179
- private
180
- def generate_specfile
181
- @package.generate_specfile(builddir)
182
- end
183
-
184
- private
185
- def edit_specfile
186
- # TODO(sissel): support editing multiple files for targets like
187
- # puppet which generate multiple manifests.
188
- editor = ENV['FPM_EDITOR'] || ENV['EDITOR'] || 'vi'
189
- safesystem("#{editor} '#{package.specfile(builddir)}'")
190
- unless File.size? package.specfile(builddir)
191
- puts "Empty specfile. Aborting."
192
- exit 1
193
- end
194
- end
195
-
196
- private
197
- def generate_md5sums
198
- md5sums = checksum(paths)
199
- File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums }
200
- md5sums
201
- end
202
-
203
- private
204
- def checksum(paths)
205
- paths.collect do |path|
206
- if File.directory? path
207
- # This should work for both cases where we use -C or not ...
208
- %x{ find #{path} -type f -print0 | xargs -0 md5sum }.split("\n").collect do |i|
209
- # Remove leading path and "./" from the md5sum output if present ...
210
- i = i.split(/\s+/)
211
- "%s %s" % [i[0], i[1].sub(/#{path}\//, '').sub(/\.\//, '')]
212
- end
213
- elsif File.exists? path
214
- %x{md5sum "#{path}"}
215
- else
216
- next
217
- end
218
- end.flatten
219
- end # def checksum
220
- end
data/lib/fpm/flags.rb DELETED
@@ -1,20 +0,0 @@
1
- require "fpm/namespace"
2
-
3
- class FPM::Flags
4
- def initialize(opts, flag_prefix, help_prefix)
5
- @opts = opts
6
- @flag_prefix = flag_prefix
7
- @help_prefix = help_prefix
8
- end # def initialize
9
-
10
- def on(*args, &block)
11
- fixed_args = args.collect do |arg|
12
- if arg =~ /^--/
13
- "--#{@flag_prefix}-#{arg.gsub(/^--/, "")}"
14
- else
15
- "(#{@help_prefix}) #{arg}"
16
- end
17
- end
18
- @opts.on(*fixed_args, &block)
19
- end # def on
20
- end # class FPM::Flags
data/lib/fpm/program.rb DELETED
@@ -1,273 +0,0 @@
1
- require "rubygems"
2
- require "erb" # TODO(sissel): Move to the class that needs it.
3
- require "fpm/namespace"
4
- require "optparse"
5
- require "ostruct"
6
-
7
- require "fpm"
8
- require "fpm/flags"
9
-
10
- class FPM::Program
11
- def initialize
12
- @settings = OpenStruct.new
13
- @settings.dependencies = []
14
- @settings.exclude = [] # Paths to exclude in packaging
15
- @settings.provides = []
16
- @settings.replaces = []
17
- @settings.conflicts = []
18
- @settings.source = {} # source settings
19
- @settings.target = {} # target settings
20
- @settings.config_files ||= []
21
- @settings.inputs_path = nil # file path to read a list of paths from
22
- @settings.paths = [] # Paths to include in the package
23
-
24
- # Maintainer scripts - https://github.com/jordansissel/fpm/issues/18
25
- @settings.scripts ||= {}
26
-
27
- @help = nil
28
- end # def initialize
29
-
30
- def run(args)
31
- $: << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
32
- extracted_args = options(args)
33
-
34
- ok = true
35
- if @settings.package_type.nil?
36
- $stderr.puts "Missing package target type (no -t flag?)"
37
- ok = false
38
- end
39
-
40
- if @settings.source_type.nil?
41
- $stderr.puts "Missing package source type (no -s flag?)"
42
- ok = false
43
- end
44
-
45
- paths = process_paths(extracted_args)
46
- ok = false if paths == :errors
47
-
48
- if !ok
49
- $stderr.puts "There were errors; see above."
50
- $stderr.puts
51
- $stderr.puts @help
52
- return 1
53
- end
54
-
55
- builder = FPM::Builder.new(@settings, paths)
56
- builder.assemble!
57
- puts "Created #{builder.output}"
58
- return 0
59
- end # def run
60
-
61
- def process_paths(args)
62
- paths_iolike = args
63
- read_from_stdin = args.length == 1 && args.first == '-'
64
-
65
- ok = true
66
- if @settings.inputs_path
67
- if read_from_stdin
68
- $stderr.puts "Error: setting --inputs conflicts with passing '-' as the only argument"
69
- ok = false
70
- end
71
- unless File.file?(@settings.inputs_path)
72
- $stderr.puts "Error: '#{@settings.inputs_path}' does not exist"
73
- ok = false
74
- end
75
- end
76
-
77
- return :errors if !ok
78
-
79
- if read_from_stdin
80
- paths_iolike = $stdin
81
- end
82
- if @settings.inputs_path
83
- paths_iolike = File.open(@settings.inputs_path, 'r')
84
- end
85
-
86
- paths = []
87
- paths_iolike.each do |entry|
88
- paths << entry.strip
89
- end
90
- paths_iolike.close if paths_iolike.respond_to?(:close)
91
- paths
92
- end # def process_paths
93
-
94
- def options(args)
95
- opts = OptionParser.new
96
- default_options(opts)
97
-
98
- # Add extra flags from plugins
99
- FPM::Source::Gem.flags(FPM::Flags.new(opts, "gem", "gem source only"), @settings)
100
- FPM::Source::Python.flags(FPM::Flags.new(opts, "python", "python source only"),
101
- @settings)
102
- FPM::Target::Deb.flags(FPM::Flags.new(opts, "deb", "deb target only"), @settings)
103
-
104
- # Process fpmrc first
105
- fpmrc(opts)
106
-
107
- # Proces normal flags now.
108
- remaining = opts.parse(args)
109
-
110
- # need to print help in a different scope
111
- @help = opts.help
112
-
113
- return remaining
114
- end # def options
115
-
116
- def fpmrc(options)
117
- # Skip if we have no HOME environment variable.
118
- return if !ENV.include?("HOME")
119
- rcpath = File.expand_path("~/.fpmrc")
120
- return if !File.exists?(rcpath)
121
-
122
- # fpmrc exists, read it as flags, one per line.
123
- File.new(rcpath, "r").each do |line|
124
- flag = line.chomp
125
- begin
126
- options.parse([flag])
127
- rescue => e
128
- $stderr.puts "Error parsing fpmrc (#{rcpath})"
129
- raise e
130
- end # begin
131
- end # File.new
132
- end # def fpmrc
133
-
134
- def default_options(opts)
135
- # TODO(sissel): Maybe this should be '-o OUTPUT' ?
136
- opts.on("-p PACKAGEFILE", "--package PACKAGEFILE",
137
- "The package file to manage") do |path|
138
- if path =~ /^\//
139
- @settings.package_path = path
140
- else
141
- @settings.package_path = "#{Dir.pwd}/#{path}"
142
- end
143
- end # --package
144
-
145
- opts.on("-n PACKAGENAME", "--name PACKAGENAME",
146
- "What name to give to the package") do |name|
147
- @settings.package_name = name
148
- end # --name
149
-
150
- opts.on("-v VERSION", "--version VERSION",
151
- "version to give the package") do |version|
152
- @settings.version = version
153
- end # --version
154
-
155
- opts.on("--iteration ITERATION",
156
- "(optional) Set the iteration value for this package ('release' for RPM).") do |iteration|
157
- @settings.iteration = iteration
158
- end # --iteration
159
-
160
- opts.on("--epoch EPOCH",
161
- "(optional) Set epoch value for this package.") do |epoch|
162
- @settings.epoch = epoch
163
- end # --epoch
164
-
165
- opts.on("-d DEPENDENCY", "--depends DEPENDENCY") do |dep|
166
- @settings.dependencies << dep
167
- end # --depends
168
-
169
- opts.on("--category SECTION_OR_GROUP") do |thing|
170
- @settings.category = thing
171
- end # --category
172
-
173
- opts.on("--provides PROVIDES") do |thing|
174
- @settings.provides << thing
175
- end # --provides
176
-
177
- opts.on("--conflicts CONFLICTS") do |thing|
178
- @settings.conflicts << thing
179
- end # --conflicts
180
-
181
- opts.on("--replaces REPLACES") do |thing|
182
- @settings.replaces << thing
183
- end # --replaces
184
-
185
- opts.on("--config-files PATH",
186
- "(optional) Treat path as a configuration file. Uses conffiles in deb or %config in rpm. (/etc/package.conf)") do |thing|
187
- @settings.config_files << thing
188
- end
189
-
190
- opts.on("-a ARCHITECTURE", "--architecture ARCHITECTURE") do |arch|
191
- @settings.architecture = arch
192
- end # --architecture
193
-
194
- opts.on("-m MAINTAINER", "--maintainer MAINTAINER") do |maintainer|
195
- @settings.maintainer = maintainer
196
- end # --maintainer
197
-
198
- opts.on("-C DIRECTORY", "Change directory before searching for files") do |dir|
199
- @settings.chdir = dir
200
- end # -C
201
-
202
- opts.on("-t PACKAGE_TYPE", "the type of package you want to create") do |type|
203
- @settings.package_type = type
204
- end # -t
205
-
206
- opts.on("-s SOURCE_TYPE", "what to build the package from") do |st|
207
- @settings.source_type = st
208
- end # -s
209
-
210
- opts.on("-S PACKAGE_SUFFIX", "which suffix to append to package and dependencies") do |sfx|
211
- @settings.suffix = sfx
212
- end # -S
213
-
214
- opts.on("--prefix PREFIX",
215
- "A path to prefix files with when building the target package. This may not be necessary for all source types. For example, the 'gem' type will prefix with your gem directory (gem env | grep -A1 PATHS:)") do |prefix|
216
- @settings.prefix = prefix
217
- end # --prefix
218
-
219
- opts.on("-e", "--edit", "Edit the specfile before building") do
220
- @settings.edit = true
221
- end # --edit
222
-
223
- opts.on("-x PATTERN", "--exclude PATTERN",
224
- "Exclude paths matching pattern (according to tar --exclude)") do |pattern|
225
- @settings.exclude << pattern
226
- end # -x / --exclude
227
-
228
- opts.on("--post-install SCRIPTPATH",
229
- "Add a post-install action. This script will be included in the" \
230
- " resulting package") do |path|
231
- @settings.scripts["post-install"] = File.expand_path(path)
232
- end # --post-install
233
-
234
- opts.on("--pre-install SCRIPTPATH",
235
- "Add a pre-install action. This script will be included in the" \
236
- " resulting package") do |path|
237
- @settings.scripts["pre-install"] = File.expand_path(path)
238
- end # --pre-install
239
-
240
- opts.on("--pre-uninstall SCRIPTPATH",
241
- "Add a pre-uninstall action. This script will be included in the" \
242
- " resulting package") do |path|
243
- @settings.scripts["pre-uninstall"] = File.expand_path(path)
244
- end # --pre-uninstall
245
-
246
- opts.on("--post-uninstall SCRIPTPATH",
247
- "Add a post-uninstall action. This script will be included in the" \
248
- " resulting package") do |path|
249
- @settings.scripts["post-uninstall"] = File.expand_path(path)
250
- end # --post-uninstall
251
-
252
- opts.on("--description DESCRIPTION",
253
- "Add a description for this package.") do |description|
254
- @settings.description = description
255
- end # --description
256
-
257
- opts.on("--url URL",
258
- "Add a url for this package.") do |url|
259
- @settings.url = url
260
- end # --url
261
-
262
- opts.on("--inputs FILEPATH",
263
- "The path to a file containing a newline-separated list of " \
264
- "files and dirs to package.") do |path|
265
- settings.source[:inputs] = path
266
- end
267
-
268
- opts.separator "Pass - as the only argument to have the list of " \
269
- "files and dirs read from STDIN " \
270
- "(e.g. fpm -s dir -t deb - < FILELIST)"
271
-
272
- end # def default_options
273
- end # class FPM::Program