Skip to content
This repository has been archived by the owner on Jan 16, 2025. It is now read-only.

Patch improvements: DSL, checksums, caching #22775

Closed
wants to merge 4 commits into from
Closed

Patch improvements: DSL, checksums, caching #22775

wants to merge 4 commits into from

Conversation

jacknagel
Copy link
Contributor

This implements a new patch DSL along with support for checksums and caching.

Here is what the DSL looks like so far. I'm not married to it, so please make suggestions. In particular, I don't find patch :p0 do aesthetically pleasing. However I don't want to push everything into one method call (i.e., patch :p0, 'url', 'checksum') because the lines get too long.

# p1 is assumed, otherwise pass a symbol argument
patch do
  url '...'
  sha1 '...'
end

patch :p0 do
  url '...'
  sha1 '...'
end

# patches can go in the stable, devel, and head blocks
# as well, rather than using conditionals
stable do
  # ...

  patch do
    url '...'
    sha1 '...'
  end
end

# embedded patches (__END__)
# note: we use :DATA because we can only use the
# actual DATA constant properly in the build script 
patch :DATA
patch :p0, :DATA

# embed a patch without using __END__
# this means it is now possible to have multiple embedded
# patches, and make only some of them conditional
patch :p0, %q{
--- src/main.c  2012-06-30 12:22:29.000000000 +0200
+++ src/main.c  2012-06-30 12:19:11.000000000 +0200
@@ -25,6 +25,7 @@

 #include <time.h>
 #include <sys/stat.h>
+#include <netinet/udp.h>
 #include <pwd.h>
 #include <grp.h>
 #include "queue.h"
}
  • Defining a patches method still works, but these patches are not cached (as they lack checksums).
  • External patches are implemented using Resources, so instead of everything being downloaded up front, patches are downloaded and applied one at a time. The way resources are coupled to their download strategies makes it impossible to preserve the old behavior and use the existing caching/checksum machinery. I don't think this is a problem, because they are cached, but it is different.

@@ -210,7 +213,7 @@ def options; [] end
# }
# The final option is to return DATA, then put a diff after __END__. You
# can still return a Hash with DATA as the value for a patch level key.
def patches; end
def patches; {} end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this is changed from returning nil by default to {}, but there may be formulae that override and end up returning nil anyway. Is that still handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, I put it on my list.

@MikeMcQuaid
Copy link
Member

This looks very good to me. Just to be super-explicit: fetch will now download external patches with checksums now, yeh?

@jacknagel
Copy link
Contributor Author

Yep.

@MikeMcQuaid
Copy link
Member

Very cool.

@jacknagel
Copy link
Contributor Author

Going through existing patches, some thoughts:

  • Most embedded patches are applied at -p1, because this is our default, and we control the embedded patches.
  • Most external patches are from macports, and most of them are applied with -p0.

Perhaps the default for embedded patches should remain -p1, but for external patches it should be -p0, to reduce the number of places we need to specify the strip level?

@adamv
Copy link
Contributor

adamv commented Sep 25, 2013

Another question: git diffs are -p1 by default, right?

@jacknagel
Copy link
Contributor Author

Yeah, that's another (and maybe the primary) reason most embedded patches are -p1.

@jacknagel
Copy link
Contributor Author

We could automatically use -p0 for MacPorts URLs, while still allowing an explicit argument to override it.

@MikeMcQuaid
Copy link
Member

I'd make it explicit for external except maybe MacPorts (if you think that wouldn't be confusing).

@jacknagel
Copy link
Contributor Author

I'm leaning towards punting on adding any magic at this point. We can always re-evaluate and make some stuff implicit later, but we can't undo it (breaking compat) if it turns out to be a bad idea.

@MikeMcQuaid
Copy link
Member

Sounds good.

@jacknagel
Copy link
Contributor Author

Updated a few formulae to serve as examples. I'm not planning to do a bunch of them at once, though, since it requires a bit more work than the dependency updates. We can do them a handful at a time when people get a chance.

@jacknagel
Copy link
Contributor Author

Anyone have any further comments on the DSL?

@MikeMcQuaid
Copy link
Member

Looks good to me. Might be nice if there was a way to do multiple patches in a block that remained readable.

@jacknagel
Copy link
Contributor Author

I cleaned up the flow a bit. Now all patches are fetched and checksummed before any are applied, which matches the current behavior.

@MikeMcQuaid
Copy link
Member

Looks good to me.

@manphiz
Copy link
Contributor

manphiz commented Nov 1, 2013

+1.

Also something not related to this PR but will be helpful is to introduce some other routine like post_resource_download that is evaluated before patches for unpacking resources, so that patches can be applied to other resources as well. See homebrew/versions/llvm33 for an ugly example.

@MikeMcQuaid
Copy link
Member

Another thing while we're talking about patches is that it would be useful to support Git's binary patches.

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, "..."
@jacknagel
Copy link
Contributor Author

@Homebrew/owners anybody want to review this again? Nothing has really changed, I just rebased it, so I think it's ready.

I have a separate branch with some updated formulae, I don't want to kill the build bot though.

@adamv
Copy link
Contributor

adamv commented Mar 12, 2014

I'll try to take a look tonight.

else
{}
end.each_pair do |strip, urls|
urls = [urls] unless Array === urls
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this preferential to urls = urls.to_a?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, in this case urls can be a string (think { :p1 => "https://..." })

@MikeMcQuaid
Copy link
Member

Looks good to me.

@adamv
Copy link
Contributor

adamv commented Mar 13, 2014

Looks fine here.

@jacknagel
Copy link
Contributor Author

Merged. I updated the example formula, and I'll update the wiki soon.

@jacknagel jacknagel closed this Mar 14, 2014
@jacknagel jacknagel deleted the patches branch March 14, 2014 02:42
@Homebrew Homebrew locked and limited conversation to collaborators Feb 17, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants