Check-in [d84b9cf55e]
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Move from @logger ivar to logger method. Tests pass. Hope is all we have. And hugs. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d84b9cf55ea2c2aca1b24ce15ed2c587 |
User & Date: | jls@semicomplete.com 2014-10-25 05:28:16 |
Context
2014-10-25
| ||
05:36 | Add input and output rpm trigger support This adds several rpm-specific flags: --before-install --after-install --before-uninstall --after-target-uninstall Fixes #626 (merged by hand) check-in: 4e74257a17 user: jls@semicomplete.com tags: trunk | |
05:28 | Move from @logger ivar to logger method. Tests pass. Hope is all we have. And hugs. check-in: d84b9cf55e user: jls@semicomplete.com tags: trunk | |
05:27 | Merge pull request #776 from Tapjoy/feature/sh_template_enhancements Enhancements to sh template check-in: 2f31b121c8 user: jls@semicomplete.com tags: trunk | |
Changes
Changes to lib/fpm/command.rb.
︙ | ︙ | |||
250 251 252 253 254 255 256 | def execute # Short-circuit if someone simply runs `fpm --version` if ARGV == [ "--version" ] puts FPM::VERSION return 0 end | | | | | | | | | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | def execute # Short-circuit if someone simply runs `fpm --version` if ARGV == [ "--version" ] puts FPM::VERSION return 0 end logger.level = :warn logger.level = :info if verbose? # --verbose logger.level = :debug if debug? # --debug if log_level logger.level = log_level.to_sym end if (stray_flags = args.grep(/^-/); stray_flags.any?) logger.warn("All flags should be before the first argument " \ "(stray flags found: #{stray_flags}") end # Some older behavior, if you specify: # 'fpm -s dir -t ... -C somepath' # fpm would assume you meant to add '.' to the end of the commandline. # Let's hack that. https://github.com/jordansissel/fpm/issues/187 if input_type == "dir" and args.empty? and !chdir.nil? logger.info("No args, but -s dir and -C are given, assuming '.' as input") args << "." end logger.info("Setting workdir", :workdir => workdir) ENV["TMP"] = workdir validator = Validator.new(self) if !validator.ok? validator.messages.each do |message| logger.warn(message) end logger.fatal("Fix the above problems, and you'll be rolling packages in no time!") return 1 end input_class = FPM::Package.types[input_type] output_class = FPM::Package.types[output_type] input = input_class.new |
︙ | ︙ | |||
316 317 318 319 320 321 322 | # If the instance variable @{attr} is defined, then # it means the flag was given on the command line. flag_given = instance_variable_defined?("@#{attr}") input.attributes["#{attr}_given?".to_sym] = flag_given attr = "#{attr}?" if !respond_to?(attr) # handle boolean :flag cases input.attributes[attr.to_sym] = send(attr) if respond_to?(attr) | | | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | # If the instance variable @{attr} is defined, then # it means the flag was given on the command line. flag_given = instance_variable_defined?("@#{attr}") input.attributes["#{attr}_given?".to_sym] = flag_given attr = "#{attr}?" if !respond_to?(attr) # handle boolean :flag cases input.attributes[attr.to_sym] = send(attr) if respond_to?(attr) logger.debug("Setting attribute", attr.to_sym => send(attr)) end end # Each remaining command line parameter is used as an 'input' argument. # For directories, this means paths. For things like gem and python, this # means package name or paths to the packages (rails, foo-1.0.gem, django, # bar/setup.py, etc) args.each do |arg| input.input(arg) end # If --inputs was specified, read it as a file. if !inputs.nil? if !File.exists?(inputs) logger.fatal("File given for --inputs does not exist (#{inputs})") return 1 end # Read each line as a path File.new(inputs, "r").each_line do |line| # Handle each line as if it were an argument input.input(line.strip) end end # Override package settings if they are not the default flag values # the below proc essentially does: # # if someflag != default_someflag # input.someflag = someflag # end set = proc do |object, attribute| # if the package's attribute is currently nil *or* the flag setting for this # attribute is non-default, use the value. if object.send(attribute).nil? || send(attribute) != send("default_#{attribute}") logger.info("Setting from flags: #{attribute}=#{send(attribute)}") object.send("#{attribute}=", send(attribute)) end end set.call(input, :architecture) set.call(input, :category) set.call(input, :description) set.call(input, :epoch) |
︙ | ︙ | |||
395 396 397 398 399 400 401 | # 'self.send(scriptname) == self.before_install == --before-install # Gets the path to the script path = self.send(scriptname) # Skip scripts not set next if path.nil? if !File.exists?(path) | | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | # 'self.send(scriptname) == self.before_install == --before-install # Gets the path to the script path = self.send(scriptname) # Skip scripts not set next if path.nil? if !File.exists?(path) logger.error("No such file (for #{scriptname.to_s}): #{path.inspect}") script_errors << path end # Load the script into memory. input.scripts[scriptname] = File.read(path) end setscript.call(:before_install) setscript.call(:after_install) setscript.call(:before_remove) setscript.call(:after_remove) setscript.call(:before_upgrade) setscript.call(:after_upgrade) # Bail if any setscript calls had errors. We don't need to log # anything because we've already logged the error(s) above. return 1 if script_errors.any? # Validate the package if input.name.nil? or input.name.empty? logger.fatal("No name given for this package (set name with, " \ "for example, '-n packagename')") return 1 end # Convert to the output type output = input.convert(output_class) |
︙ | ︙ | |||
445 446 447 448 449 450 451 | else package_file = output.to_s(package) end begin output.output(package_file) rescue FPM::Package::FileAlreadyExists => e | | | | | | | | < | | | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | else package_file = output.to_s(package) end begin output.output(package_file) rescue FPM::Package::FileAlreadyExists => e logger.fatal(e.message) return 1 rescue FPM::Package::ParentDirectoryMissing => e logger.fatal(e.message) return 1 end logger.log("Created package", :path => package_file) return 0 rescue FPM::Util::ExecutableNotFound => e logger.error("Need executable '#{e}' to convert #{input_type} to #{output_type}") return 1 rescue FPM::InvalidPackageConfiguration => e logger.error("Invalid package configuration: #{e}") return 1 rescue FPM::Util::ProcessFailed => e logger.error("Process failed: #{e}") return 1 ensure if debug_workspace? # only emit them if they have files [input, output].each do |plugin| next if plugin.nil? [:staging_path, :build_path].each do |pathtype| path = plugin.send(pathtype) next unless Dir.open(path).to_a.size > 2 logger.log("plugin directory", :plugin => plugin.type, :pathtype => pathtype, :path => path) end end else input.cleanup unless input.nil? output.cleanup unless output.nil? end end # def execute def run(*args) logger.subscribe(STDOUT) # fpm initialization files, note the order of the following array is # important, try .fpm in users home directory first and then the current # directory rc_files = [ ".fpm" ] rc_files << File.join(ENV["HOME"], ".fpm") if ENV["HOME"] rc_files.each do |rc_file| if File.readable? rc_file logger.warn("Loading flags from rc file #{rc_file}") File.readlines(rc_file).each do |line| # reverse becasue 'unshift' pushes onto the left side of the array. Shellwords.shellsplit(line).reverse.each do |arg| # Put '.fpm'-file flags *before* the command line flags # so that we the CLI can override the .fpm flags ARGV.unshift(arg) end end end end super(*args) rescue FPM::Package::InvalidArgument => e logger.error("Invalid package argument: #{e}") return 1 end # def run # A simple flag validator # # The goal of this class is to ensure the flags and arguments given # are a valid configuration. |
︙ | ︙ |
Changes to lib/fpm/package/cpan.rb.
︙ | ︙ | |||
69 70 71 72 73 74 75 | self.license = case metadata["license"] when Array; metadata["license"].first when nil; "unknown" else; metadata["license"] end unless metadata["distribution"].nil? | | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | self.license = case metadata["license"] when Array; metadata["license"].first when nil; "unknown" else; metadata["license"] end unless metadata["distribution"].nil? logger.info("Setting package name from 'distribution'", :distribution => metadata["distribution"]) self.name = fix_name(metadata["distribution"]) else logger.info("Setting package name from 'name'", :name => metadata["name"]) self.name = fix_name(metadata["name"]) end # author is not always set or it may be a string instead of an array self.vendor = case metadata["author"] when String; metadata["author"] when Array; metadata["author"].join(", ") else raise FPM::InvalidPackageConfiguration, "Unexpected CPAN 'author' field type: #{metadata["author"].class}. This is a bug." end if metadata.include?("author") self.url = metadata["resources"]["homepage"] rescue "unknown" # TODO(sissel): figure out if this perl module compiles anything # and set the architecture appropriately. self.architecture = "all" # Install any build/configure dependencies with cpanm. # We'll install to a temporary directory. logger.info("Installing any build or configure dependencies") cpanm_flags = ["-L", build_path("cpan"), moduledir] cpanm_flags += ["-n"] if attributes[:cpan_test?] cpanm_flags += ["--mirror", "#{attributes[:cpan_mirror]}"] if !attributes[:cpan_mirror].nil? cpanm_flags += ["--mirror-only"] if attributes[:cpan_mirror_only?] && !attributes[:cpan_mirror].nil? safesystem(attributes[:cpan_cpanm_bin], *cpanm_flags) |
︙ | ︙ | |||
213 214 215 216 217 218 219 | # Fix any files likely to cause conflicts that are duplicated # across packages. # https://github.com/jordansissel/fpm/issues/443 # https://github.com/jordansissel/fpm/issues/510 glob_prefix = attributes[:cpan_perl_lib_path] || prefix ::Dir.glob(File.join(staging_path, glob_prefix, "**/perllocal.pod")).each do |path| | | | | | | | | | | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | # Fix any files likely to cause conflicts that are duplicated # across packages. # https://github.com/jordansissel/fpm/issues/443 # https://github.com/jordansissel/fpm/issues/510 glob_prefix = attributes[:cpan_perl_lib_path] || prefix ::Dir.glob(File.join(staging_path, glob_prefix, "**/perllocal.pod")).each do |path| logger.debug("Removing useless file.", :path => path.gsub(staging_path, "")) File.unlink(path) end end # TODO(sissel): figure out if this perl module compiles anything # and set the architecture appropriately. self.architecture = "all" # Find any shared objects in the staging directory to set architecture as # native if found; otherwise keep the 'all' default. Find.find(staging_path) do |path| if path =~ /\.so$/ logger.info("Found shared library, setting architecture=native", :path => path) self.architecture = "native" end end end def unpack(tarball) directory = build_path("module") ::Dir.mkdir(directory) args = [ "-C", directory, "-zxf", tarball, "--strip-components", "1" ] safesystem("tar", *args) return directory end def download(metadata, cpan_version=nil) distribution = metadata["distribution"] author = metadata["author"] logger.info("Downloading perl module", :distribution => distribution, :version => cpan_version) # default to latest versionunless we specify one if cpan_version.nil? self.version = metadata["version"] else if metadata["version"] =~ /^v\d/ self.version = "v#{cpan_version}" else self.version = cpan_version end end metacpan_release_url = "http://api.metacpan.org/v0/release/#{author}/#{distribution}-#{self.version}" begin release_response = httpfetch(metacpan_release_url) rescue Net::HTTPServerException => e logger.error("metacpan release query failed.", :error => e.message, :module => package, :url => metacpan_release_url) raise FPM::InvalidPackageConfiguration, "metacpan release query failed" end data = release_response.body release_metadata = JSON.parse(data) archive = release_metadata["archive"] # should probably be basepathed from the url tarball = File.basename(archive) url_base = "http://www.cpan.org/" url_base = "#{attributes[:cpan_mirror]}" if !attributes[:cpan_mirror].nil? #url = "http://www.cpan.org/CPAN/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}" url = "#{url_base}/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{archive}" logger.debug("Fetching perl module", :url => url) begin response = httpfetch(url) rescue Net::HTTPServerException => e #logger.error("Download failed", :error => response.status_line, #:url => url) logger.error("Download failed", :error => e, :url => url) raise FPM::InvalidPackageConfiguration, "metacpan query failed" end File.open(build_path(tarball), "w") do |fd| #response.read_body { |c| fd.write(c) } fd.write(response.body) end return build_path(tarball) end # def download def search(package) logger.info("Asking metacpan about a module", :module => package) metacpan_url = "http://api.metacpan.org/v0/module/" + package begin response = httpfetch(metacpan_url) rescue Net::HTTPServerException => e #logger.error("metacpan query failed.", :error => response.status_line, #:module => package, :url => metacpan_url) logger.error("metacpan query failed.", :error => e.message, :module => package, :url => metacpan_url) raise FPM::InvalidPackageConfiguration, "metacpan query failed" end #data = "" #response.read_body { |c| p c; data << c } data = response.body |
︙ | ︙ |
Changes to lib/fpm/package/deb.rb.
︙ | ︙ | |||
182 183 184 185 186 187 188 | # Get the name of this package. See also FPM::Package#name # # This accessor actually modifies the name if it has some invalid or unwise # characters. def name if @name =~ /[A-Z]/ | | | | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | # Get the name of this package. See also FPM::Package#name # # This accessor actually modifies the name if it has some invalid or unwise # characters. def name if @name =~ /[A-Z]/ logger.warn("Debian tools (dpkg/apt) don't do well with packages " \ "that use capital letters in the name. In some cases it will " \ "automatically downcase them, in others it will not. It is confusing." \ " Best to not use any capital letters at all. I have downcased the " \ "package name for you just to be safe.", :oldname => @name, :fixedname => @name.downcase) @name = @name.downcase end if @name.include?("_") logger.info("Debian package names cannot include underscores; " \ "automatically converting to dashes", :name => @name) @name = @name.gsub(/[_]/, "-") end if @name.include?(" ") logger.info("Debian package names cannot include spaces; " \ "automatically converting to dashes", :name => @name) @name = @name.gsub(/[ ]/, "-") end return @name end # def name |
︙ | ︙ | |||
228 229 230 231 232 233 234 | control = File.read(File.join(path, "control")) parse = lambda do |field| value = control[/^#{field.capitalize}: .*/] if value.nil? return nil else | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | control = File.read(File.join(path, "control")) parse = lambda do |field| value = control[/^#{field.capitalize}: .*/] if value.nil? return nil else logger.info("deb field", field => value.split(": ", 2).last) return value.split(": ",2).last end end # Parse 'epoch:version-iteration' in the version string version_re = /^(?:([0-9]+):)?(.+?)(?:-(.*))?$/ m = version_re.match(parse.call("Version")) |
︙ | ︙ | |||
334 335 336 337 338 339 340 | # create 'debian-binary' file, required to make a valid debian package File.write(build_path("debian-binary"), "2.0\n") # If we are given --deb-shlibs but no --after-install script, we # should implicitly create a before/after scripts that run ldconfig if attributes[:deb_shlibs] if !script?(:after_install) | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | # create 'debian-binary' file, required to make a valid debian package File.write(build_path("debian-binary"), "2.0\n") # If we are given --deb-shlibs but no --after-install script, we # should implicitly create a before/after scripts that run ldconfig if attributes[:deb_shlibs] if !script?(:after_install) logger.info("You gave --deb-shlibs but no --after-install, so " \ "I am adding an after-install script that runs " \ "ldconfig to update the system library cache") scripts[:after_install] = template("deb/ldconfig.sh.erb").result(binding) end if !script?(:after_remove) logger.info("You gave --deb-shlibs but no --after-remove, so " \ "I am adding an after-remove script that runs " \ "ldconfig to update the system library cache") scripts[:after_remove] = template("deb/ldconfig.sh.erb").result(binding) end end if script?(:before_upgrade) or script?(:after_upgrade) |
︙ | ︙ | |||
386 387 388 389 390 391 392 | # Write the changelog file dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian.gz") FileUtils.mkdir_p(File.dirname(dest_changelog)) File.new(dest_changelog, "wb", 0644).tap do |changelog| Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz| if attributes[:deb_changelog] | | | | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | # Write the changelog file dest_changelog = File.join(staging_path, "usr/share/doc/#{name}/changelog.Debian.gz") FileUtils.mkdir_p(File.dirname(dest_changelog)) File.new(dest_changelog, "wb", 0644).tap do |changelog| Zlib::GzipWriter.new(changelog, Zlib::BEST_COMPRESSION).tap do |changelog_gz| if attributes[:deb_changelog] logger.info("Writing user-specified changelog", :source => attributes[:deb_changelog]) File.new(attributes[:deb_changelog]).tap do |fd| chunk = nil # Ruby 1.8.7 doesn't have IO#copy_stream changelog_gz.write(chunk) while chunk = fd.read(16384) end.close else logger.info("Creating boilerplate changelog file") changelog_gz.write(template("deb/changelog.erb").result(binding)) end end.close end # No need to close, GzipWriter#close will close it. attributes.fetch(:deb_init_list, []).each do |init| name = File.basename(init, ".init") |
︙ | ︙ | |||
473 474 475 476 477 478 479 | dep = "#{name} (#{debianize_op(op)} #{version})" end end name_re = /^[^ \(]+/ name = dep[name_re] if name =~ /[A-Z]/ | | | | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | dep = "#{name} (#{debianize_op(op)} #{version})" end end name_re = /^[^ \(]+/ name = dep[name_re] if name =~ /[A-Z]/ logger.warn("Downcasing dependency '#{name}' because deb packages " \ " don't work so good with uppercase names") dep = dep.gsub(name_re) { |n| n.downcase } end if dep.include?("_") logger.warn("Replacing dependency underscores with dashes in '#{dep}' because " \ "debs don't like underscores") dep = dep.gsub("_", "-") end # Convert gem ~> X.Y.Z to '>= X.Y.Z' and << X.Y+1.0 if dep =~ /\(~>/ name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1] |
︙ | ︙ | |||
521 522 523 524 525 526 527 | end end # def fix_dependency def fix_provides(provides) name_re = /^[^ \(]+/ name = provides[name_re] if name =~ /[A-Z]/ | | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | end end # def fix_dependency def fix_provides(provides) name_re = /^[^ \(]+/ name = provides[name_re] if name =~ /[A-Z]/ logger.warn("Downcasing provides '#{name}' because deb packages " \ " don't work so good with uppercase names") provides = provides.gsub(name_re) { |n| n.downcase } end if provides.include?("_") logger.warn("Replacing 'provides' underscores with dashes in '#{provides}' because " \ "debs don't like underscores") provides = provides.gsub("_", "-") end return provides.rstrip end def control_path(path=nil) |
︙ | ︙ | |||
558 559 560 561 562 563 564 | write_debconf # write the debconf files write_meta_files # write additional meta files write_triggers # write trigger config to 'triggers' file write_md5sums # write the md5sums file # Make the control.tar.gz with(build_path("control.tar.gz")) do |controltar| | | | | | | | | | | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | write_debconf # write the debconf files write_meta_files # write additional meta files write_triggers # write trigger config to 'triggers' file write_md5sums # write the md5sums file # Make the control.tar.gz with(build_path("control.tar.gz")) do |controltar| logger.info("Creating", :path => controltar, :from => control_path) args = [ tar_cmd, "-C", control_path, "-zcf", controltar, "--owner=0", "--group=0", "--numeric-owner", "." ] safesystem(*args) end logger.debug("Removing no longer needed control dir", :path => control_path) ensure FileUtils.rm_r(control_path) end # def write_control_tarball def write_control # warn user if epoch is set logger.warn("epoch in Version is set", :epoch => self.epoch) if self.epoch # calculate installed-size if necessary: if attributes[:deb_installed_size].nil? logger.info("No deb_installed_size set, calculating now.") total = 0 Find.find(staging_path) do |path| stat = File.lstat(path) next if stat.directory? total += stat.size end # Per http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Installed-Size # "The disk space is given as the integer value of the estimated # installed size in bytes, divided by 1024 and rounded up." attributes[:deb_installed_size] = total / 1024 end # Write the control file with(control_path("control")) do |control| if attributes[:deb_custom_control] logger.debug("Using '#{attributes[:deb_custom_control]}' template for the control file") control_data = File.read(attributes[:deb_custom_control]) else logger.debug("Using 'deb.erb' template for the control file") control_data = template("deb.erb").result(binding) end logger.debug("Writing control file", :path => control) File.write(control, control_data) File.chmod(0644, control) edit_file(control) if attributes[:edit?] end end # def write_control # Write out the maintainer scripts # # SCRIPT_MAP is a map from the package ':after_install' to debian # 'post_install' names def write_scripts SCRIPT_MAP.each do |scriptname, filename| next unless script?(scriptname) with(control_path(filename)) do |controlscript| logger.debug("Writing control script", :source => filename, :target => controlscript) File.write(controlscript, script(scriptname)) # deb maintainer scripts are required to be executable File.chmod(0755, controlscript) end end end # def write_scripts |
︙ | ︙ | |||
658 659 660 661 662 663 664 | end File.chmod(0644, conffiles) end end # def write_conffiles def write_shlibs return unless attributes[:deb_shlibs] | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 | end File.chmod(0644, conffiles) end end # def write_conffiles def write_shlibs return unless attributes[:deb_shlibs] logger.info("Adding shlibs", :content => attributes[:deb_shlibs]) File.open(control_path("shlibs"), "w") do |out| out.write(attributes[:deb_shlibs]) end end # def write_shlibs def write_debconf if attributes[:deb_config] |
︙ | ︙ |
Changes to lib/fpm/package/dir.rb.
︙ | ︙ | |||
60 61 62 63 64 65 66 | if attributes[:prefix] destination = File.join(attributes[:prefix], destination) end destination = File.join(staging_path, destination) | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | if attributes[:prefix] destination = File.join(attributes[:prefix], destination) end destination = File.join(staging_path, destination) logger["method"] = "input" begin ::Dir.chdir(chdir) do begin clone(source, destination) rescue Errno::ENOENT => e raise FPM::InvalidPackageConfiguration, "Cannot package the path '#{File.join(chdir, source)}', does it exist?" |
︙ | ︙ | |||
83 84 85 86 87 88 89 | # can include license data from themselves (rpms, gems, etc), # but to make sure a simple dir -> rpm works without having # to specify a license. self.license = "unknown" self.vendor = [ENV["USER"], Socket.gethostname].join("@") ensure # Clean up any logger context we added. | | | | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # can include license data from themselves (rpms, gems, etc), # but to make sure a simple dir -> rpm works without having # to specify a license. self.license = "unknown" self.vendor = [ENV["USER"], Socket.gethostname].join("@") ensure # Clean up any logger context we added. logger.remove("method") end # def input # Output this package to the given directory. def output(output_path) output_check(output_path) output_path = File.expand_path(output_path) ::Dir.chdir(staging_path) do logger["method"] = "output" clone(".", output_path) end ensure logger.remove("method") end # def output private # Copy a file or directory to a destination # # This is special because it respects the full path of the source. # Aditionally, hardlinks will be used instead of copies. # # Example: # # clone("/tmp/hello/world", "/tmp/example") # # The above will copy, recursively, /tmp/hello/world into # /tmp/example/hello/world def clone(source, destination) logger.debug("Cloning path", :source => source, :destination => destination) # Edge case check; abort if the temporary directory is the source. # If the temporary dir is the same path as the source, it causes # fpm to recursively (and forever) copy the staging directory by # accident (#542). if File.expand_path(source) == File.expand_path(::Dir.tmpdir) raise FPM::InvalidPackageConfiguration, "A source directory cannot be the root of your temporary " \ |
︙ | ︙ | |||
151 152 153 154 155 156 157 | end # def clone # Copy a path. # # Files will be hardlinked if possible, but copied otherwise. # Symlinks should be copied as symlinks. def copy(source, destination) | | | | | | | | 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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | end # def clone # Copy a path. # # Files will be hardlinked if possible, but copied otherwise. # Symlinks should be copied as symlinks. def copy(source, destination) logger.debug("Copying path", :source => source, :destination => destination) directory = File.dirname(destination) if !File.directory?(directory) FileUtils.mkdir_p(directory) end if File.directory?(source) if !File.symlink?(source) # Create a directory if this path is a directory logger.debug("Creating", :directory => destination) if !File.directory?(destination) FileUtils.mkdir(destination) end else # Linking symlinked directories causes a hardlink to be created, which # results in the source directory being wiped out during cleanup, # so copy the symlink. logger.debug("Copying symlinked directory", :source => source, :destination => destination) FileUtils.copy_entry(source, destination) end else # Otherwise try copying the file. begin logger.debug("Linking", :source => source, :destination => destination) File.link(source, destination) rescue Errno::ENOENT, Errno::EXDEV, Errno::EPERM # Hardlink attempt failed, copy it instead logger.debug("Copying", :source => source, :destination => destination) copy_entry(source, destination) rescue Errno::EEXIST sane_path = destination.gsub(staging_path, "") logger.error("Cannot copy file, the destination path is probably a directory and I attempted to write a file.", :path => sane_path, :staging => staging_path) end end copy_metadata(source, destination) end # def copy def copy_metadata(source, destination) |
︙ | ︙ |
Changes to lib/fpm/package/gem.rb.
︙ | ︙ | |||
58 59 60 61 62 63 64 | def download_if_necessary(gem, gem_version) path = gem if !File.exists?(path) path = download(gem, gem_version) end | | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | def download_if_necessary(gem, gem_version) path = gem if !File.exists?(path) path = download(gem, gem_version) end logger.info("Using gem file", :path => path) return path end # def download_if_necessary def download(gem_name, gem_version=nil) logger.info("Trying to download", :gem => gem_name, :version => gem_version) gem_fetch = [ "#{attributes[:gem_gem]}", "fetch", gem_name] gem_fetch += ["--prerelease"] if attributes[:gem_prerelease?] gem_fetch += ["--version", gem_version] if gem_version download_dir = build_path(gem_name) FileUtils.mkdir(download_dir) unless File.directory?(download_dir) ::Dir.chdir(download_dir) do |dir| logger.debug("Downloading in directory #{dir}") safesystem(*gem_fetch) end gem_files = ::Dir.glob(File.join(download_dir, "*.gem")) if gem_files.length != 1 raise "Unexpected number of gem files in #{download_dir}, #{gem_files.length} should be 1" |
︙ | ︙ | |||
199 200 201 202 203 204 205 | # Delete bin_path if it's empty, and any empty parents (#612) # Above, we mkdir_p bin_path because rubygems aborts if the parent # directory doesn't exist, for example: # ERROR: While executing gem ... (Errno::ENOENT) # No such file or directory - /tmp/something/weird/bin tmp = bin_path while ::Dir.entries(tmp).size == 2 || tmp == "/" # just [ "..", "." ] is an empty directory | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | # Delete bin_path if it's empty, and any empty parents (#612) # Above, we mkdir_p bin_path because rubygems aborts if the parent # directory doesn't exist, for example: # ERROR: While executing gem ... (Errno::ENOENT) # No such file or directory - /tmp/something/weird/bin tmp = bin_path while ::Dir.entries(tmp).size == 2 || tmp == "/" # just [ "..", "." ] is an empty directory logger.info("Deleting empty bin_path", :path => tmp) ::Dir.rmdir(tmp) tmp = File.dirname(tmp) end if attributes[:gem_version_bins?] and File.directory?(bin_path) (::Dir.entries(bin_path) - ['.','..']).each do |bin| FileUtils.mv("#{bin_path}/#{bin}", "#{bin_path}/#{bin}-#{self.version}") end |
︙ | ︙ |
Changes to lib/fpm/package/osxpkg.rb.
︙ | ︙ | |||
78 79 80 81 82 83 84 | end # def scripts_path def write_scripts SCRIPT_MAP.each do |scriptname, filename| next unless script?(scriptname) with(scripts_path(filename)) do |pkgscript| | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | end # def scripts_path def write_scripts SCRIPT_MAP.each do |scriptname, filename| next unless script?(scriptname) with(scripts_path(filename)) do |pkgscript| logger.info("Writing pkg script", :source => filename, :target => pkgscript) File.write(pkgscript, script(scriptname)) # scripts are required to be executable File.chmod(0755, pkgscript) end end end # def write_scripts |
︙ | ︙ | |||
106 107 108 109 110 111 112 | with(build_path("expand")) do |path| doc = REXML::Document.new File.open(File.join(path, "PackageInfo")) pkginfo_elem = doc.elements["pkg-info"] identifier = pkginfo_elem.attribute("identifier").value self.version = pkginfo_elem.attribute("version").value # set name to the last dot element of the identifier self.name = identifier.split(".").last | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | with(build_path("expand")) do |path| doc = REXML::Document.new File.open(File.join(path, "PackageInfo")) pkginfo_elem = doc.elements["pkg-info"] identifier = pkginfo_elem.attribute("identifier").value self.version = pkginfo_elem.attribute("version").value # set name to the last dot element of the identifier self.name = identifier.split(".").last logger.info("inferring name #{self.name} from pkg-id #{identifier}") end end # def extract_info # Take a flat package as input def input(input_path) # TODO: Fail if it's a Distribution pkg or old-fashioned expand_dir = File.join(build_path, "expand") |
︙ | ︙ |
Changes to lib/fpm/package/pear.rb.
︙ | ︙ | |||
37 38 39 40 41 42 43 | # * :pear_package_name_prefix - changes the def input(input_package) if !program_in_path?("pear") raise ExecutableNotFound.new("pear") end # Create a temporary config file | | | | | | | | | | | | | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | # * :pear_package_name_prefix - changes the def input(input_package) if !program_in_path?("pear") raise ExecutableNotFound.new("pear") end # Create a temporary config file logger.debug("Creating pear config file") config = File.expand_path(build_path("pear.config")) installroot = attributes[:prefix] || "/usr/share" safesystem("pear", "config-create", staging_path(installroot), config) if attributes[:pear_php_dir] logger.info("Setting php_dir", :php_dir => attributes[:pear_php_dir]) safesystem("pear", "-c", config, "config-set", "php_dir", "#{staging_path(installroot)}/#{attributes[:pear_php_dir]}") end if attributes[:pear_data_dir] logger.info("Setting data_dir", :data_dir => attributes[:pear_data_dir]) safesystem("pear", "-c", config, "config-set", "data_dir", "#{staging_path(installroot)}/#{attributes[:pear_data_dir]}") end bin_dir = attributes[:pear_bin_dir] || "usr/bin" logger.info("Setting bin_dir", :bin_dir => bin_dir) safesystem("pear", "-c", config, "config-set", "bin_dir", bin_dir) php_bin = attributes[:pear_php_bin] || "/usr/bin/php" logger.info("Setting php_bin", :php_bin => php_bin) safesystem("pear", "-c", config, "config-set", "php_bin", php_bin) # do channel-discover if required if !attributes[:pear_channel].nil? logger.info("Custom channel specified", :channel => attributes[:pear_channel]) channel_list = safesystemout("pear", "-c", config, "list-channels") if channel_list !~ /#{Regexp.quote(attributes[:pear_channel])}/ logger.info("Discovering new channel", :channel => attributes[:pear_channel]) safesystem("pear", "-c", config, "channel-discover", attributes[:pear_channel]) end input_package = "#{attributes[:pear_channel]}/#{input_package}" logger.info("Prefixing package name with channel", :package => input_package) end # do channel-update if requested if attributes[:pear_channel_update?] channel = attributes[:pear_channel] || "pear" logger.info("Updating the channel", :channel => channel) safesystem("pear", "-c", config, "channel-update", channel) end logger.info("Installing pear package", :package => input_package, :directory => staging_path) ::Dir.chdir(staging_path) do safesystem("pear", "-c", config, "install", "-n", "-f", input_package) end pear_cmd = "pear -c #{config} remote-info #{input_package}" logger.info("Fetching package information", :package => input_package, :command => pear_cmd) name = %x{#{pear_cmd} | sed -ne '/^Package\s*/s/^Package\s*//p'}.chomp self.name = "#{attributes[:pear_package_name_prefix]}-#{name}" self.version = %x{#{pear_cmd} | sed -ne '/^Installed\s*/s/^Installed\s*//p'}.chomp self.description = %x{#{pear_cmd} | sed -ne '/^Summary\s*/s/^Summary\s*//p'}.chomp logger.debug("Package info", :name => self.name, :version => self.version, :description => self.description) # Remove the stuff we don't want delete_these = [".depdb", ".depdblock", ".filemap", ".lock", ".channel", "cache", "temp", "download", ".channels", ".registry"] Find.find(staging_path) do |path| if File.file?(path) logger.info("replacing staging_path in file", :replace_in => path, :staging_path => staging_path) begin content = File.read(path).gsub(/#{Regexp.escape(staging_path)}/, "") File.write(path, content) rescue ArgumentError => e logger.warn("error replacing staging_path in file", :replace_in => path, :error => e) end end FileUtils.rm_r(path) if delete_these.include?(File.basename(path)) end end # def input end # class FPM::Package::PEAR |
Changes to lib/fpm/package/puppet.rb.
︙ | ︙ | |||
14 15 16 17 18 19 20 | return @architecture end # def architecture # Default specfile generator just makes one specfile, whatever that is for # this package. def generate_specfile(builddir) paths = [] | | | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | return @architecture end # def architecture # Default specfile generator just makes one specfile, whatever that is for # this package. def generate_specfile(builddir) paths = [] logger.info("PWD: #{File.join(builddir, unpack_data_to)}") fileroot = File.join(builddir, unpack_data_to) Dir.chdir(fileroot) do Find.find(".") do |p| next if p == "." paths << p end end logger.info(paths[-1]) manifests = %w{package.pp package/remove.pp} ::Dir.mkdir(File.join(builddir, "manifests")) manifests.each do |manifest| dir = File.join(builddir, "manifests", File.dirname(manifest)) logger.info("manifests targeting: #{dir}") ::Dir.mkdir(dir) if !File.directory?(dir) File.open(File.join(builddir, "manifests", manifest), "w") do |f| logger.info("manifest: #{f.path}") template = template(File.join("puppet", "#{manifest}.erb")) ::Dir.chdir(fileroot) do f.puts template.result(binding) end end end end # def generate_specfile |
︙ | ︙ | |||
58 59 60 61 62 63 64 | when "pre-uninstall" when "post-uninstall" end # case name end # self.scripts.each if File.exists?(params[:output]) # TODO(sissel): Allow folks to choose output? | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | when "pre-uninstall" when "post-uninstall" end # case name end # self.scripts.each if File.exists?(params[:output]) # TODO(sissel): Allow folks to choose output? logger.error("Puppet module directory '#{params[:output]}' already " \ "exists. Delete it or choose another output (-p flag)") end ::Dir.mkdir(params[:output]) builddir = ::Dir.pwd # Copy 'files' from builddir to :output/files Find.find("files", "manifests") do |path| logger.info("Copying path: #{path}") if File.directory?(path) ::Dir.mkdir(File.join(params[:output], path)) else FileUtils.cp(path, File.join(params[:output], path)) end end end # def build! |
︙ | ︙ | |||
96 97 98 99 100 101 102 | # Helper for user lookup def uid2user(uid) begin pwent = Etc.getpwuid(uid) return pwent.name rescue ArgumentError => e # Invalid user id? No user? Return the uid. | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | # Helper for user lookup def uid2user(uid) begin pwent = Etc.getpwuid(uid) return pwent.name rescue ArgumentError => e # Invalid user id? No user? Return the uid. logger.warn("Failed to find username for uid #{uid}") return uid.to_s end end # def uid2user # Helper for group lookup def gid2group(gid) begin grent = Etc.getgrgid(gid) return grent.name rescue ArgumentError => e # Invalid user id? No user? Return the uid. logger.warn("Failed to find group for gid #{gid}") return gid.to_s end end # def uid2user end # class FPM::Target::Puppet |
Changes to lib/fpm/package/python.rb.
︙ | ︙ | |||
28 29 30 31 32 33 34 | "is used instead", :default => nil option "--pypi", "PYPI_URL", "PyPi Server uri for retrieving packages.", :default => "http://pypi.python.org/simple" option "--package-prefix", "NAMEPREFIX", "(DEPRECATED, use --package-name-prefix) Name to prefix the package " \ "name with." do |value| | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | "is used instead", :default => nil option "--pypi", "PYPI_URL", "PyPi Server uri for retrieving packages.", :default => "http://pypi.python.org/simple" option "--package-prefix", "NAMEPREFIX", "(DEPRECATED, use --package-name-prefix) Name to prefix the package " \ "name with." do |value| logger.warn("Using deprecated flag: --package-prefix. Please use " \ "--package-name-prefix") value end option "--package-name-prefix", "PREFIX", "Name to prefix the package " \ "name with.", :default => "python" option "--fix-name", :flag, "Should the target package name be prefixed?", :default => true |
︙ | ︙ | |||
85 86 87 88 89 90 91 | if File.directory?(path_to_package) setup_py = File.join(path_to_package, "setup.py") else setup_py = path_to_package end if !File.exists?(setup_py) | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | if File.directory?(path_to_package) setup_py = File.join(path_to_package, "setup.py") else setup_py = path_to_package end if !File.exists?(setup_py) logger.error("Could not find 'setup.py'", :path => setup_py) raise "Unable to find python package; tried #{setup_py}" end load_package_info(setup_py) install_to_staging(setup_py) end # def input # Download the given package if necessary. If version is given, that version # will be downloaded, otherwise the latest is fetched. def download_if_necessary(package, version=nil) # TODO(sissel): this should just be a 'download' method, the 'if_necessary' # part should go elsewhere. path = package # If it's a path, assume local build. if File.directory?(path) or (File.exists?(path) and File.basename(path) == "setup.py") return path end logger.info("Trying to download", :package => package) if version.nil? want_pkg = "#{package}" else want_pkg = "#{package}==#{version}" end target = build_path(package) FileUtils.mkdir(target) unless File.directory?(target) if attributes[:python_pip].nil? # no pip, use easy_install logger.debug("no pip, defaulting to easy_install", :easy_install => attributes[:python_easyinstall]) safesystem(attributes[:python_easyinstall], "-i", attributes[:python_pypi], "--editable", "-U", "--build-directory", target, want_pkg) else logger.debug("using pip", :pip => attributes[:python_pip]) safesystem(attributes[:python_pip], "install", "--no-deps", "--no-install", "-i", attributes[:python_pypi], "-U", "--build", target, want_pkg) end # easy_install will put stuff in @tmpdir/packagename/, so find that: # @tmpdir/somepackage/setup.py dirs = ::Dir.glob(File.join(target, "*")) if dirs.length != 1 |
︙ | ︙ | |||
150 151 152 153 154 155 156 | "try:", " import json", "except ImportError:", " import simplejson as json" ].join("\n") safesystem("#{attributes[:python_bin]} -c '#{json_test_code}'") rescue FPM::Util::ProcessFailed => e | | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | "try:", " import json", "except ImportError:", " import simplejson as json" ].join("\n") safesystem("#{attributes[:python_bin]} -c '#{json_test_code}'") rescue FPM::Util::ProcessFailed => e logger.error("Your python environment is missing json support (either json or simplejson python module). I cannot continue without this.", :python => attributes[:python_bin], :error => e) raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing simplejson or json modules." end begin safesystem("#{attributes[:python_bin]} -c 'import pkg_resources'") rescue FPM::Util::ProcessFailed => e logger.error("Your python environment is missing a working setuptools module. I tried to find the 'pkg_resources' module but failed.", :python => attributes[:python_bin], :error => e) raise FPM::Util::ProcessFailed, "Python (#{attributes[:python_bin]}) is missing pkg_resources module." end # Add ./pyfpm/ to the python library path pylib = File.expand_path(File.dirname(__FILE__)) # chdir to the directory holding setup.py because some python setup.py's assume that you are |
︙ | ︙ | |||
180 181 182 183 184 185 186 | if attributes[:python_obey_requirements_txt?] setup_cmd += " --load-requirements-txt" end # Capture the output, which will be JSON metadata describing this python # package. See fpm/lib/fpm/package/pyfpm/get_metadata.py for more # details. | | | | | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | if attributes[:python_obey_requirements_txt?] setup_cmd += " --load-requirements-txt" end # Capture the output, which will be JSON metadata describing this python # package. See fpm/lib/fpm/package/pyfpm/get_metadata.py for more # details. logger.info("fetching package metadata", :setup_cmd => setup_cmd) success = safesystem(setup_cmd) #%x{#{setup_cmd}} if !success logger.error("setup.py get_metadata failed", :command => setup_cmd, :exitcode => $?.exitstatus) raise "An unexpected error occurred while processing the setup.py file" end File.read(tmp) end logger.debug("result from `setup.py get_metadata`", :data => output) metadata = JSON.parse(output) logger.info("object output of get_metadata", :json => metadata) self.architecture = metadata["architecture"] self.description = metadata["description"] # Sometimes the license field is multiple lines; do best-effort and just # use the first line. self.license = metadata["license"].split(/[\r\n]+/).first self.version = metadata["version"] |
︙ | ︙ | |||
219 220 221 222 223 224 225 | self.name = self.name.downcase if attributes[:python_downcase_name?] if !attributes[:no_auto_depends?] and attributes[:python_dependencies?] self.dependencies = metadata["dependencies"].collect do |dep| dep_re = /^([^<>!= ]+)\s*(?:([<>!=]{1,2})\s*(.*))?$/ match = dep_re.match(dep) if match.nil? | | | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | self.name = self.name.downcase if attributes[:python_downcase_name?] if !attributes[:no_auto_depends?] and attributes[:python_dependencies?] self.dependencies = metadata["dependencies"].collect do |dep| dep_re = /^([^<>!= ]+)\s*(?:([<>!=]{1,2})\s*(.*))?$/ match = dep_re.match(dep) if match.nil? logger.error("Unable to parse dependency", :dependency => dep) raise FPM::InvalidPackageConfiguration, "Invalid dependency '#{dep}'" end name, cmp, version = match.captures # convert == to = if cmp == "==" logger.info("Converting == dependency requirement to =", :dependency => dep ) cmp = "=" end # dependency name prefixing is optional, if enabled, a name 'foo' will # become 'python-foo' (depending on what the python_package_name_prefix # is) name = fix_name(name) if attributes[:python_fix_dependencies?] |
︙ | ︙ |
Changes to lib/fpm/package/rpm.rb.
︙ | ︙ | |||
253 254 255 256 257 258 259 | if self.attributes[:rpm_ignore_iteration_in_dependencies?] self.dependencies = self.dependencies.collect do |dep| name, op, version = dep.split(/\s+/) if op == '=' nextversion = version.split('.').collect { |v| v.to_i } nextversion[-1] += 1 nextversion = nextversion.join(".") | | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | if self.attributes[:rpm_ignore_iteration_in_dependencies?] self.dependencies = self.dependencies.collect do |dep| name, op, version = dep.split(/\s+/) if op == '=' nextversion = version.split('.').collect { |v| v.to_i } nextversion[-1] += 1 nextversion = nextversion.join(".") logger.warn("Converting dependency #{dep} to #{name} >= #{version}, #{name} < #{nextversion}") ["#{name} >= #{version}", "#{name} < #{nextversion}"] else dep end end.flatten end setscript = proc do |scriptname| script_path = self.attributes[scriptname] # Skip scripts not set next if script_path.nil? if !File.exists?(script_path) logger.error("No such file (for #{scriptname.to_s}): #{script_path.inspect}") script_errors << script_path end # Load the script into memory. scripts[scriptname] = File.read(script_path) end setscript.call(:rpm_verifyscript) |
︙ | ︙ | |||
430 431 432 433 434 435 436 | specfile = File.join(build_path("SPECS"), "#{name}.spec") File.write(specfile, rpmspec) edit_file(specfile) if attributes[:edit?] args << specfile | | | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | specfile = File.join(build_path("SPECS"), "#{name}.spec") File.write(specfile, rpmspec) edit_file(specfile) if attributes[:edit?] args << specfile logger.info("Running rpmbuild", :args => args) safesystem(*args) ::Dir["#{build_path}/RPMS/**/*.rpm"].each do |rpmpath| # This should only output one rpm, should we verify this? FileUtils.cp(rpmpath, output_path) end end # def output def prefix return (attributes[:prefix] or "/") end # def prefix def build_sub_dir return "BUILD" #return File.join("BUILD", prefix) end # def build_sub_dir def version if @version.kind_of?(String) and @version.include?("-") logger.warn("Package version '#{@version}' includes dashes, converting" \ " to underscores") @version = @version.gsub(/-/, "_") end return @version end # The default epoch value must be nil, see #381 def epoch return @epoch if @epoch.is_a?(Numeric) if @epoch.nil? or @epoch.empty? logger.warn("no value for epoch is set, defaulting to nil") return nil end return @epoch end # def epoch def to_s(format=nil) |
︙ | ︙ |
Changes to lib/fpm/package/sh.rb.
︙ | ︙ | |||
42 43 44 45 46 47 48 | end path end # Returns the path to the tar file containing the packed up staging directory def payload payload_tar = build_path("payload.tar") | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | end path end # Returns the path to the tar file containing the packed up staging directory def payload payload_tar = build_path("payload.tar") logger.info("Creating payload tar ", :path => payload_tar) args = [ tar_cmd, "-C", staging_path, "-cf", payload_tar, "--owner=0", |
︙ | ︙ |
Changes to spec/fpm/util_spec.rb.
1 2 3 4 5 6 7 8 9 10 | require "spec_setup" require "fpm" # local require "fpm/util" # local require "stud/temporary" describe FPM::Util do subject do Class.new do include FPM::Util | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | require "spec_setup" require "fpm" # local require "fpm/util" # local require "stud/temporary" describe FPM::Util do subject do Class.new do include FPM::Util end.new end context "#copy_entry" do context "when given files that are hardlinks" do it "should keep those files as hardlinks" do Stud::Temporary.directory do |path| |
︙ | ︙ |