diff options
| author | Jack Nagel | 2014-03-13 19:51:23 -0500 | 
|---|---|---|
| committer | Jack Nagel | 2014-03-13 21:35:41 -0500 | 
| commit | bc6e4a189491f0e3f911b879efec3e570029dd8e (patch) | |
| tree | 3a37c4f0a4575d6f1986f5b182e904f59f3255ff /Library/Homebrew/patch.rb | |
| parent | f36e676bc9e93c4c10d14b3e10e9e2f72bfb25db (diff) | |
| download | brew-bc6e4a189491f0e3f911b879efec3e570029dd8e.tar.bz2 | |
New patch implementation and DSL
This commit introduces a new patch implementation that supports
checksums and caching.
Patches are declared in blocks:
  patch do
    url ...
    sha1 ...
  end
A strip level of -p1 is assumed. It can be overridden using a symbol
argument:
  patch :p0 do
    url ...
    sha1 ...
  end
Patches can be declared in stable, devel, and head blocks. This form is
preferred over using conditionals.
  stable do
    # ...
    patch do
      url ...
      sha1 ...
    end
  end
Embedded (__END__) patches are declared like so:
  patch :DATA
  patch :p0, :DATA
Patches can also be embedded by passing a string. This makes it possible
to provide multiple embedded patches while making only some of them
conditional.
  patch :p0, "..."
Diffstat (limited to 'Library/Homebrew/patch.rb')
| -rw-r--r-- | Library/Homebrew/patch.rb | 82 | 
1 files changed, 82 insertions, 0 deletions
| diff --git a/Library/Homebrew/patch.rb b/Library/Homebrew/patch.rb new file mode 100644 index 000000000..a4616eee6 --- /dev/null +++ b/Library/Homebrew/patch.rb @@ -0,0 +1,82 @@ +require 'resource' +require 'stringio' + +class Patch +  def self.create(strip, io=nil, &block) +    case strip ||= :p1 +    when :DATA, IO, StringIO +      IOPatch.new(strip, :p1) +    when String +      IOPatch.new(StringIO.new(strip), :p1) +    when Symbol +      case io +      when :DATA, IO, StringIO +        IOPatch.new(io, strip) +      when String +        IOPatch.new(StringIO.new(io), strip) +      else +        ExternalPatch.new(strip, &block) +      end +    else +      raise ArgumentError, "unexpected value #{strip.inspect} for strip" +    end +  end + +  attr_reader :whence + +  def external? +    whence == :resource +  end +end + +class IOPatch < Patch +  attr_writer :owner +  attr_reader :strip + +  def initialize(io, strip) +    @io     = io +    @strip  = strip +    @whence = :io +  end + +  def apply +    @io = DATA if @io == :DATA +    data = @io.read +    data.gsub!("HOMEBREW_PREFIX", HOMEBREW_PREFIX) +    IO.popen("/usr/bin/patch -g 0 -f -#{strip}", "w") { |p| p.write(data) } +    raise ErrorDuringExecution, "Applying DATA patch failed" unless $?.success? +  ensure +    # IO and StringIO cannot be marshaled, so remove the reference +    # in case we are indirectly referenced by an exception later. +    @io = nil +  end +end + +class ExternalPatch < Patch +  attr_reader :resource, :strip + +  def initialize(strip, &block) +    @strip    = strip +    @resource = Resource.new(&block) +    @whence   = :resource +  end + +  def url +    resource.url +  end + +  def owner= owner +    resource.owner   = owner +    resource.name    = "patch-#{resource.checksum}" +    resource.version = owner.version +  end + +  def apply +    dir = Pathname.pwd +    resource.unpack do +      # Assumption: the only file in the staging directory is the patch +      patchfile = Pathname.pwd.children.first +      safe_system "/usr/bin/patch", "-g", "0", "-f", "-d", dir, "-#{strip}", "-i", patchfile +    end +  end +end | 
