Class: FPM::Package
- Inherits:
-
Object
- Object
- FPM::Package
- Includes:
- Cabin::Inspectable, Util
- Defined in:
- lib/fpm/package.rb,
lib/fpm/namespace.rb
Overview
This class is the parent of all packages. If you want to implement an FPM package type, you’ll inherit from this.
Direct Known Subclasses
APK, CPAN, Deb, Dir, Empty, FreeBSD, Gem, NPM, OSXpkg, P5P, PEAR, Pacman, Pkgin, PleaseRun, Puppet, Python, RPM, Sh, Snap, Solaris, Tar, Virtualenv, Zip
Defined Under Namespace
Classes: APK, CPAN, Deb, Dir, Empty, FileAlreadyExists, FreeBSD, Gem, InvalidArgument, NPM, OSXpkg, P5P, PEAR, Pacman, ParentDirectoryMissing, Pkgin, PleaseRun, Puppet, Python, RPM, Sh, Snap, Solaris, Tar, Virtualenv, Zip
Instance Attribute Summary collapse
-
#architecture ⇒ Object
What architecture is this package for?.
-
#attributes ⇒ Object
Any other attributes specific to this package.
-
#attrs ⇒ Object
Returns the value of attribute attrs.
-
#category ⇒ Object
The category of this package.
-
#config_files ⇒ Object
Array of configuration files.
-
#conflicts ⇒ Object
Array of things this package conflicts with.
-
#dependencies ⇒ Object
Array of dependencies.
-
#description ⇒ Object
a summary or description of the package.
-
#directories ⇒ Object
Returns the value of attribute directories.
-
#epoch ⇒ Object
The epoch version of this package This is used most when an upstream package changes it’s versioning style so standard comparisions wouldn’t work.
-
#iteration ⇒ Object
The iteration of this package.
-
#license ⇒ Object
A identifier representing the license.
-
#maintainer ⇒ Object
Who maintains this package? This could be the upstream author or the package maintainer.
-
#name ⇒ Object
The name of this package.
-
#provides ⇒ Object
Array of things this package provides.
-
#replaces ⇒ Object
Array of things this package replaces.
-
#scripts ⇒ Object
hash of scripts for maintainer/package scripts (postinstall, etc).
-
#url ⇒ Object
URL for this package.
-
#vendor ⇒ Object
A identifier representing the vendor.
-
#version ⇒ Object
Get the version of this package.
Class Method Summary collapse
-
.apply_options(clampcommand) ⇒ Object
Apply the options for this package on the clamp command.
-
.default_attributes(&block) ⇒ Object
def apply_options.
-
.inherited(klass) ⇒ Object
This method is invoked when subclass occurs.
-
.option(flag, param, help, options = {}, &block) ⇒ Object
This allows packages to define flags for the fpm command line.
-
.type ⇒ Object
Get the type of this package class.
-
.types ⇒ Object
Get a list of all known package subclasses.
Instance Method Summary collapse
-
#build_path(path = nil) ⇒ Object
def staging_path.
-
#cleanup ⇒ Object
Clean up any temporary storage used by this class.
-
#cleanup_build ⇒ Object
def cleanup_staging.
-
#cleanup_staging ⇒ Object
def cleanup.
-
#convert(klass) ⇒ Object
Convert this package to a new package type.
-
#converted_from(origin) ⇒ Object
This method is invoked on a package when it has been converted to a new package format.
-
#edit_file(path) ⇒ Object
def to_s.
-
#files ⇒ Object
List all files in the staging_path.
-
#initialize ⇒ Package
constructor
A new instance of Package.
-
#input(thing_to_input) ⇒ Object
Add a new source to this package.
-
#output(path) ⇒ Object
Output this package to the given path.
-
#script(script_name) ⇒ Object
Get the contents of the script by a given name.
-
#staging_path(path = nil) ⇒ Object
def output.
- #to_s(fmt = nil) ⇒ Object
-
#type ⇒ Object
Get the ‘type’ for this instance.
Methods included from Util
#ar_cmd, #ar_cmd_deterministic?, #copied_entries, #copy_entry, #copy_metadata, #default_shell, #erbnew, #execmd, #expand_pessimistic_constraints, #logger, #program_exists?, #program_in_path?, #safesystem, #safesystemout, #tar_cmd, #tar_cmd_supports_sort_names_and_set_mtime?
Constructor Details
#initialize ⇒ Package
Returns a new instance of Package.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/fpm/package.rb', line 119 def initialize # Attributes for this specific package @attributes = { # Default work location :workdir => ::Dir.tmpdir } # Reference # http://www.debian.org/doc/manuals/maint-guide/first.en.html # http://wiki.debian.org/DeveloperConfiguration # https://github.com/jordansissel/fpm/issues/37 if ENV.include?("DEBEMAIL") and ENV.include?("DEBFULLNAME") # Use DEBEMAIL and DEBFULLNAME as the default maintainer if available. @maintainer = "#{ENV["DEBFULLNAME"]} <#{ENV["DEBEMAIL"]}>" else # TODO(sissel): Maybe support using 'git config' for a default as well? # git config --get user.name, etc can be useful. # # Otherwise default to user@currenthost @maintainer = "<#{ENV["USER"]}@#{Socket.gethostname}>" end # Set attribute defaults based on flags # This allows you to define command line options with default values # that also are obeyed if fpm is used programmatically. self.class.default_attributes do |attribute, value| attributes[attribute] = value end @name = nil @architecture = "native" @description = "no description given" @version = nil @epoch = nil @iteration = nil @url = nil @category = "default" @license = "unknown" @vendor = "none" # Iterate over all the options and set defaults if self.class.respond_to?(:declared_options) self.class..each do |option| option.attribute_name.tap do |attr| # clamp makes option attributes available as accessor methods # do --foo-bar is available as 'foo_bar' # make these available as package attributes. attr = "#{attr}?" if !respond_to?(attr) input.attributes[attr.to_sym] = send(attr) if respond_to?(attr) end end end @provides = [] @conflicts = [] @replaces = [] @dependencies = [] @scripts = {} @config_files = [] @directories = [] @attrs = {} build_path # Dont' initialize staging_path just yet, do it lazily so subclass can get a word in. end |
Instance Attribute Details
#architecture ⇒ Object
What architecture is this package for?
80 81 82 |
# File 'lib/fpm/package.rb', line 80 def architecture @architecture end |
#attributes ⇒ Object
Any other attributes specific to this package. This is where you’d put rpm, deb, or other specific attributes.
113 114 115 |
# File 'lib/fpm/package.rb', line 113 def attributes @attributes end |
#attrs ⇒ Object
Returns the value of attribute attrs.
115 116 117 |
# File 'lib/fpm/package.rb', line 115 def attrs @attrs end |
#category ⇒ Object
The category of this package. RedHat calls this ‘Group’ Debian calls this ‘Section’ FreeBSD would put this in /usr/ports/<category>/…
74 75 76 |
# File 'lib/fpm/package.rb', line 74 def category @category end |
#config_files ⇒ Object
Array of configuration files
107 108 109 |
# File 'lib/fpm/package.rb', line 107 def config_files @config_files end |
#conflicts ⇒ Object
Array of things this package conflicts with. (Not all packages support this)
91 92 93 |
# File 'lib/fpm/package.rb', line 91 def conflicts @conflicts end |
#dependencies ⇒ Object
Array of dependencies.
83 84 85 |
# File 'lib/fpm/package.rb', line 83 def dependencies @dependencies end |
#description ⇒ Object
a summary or description of the package
98 99 100 |
# File 'lib/fpm/package.rb', line 98 def description @description end |
#directories ⇒ Object
Returns the value of attribute directories.
109 110 111 |
# File 'lib/fpm/package.rb', line 109 def directories @directories end |
#epoch ⇒ Object
The epoch version of this package This is used most when an upstream package changes it’s versioning style so standard comparisions wouldn’t work.
47 48 49 |
# File 'lib/fpm/package.rb', line 47 def epoch @epoch end |
#iteration ⇒ Object
The iteration of this package.
Debian calls this 'release' and is the last '-NUMBER' in the version
RedHat has this as 'Release' in the .spec file
FreeBSD calls this 'PORTREVISION'
Iteration can be nil. If nil, the fpm package implementation is expected to handle any default value that should be instead.
56 57 58 |
# File 'lib/fpm/package.rb', line 56 def iteration @iteration end |
#license ⇒ Object
A identifier representing the license. Any string is fine.
77 78 79 |
# File 'lib/fpm/package.rb', line 77 def license @license end |
#maintainer ⇒ Object
Who maintains this package? This could be the upstream author or the package maintainer. You pick.
60 61 62 |
# File 'lib/fpm/package.rb', line 60 def maintainer @maintainer end |
#name ⇒ Object
The name of this package
39 40 41 |
# File 'lib/fpm/package.rb', line 39 def name @name end |
#provides ⇒ Object
Array of things this package provides. (Not all packages support this)
87 88 89 |
# File 'lib/fpm/package.rb', line 87 def provides @provides end |
#replaces ⇒ Object
Array of things this package replaces. (Not all packages support this)
95 96 97 |
# File 'lib/fpm/package.rb', line 95 def replaces @replaces end |
#scripts ⇒ Object
hash of scripts for maintainer/package scripts (postinstall, etc)
The keys are :before_install, etc The values are the text to use in the script.
104 105 106 |
# File 'lib/fpm/package.rb', line 104 def scripts @scripts end |
#url ⇒ Object
URL for this package. Could be the homepage. Could be the download url. You pick.
68 69 70 |
# File 'lib/fpm/package.rb', line 68 def url @url end |
#vendor ⇒ Object
A identifier representing the vendor. Any string is fine. This is usually who produced the software.
64 65 66 |
# File 'lib/fpm/package.rb', line 64 def vendor @vendor end |
#version ⇒ Object
Get the version of this package
42 43 44 |
# File 'lib/fpm/package.rb', line 42 def version @version end |
Class Method Details
.apply_options(clampcommand) ⇒ Object
Apply the options for this package on the clamp command
Package flags become attributes ‘type-flag’
So if you have:
class Foo < FPM::Package
option "--bar-baz" ...
end
The attribute value for –foo-bar-baz will be :foo_bar_baz“
453 454 455 456 457 458 459 |
# File 'lib/fpm/package.rb', line 453 def (clampcommand) ||= [] .each do |args| flag, param, help, , block = args clampcommand.option(flag, param, help, , &block) end end |
.default_attributes(&block) ⇒ Object
def apply_options
461 462 463 464 465 466 467 468 |
# File 'lib/fpm/package.rb', line 461 def default_attributes(&block) return if .nil? .each do |flag, param, help, , _block| attr = flag.first.gsub(/^-+/, "").gsub(/-/, "_").gsub("[no_]", "") attr += "?" if param == :flag yield attr.to_sym, [:default] end end |
.inherited(klass) ⇒ Object
This method is invoked when subclass occurs.
Lets us track all known FPM::Package subclasses
414 415 416 417 |
# File 'lib/fpm/package.rb', line 414 def inherited(klass) @subclasses ||= {} @subclasses[klass.name.gsub(/.*:/, "").downcase] = klass end |
.option(flag, param, help, options = {}, &block) ⇒ Object
This allows packages to define flags for the fpm command line
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 |
# File 'lib/fpm/package.rb', line 425 def option(flag, param, help, ={}, &block) ||= [] if !flag.is_a?(Array) flag = [flag] end if param == :flag # Automatically make 'flag' (boolean) options tunable with '--[no-]...' flag = flag.collect { |f| "--[no-]#{type}-#{f.gsub(/^--/, "")}" } else flag = flag.collect { |f| "--#{type}-#{f.gsub(/^--/, "")}" } end help = "(#{type} only) #{help}" << [flag, param, help, , block] end |
.type ⇒ Object
Get the type of this package class.
For “Foo::Bar::BAZ” this will return “baz”
473 474 475 |
# File 'lib/fpm/package.rb', line 473 def type self.name.split(':').last.downcase end |
.types ⇒ Object
Get a list of all known package subclasses
420 421 422 |
# File 'lib/fpm/package.rb', line 420 def types return @subclasses end |
Instance Method Details
#build_path(path = nil) ⇒ Object
def staging_path
265 266 267 268 269 270 271 272 273 |
# File 'lib/fpm/package.rb', line 265 def build_path(path=nil) @build_path ||= Stud::Temporary.directory("package-#{type}-build") if path.nil? return @build_path else return File.join(@build_path, path) end end |
#cleanup ⇒ Object
Clean up any temporary storage used by this class.
276 277 278 279 |
# File 'lib/fpm/package.rb', line 276 def cleanup cleanup_staging cleanup_build end |
#cleanup_build ⇒ Object
def cleanup_staging
288 289 290 291 292 293 |
# File 'lib/fpm/package.rb', line 288 def cleanup_build if File.directory?(build_path) logger.debug("Cleaning up build path", :path => build_path) FileUtils.rm_r(build_path) end end |
#cleanup_staging ⇒ Object
def cleanup
281 282 283 284 285 286 |
# File 'lib/fpm/package.rb', line 281 def cleanup_staging if File.directory?(staging_path) logger.debug("Cleaning up staging path", :path => staging_path) FileUtils.rm_r(staging_path) end end |
#convert(klass) ⇒ Object
Convert this package to a new package type
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/fpm/package.rb', line 193 def convert(klass) logger.info("Converting #{self.type} to #{klass.type}") exclude pkg = klass.new pkg.cleanup_staging # purge any directories that may have been created by klass.new # copy other bits ivars = [ :@architecture, :@category, :@config_files, :@conflicts, :@dependencies, :@description, :@epoch, :@iteration, :@license, :@maintainer, :@name, :@provides, :@replaces, :@scripts, :@url, :@vendor, :@version, :@directories, :@staging_path, :@attrs ] ivars.each do |ivar| #logger.debug("Copying ivar", :ivar => ivar, :value => instance_variable_get(ivar), #:from => self.type, :to => pkg.type) pkg.instance_variable_set(ivar, instance_variable_get(ivar)) end # Attributes are special! We do not want to remove the default values of # the destination package type unless their value is specified on the # source package object. pkg.attributes.merge!(self.attributes) pkg.converted_from(self.class) return pkg end |
#converted_from(origin) ⇒ Object
This method is invoked on a package when it has been converted to a new package format. The purpose of this method is to do any extra conversion steps, like translating dependency conditions, etc.
226 227 228 229 |
# File 'lib/fpm/package.rb', line 226 def converted_from(origin) # nothing to do by default. Subclasses may implement this. # See the RPM package class for an example. end |
#edit_file(path) ⇒ Object
def to_s
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/fpm/package.rb', line 366 def edit_file(path) editor = ENV['FPM_EDITOR'] || ENV['EDITOR'] || 'vi' logger.info("Launching editor", :file => path) command = "#{editor} #{Shellwords.escape(path)}" system("#{editor} #{Shellwords.escape(path)}") if !$?.success? raise ProcessFailed.new("'#{editor}' failed (exit code " \ "#{$?.exitstatus}) Full command was: " \ "#{command}"); end if File.size(path) == 0 raise "Empty file after editing: #{path.inspect}" end end |
#files ⇒ Object
List all files in the staging_path
The paths will all be relative to staging_path and will not include that path.
This method will emit ‘leaf’ paths. Files, symlinks, and other file-like things are emitted. Intermediate directories are ignored, but empty directories are emitted.
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/fpm/package.rb', line 303 def files is_leaf = lambda do |path| # True if this is a file/symlink/etc, but not a plain directory return true if !(File.directory?(path) and !File.symlink?(path)) # Empty directories are leafs as well. return true if ::Dir.entries(path).sort == [".", ".."] # False otherwise (non-empty directory, etc) return false end # is_leaf # Find all leaf-like paths (files, symlink, empty directories, etc) # Also trim the leading path such that '#{staging_path}/' is removed from # the path before returning. # # Wrapping Find.find in an Enumerator is required for sane operation in ruby 1.8.7, # but requires the 'backports/latest' gem (which is used in other places in fpm) return Enumerator.new { |y| Find.find(staging_path) { |path| y << path } } \ .select { |path| path != staging_path } \ .select { |path| is_leaf.call(path) } \ .collect { |path| path[staging_path.length + 1.. -1] } end |
#input(thing_to_input) ⇒ Object
Add a new source to this package. The exact behavior depends on the kind of package being managed.
For instance:
-
for FPM::Package::Dir, << expects a path to a directory or files.
-
for FPM::Package::RPM, << expects a path to an rpm.
The idea is that you can keep pumping in new things to a package for later conversion or output.
Implementations are expected to put files relevant to the ‘input’ in the staging_path
244 245 246 247 |
# File 'lib/fpm/package.rb', line 244 def input(thing_to_input) raise NotImplementedError.new("#{self.class.name} does not yet support " \ "reading #{self.type} packages") end |
#output(path) ⇒ Object
Output this package to the given path.
250 251 252 253 |
# File 'lib/fpm/package.rb', line 250 def output(path) raise NotImplementedError.new("#{self.class.name} does not yet support " \ "creating #{self.type} packages") end |
#script(script_name) ⇒ Object
Get the contents of the script by a given name.
If template_scripts? is set in attributes (often by the –template-scripts flag), then apply it as an ERB template.
519 520 521 522 523 524 525 526 527 528 |
# File 'lib/fpm/package.rb', line 519 def script(script_name) if attributes[:template_scripts?] erb = erbnew(scripts[script_name]) # TODO(sissel): find the original file name for the file. erb.filename = "script(#{script_name})" return erb.result(binding) else return scripts[script_name] end end |
#staging_path(path = nil) ⇒ Object
def output
255 256 257 258 259 260 261 262 263 |
# File 'lib/fpm/package.rb', line 255 def staging_path(path=nil) @staging_path ||= Stud::Temporary.directory("package-#{type}-staging") if path.nil? return @staging_path else return File.join(@staging_path, path) end end |
#to_s(fmt = nil) ⇒ Object
354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/fpm/package.rb', line 354 def to_s(fmt=nil) fmt = "NAME.EXTENSION" if fmt.nil? return fmt.gsub("ARCH", to_s_arch) \ .gsub("NAME", to_s_name) \ .gsub("FULLVERSION", to_s_fullversion) \ .gsub("VERSION", to_s_version) \ .gsub("ITERATION", to_s_iteration) \ .gsub("EPOCH", to_s_epoch) \ .gsub("TYPE", to_s_type) \ .gsub("EXTENSION", to_s_extension) end |
#type ⇒ Object
Get the ‘type’ for this instance.
For FPM::Package::ABC, this returns ‘abc’
188 189 190 |
# File 'lib/fpm/package.rb', line 188 def type self.class.type end |