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.
Defined Under Namespace
Classes: Deb, Dir, FileAlreadyExists, Gem, InvalidArgument, NPM, PEAR, ParentDirectoryMissing, Puppet, Python, RPM, Solaris, Tar
Instance Attribute Summary collapse
-
#architecture ⇒ Object
What architecture is this package for?.
-
#attributes ⇒ Object
Any other attributes specific to this package.
-
#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.
-
#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.
-
#excludes ⇒ Object
Array of glob patterns to exclude from this package.
-
#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 paths 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
-
#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 covered 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 = "NAME.TYPE") ⇒ Object
def template.
-
#type ⇒ Object
Get the ‘type’ for this instance.
Methods included from Util
#program_in_path?, #safesystem, #tar_cmd, #with
Constructor Details
#initialize ⇒ Package
Returns a new instance of Package.
113 114 115 116 117 118 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 |
# File 'lib/fpm/package.rb', line 113 def initialize @logger = Cabin::Channel.get # Attributes for this specific package @attributes = {} # 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| with(option.attribute_name) 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 = [] staging_path build_path end |
Instance Attribute Details
#architecture ⇒ Object
What architecture is this package for?
78 79 80 |
# File 'lib/fpm/package.rb', line 78 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.
109 110 111 |
# File 'lib/fpm/package.rb', line 109 def attributes @attributes end |
#category ⇒ Object
The category of this package. RedHat calls this ‘Group’ Debian calls this ‘Section’ FreeBSD would put this in /usr/ports/<category>/…
72 73 74 |
# File 'lib/fpm/package.rb', line 72 def category @category end |
#config_files ⇒ Object
Array of configuration files
105 106 107 |
# File 'lib/fpm/package.rb', line 105 def config_files @config_files end |
#conflicts ⇒ Object
Array of things this package conflicts with. (Not all packages support this)
89 90 91 |
# File 'lib/fpm/package.rb', line 89 def conflicts @conflicts end |
#dependencies ⇒ Object
Array of dependencies.
81 82 83 |
# File 'lib/fpm/package.rb', line 81 def dependencies @dependencies end |
#description ⇒ Object
a summary or description of the package
99 100 101 |
# File 'lib/fpm/package.rb', line 99 def description @description 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.
45 46 47 |
# File 'lib/fpm/package.rb', line 45 def epoch @epoch end |
#excludes ⇒ Object
Array of glob patterns to exclude from this package
96 97 98 |
# File 'lib/fpm/package.rb', line 96 def excludes @excludes 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.
54 55 56 |
# File 'lib/fpm/package.rb', line 54 def iteration @iteration end |
#license ⇒ Object
A identifier representing the license. Any string is fine.
75 76 77 |
# File 'lib/fpm/package.rb', line 75 def license @license end |
#maintainer ⇒ Object
Who maintains this package? This could be the upstream author or the package maintainer. You pick.
58 59 60 |
# File 'lib/fpm/package.rb', line 58 def maintainer @maintainer end |
#name ⇒ Object
The name of this package
37 38 39 |
# File 'lib/fpm/package.rb', line 37 def name @name end |
#provides ⇒ Object
Array of things this package provides. (Not all packages support this)
85 86 87 |
# File 'lib/fpm/package.rb', line 85 def provides @provides end |
#replaces ⇒ Object
Array of things this package replaces. (Not all packages support this)
93 94 95 |
# File 'lib/fpm/package.rb', line 93 def replaces @replaces end |
#scripts ⇒ Object
hash of paths for maintainer/package scripts (postinstall, etc)
102 103 104 |
# File 'lib/fpm/package.rb', line 102 def scripts @scripts end |
#url ⇒ Object
URL for this package. Could be the homepage. Could be the download url. You pick.
66 67 68 |
# File 'lib/fpm/package.rb', line 66 def url @url end |
#vendor ⇒ Object
A identifier representing the vendor. Any string is fine. This is usually who produced the software.
62 63 64 |
# File 'lib/fpm/package.rb', line 62 def vendor @vendor end |
#version ⇒ Object
Get the version of this package
40 41 42 |
# File 'lib/fpm/package.rb', line 40 def version @version end |
Class Method Details
.apply_options(clampcommand) ⇒ Object
438 439 440 441 442 443 444 |
# File 'lib/fpm/package.rb', line 438 def (clampcommand) @options ||= [] @options.each do |args| flag, param, help, , block = args clampcommand.option(flag, param, help, , &block) end end |
.default_attributes(&block) ⇒ Object
def apply_options
446 447 448 449 450 451 452 453 |
# File 'lib/fpm/package.rb', line 446 def default_attributes(&block) return if @options.nil? @options.each do |flag, param, help, , block| attr = flag.first.gsub(/^-+/, "").gsub(/-/, "_") 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
399 400 401 402 |
# File 'lib/fpm/package.rb', line 399 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
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 |
# File 'lib/fpm/package.rb', line 410 def option(flag, param, help, ={}, &block) @options ||= [] 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}" @options << [flag, param, help, , block] end |
.type ⇒ Object
Get the type of this package class.
For “Foo::Bar::BAZ” this will return “baz”
458 459 460 |
# File 'lib/fpm/package.rb', line 458 def type self.name.split(':').last.downcase end |
.types ⇒ Object
Get a list of all known package subclasses
405 406 407 |
# File 'lib/fpm/package.rb', line 405 def types return @subclasses end |
Instance Method Details
#cleanup ⇒ Object
Clean up any temporary storage used by this class.
262 263 264 265 |
# File 'lib/fpm/package.rb', line 262 def cleanup cleanup_staging cleanup_build end |
#cleanup_build ⇒ Object
def cleanup_staging
274 275 276 277 278 279 |
# File 'lib/fpm/package.rb', line 274 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
267 268 269 270 271 272 |
# File 'lib/fpm/package.rb', line 267 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
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/fpm/package.rb', line 184 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, :@attributes, :@category, :@config_files, :@conflicts, :@dependencies, :@description, :@epoch, :@iteration, :@license, :@maintainer, :@name, :@provides, :@replaces, :@scripts, :@url, :@vendor, :@version, :@config_files, :@staging_path ] 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 pkg.converted_from(self.class) return pkg end |
#converted_from(origin) ⇒ Object
This method is invoked on a package when it has been covered to a new package format. The purpose of this method is to do any extra conversion steps, like translating dependency conditions, etc.
212 213 214 215 |
# File 'lib/fpm/package.rb', line 212 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
334 335 336 337 338 339 340 341 342 |
# File 'lib/fpm/package.rb', line 334 def edit_file(path) editor = ENV['FPM_EDITOR'] || ENV['EDITOR'] || 'vi' @logger.info("Launching editor", :file => path) safesystem("#{editor} #{Shellwords.escape(path)}") 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.
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/fpm/package.rb', line 289 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' 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
230 231 232 233 |
# File 'lib/fpm/package.rb', line 230 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.
236 237 238 239 |
# File 'lib/fpm/package.rb', line 236 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.
488 489 490 491 492 493 494 495 496 497 |
# File 'lib/fpm/package.rb', line 488 def script(script_name) if attributes[:template_scripts?] erb = ERB.new(scripts[script_name], nil, "-") # 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
241 242 243 244 245 246 247 248 249 |
# File 'lib/fpm/package.rb', line 241 def staging_path(path=nil) @staging_path ||= ::Dir.mktmpdir("package-#{type}-staging") #, ::Dir.pwd) if path.nil? return @staging_path else return File.join(@staging_path, path) end end |
#to_s(fmt = "NAME.TYPE") ⇒ Object
def template
321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/fpm/package.rb', line 321 def to_s(fmt="NAME.TYPE") fmt = "NAME.TYPE" if fmt.nil? fullversion = version.to_s fullversion += "-#{iteration}" if iteration return fmt.gsub("ARCH", architecture.to_s) \ .gsub("NAME", name.to_s) \ .gsub("FULLVERSION", fullversion) \ .gsub("VERSION", version.to_s) \ .gsub("ITERATION", iteration.to_s) \ .gsub("EPOCH", epoch.to_s) \ .gsub("TYPE", type.to_s) end |
#type ⇒ Object
Get the ‘type’ for this instance.
For FPM::Package::ABC, this returns ‘abc’
179 180 181 |
# File 'lib/fpm/package.rb', line 179 def type self.class.type end |