FS#15051 - [code included] makepkg: update md5sums directly in PKGBUILD
Attached to Project:
Pacman
Opened by Tomas Mudrunka (harvie) - Thursday, 11 June 2009, 03:30 GMT
Last edited by Allan McRae (Allan) - Wednesday, 16 June 2010, 07:01 GMT
Opened by Tomas Mudrunka (harvie) - Thursday, 11 June 2009, 03:30 GMT
Last edited by Allan McRae (Allan) - Wednesday, 16 June 2010, 07:01 GMT
|
Details
Summary and Info:
there is makepkg -g option that will produce array of checksums that can be used in PKGBUILD, but why not update PKGBUILD directly? maybe i can add "source md5sums" line to my PKGBUILD and ship it with file created by "makepkg -g > md5sums", but i think that there can be some more simple way (makepkg -G). i think that this can be done using available "makepkg -g 2>/dev/null" feature and bit of sed+regexp magic. i'll try to find some solution and post the code to the comments (if i'll manage to write that) this is my simple implementation which works for me: update_hashes() { sed -ne '1h;1!H;${;g;s/md5sums=([^)]*)/'$(makepkg -p "$1" -g 2>/dev/null)'/g;p;}' "$1" > "$1.new" #maybe this code should be changed to replace only first occurence of md5sums array... mv -f "$1" "$1.bak" mv -f "$1.new" "$1" } update_hashes PKGBUILD; there can be also some easy way to update checksums when packing source packages like: "makepkg --source -g" any other ideas? |
This task depends upon
Closed by Allan McRae (Allan)
Wednesday, 16 June 2010, 07:01 GMT
Reason for closing: Won't implement
Additional comments about closing: Best implemented outside of makepkg. Feel free to submit a script for pacman-contrib
Wednesday, 16 June 2010, 07:01 GMT
Reason for closing: Won't implement
Additional comments about closing: Best implemented outside of makepkg. Feel free to submit a script for pacman-contrib
and they should be replaced by preffered alghoritm (corresponding to makepkg settings - archlinux guidelines)
update_hashes() {
#sed -ne '1h;1!H;${;g;s/md5sums=([^)]*)/'$(makepkg -p "$1" -g 2>/dev/null)'/g;p;}' "$1" > "$1.new"
sed -ne '1h;1!H;${;g;s/\(md5\|sha\|sha1\|sha224\|sha256\|sha384\|sha512\)sums=([^)]*)/'$(makepkg -p "$1" -g 2>/dev/null)'/1;p;}' "$1" > "$1.new"
mv -f "$1" "$1.bak"
mv -f "$1.new" "$1"
}
update_hashes PKGBUILD;
Now as for the implementation. A couple of things I think could be improved. First, a PKGBUILD can specify multiple hashes which with the above would result in multiple copies of whatever is generated by "makepkg -g". So each hash should be updated separately. That also means not using the "makepkg -g" output but having to generate it.
{ rm PKGBUILD; awk '$0 ~ /^md5sums/ {i = 1; system("makepkg -g 2>/dev/null")}; !i {print}; $0 ~ /\)/ {i = 0}' > PKGBUILD; } < PKGBUILD
People might have a .bak or .new that they actually want.
Though it does not address allan's comment either (each hash should be updated separately).
I think both makepkg -g and makepkg -G should look at the hashsums defined in the PKGBUILD and use that.
Surprisingly I still have that old patch, and a quick look at it again reveals a good number of bad assumptions and flaws =/ But if someone can provide a _failsafe_ awk/sed/perl one-liner to restrict the focus between n sets of /^${integ}sums=('/,/')/ then it will work flawlessly. Once that's taken care of, whatever ${integ}s are used in the current buildscript can be generated separately and safely injected one by one.
If it takes more than that to get it working, we should forget about implementing this.
# ~/.bashrc
# will not work on sums at bottom of pkgbuild each on a newline
mkpk() {
sed -i '/^md5sums=([^)]*)/d' PKGBUILD && makepkg -g >> PKGBUILD && makepkg
}
And you don't even need this if all you're doing is installing for yourself, and not distributing (eg. uploading to AUR). makepkg simply takes the last set it finds.
Anyway, this is still sort of crippled (no CARCH support), but integrates fine.
makepkg -G, --getinteg
+ # necessary override for --geninteg
+ unset INTEGRITY_CHECK
+
+ for integ in md5 sha1 sha256 sha384 sha512; do
+ grep "${integ}sums=(" $file &> /dev/null && \
+ INTEGRITY_CHECK=(${INTEGRITY_CHECK[@]} $integ)
+ done
+
+ [ ${#INTEGRITY_CHECK[@]} -eq 0 ] && source "$MAKEPKG_CONF"
Then it would be the behavior I proposed earlier : "I think both makepkg -g and makepkg -G should look at the hashsums defined in the PKGBUILD and use that."
Any opinions ?
There are a few things I did not like so I rewrote it a bit.
Like it does not seem necessary to re-source makepkg.conf , you just need to use a different variable name :)
Also I removed some features which seemed a bit too hackish to me, like the check for CARCH or the check for vim modeset line.
I hope I did not break things too much and that you like my version.
[ "$CARCH" = "i686" ] && md5sums=('0c9c81f8f0b85fd96a8db06d36b50b33')
The sed line actually deleted the next stuff after that line, which was the build() function, so that was killed :)
Thinking about it, it seems impossible to support every damn pkgbuilds out there. This feature might be much more dangerous than it is helpful.
If we still really want to do that, we should at the very least add a backup to sed -i line. But I am not sure what happens if we mess up twice in a row, we lose everything too ?
Anyway I like the new behavior of makepkg -g I implemented, but not sure I will support makepkg -G.
If -G is implemented, it'll be like what Daenyth mentioned: "with certain caveats"
Hence the check for "CARCH && sums" so it fails for such cases. I'm also in support of "work for everything not most things" here, so I'd say -G doesn't prove to be worthy. It can be done, and that sed line will work fine, but when it comes to redirecting, eg. echo "[ \"$CARCH\" ... && $(generate_checksums)" >> $script it looks like:
[ "$CARCH" = "i686" ] && md5sums=('0c9c81f8f0b85fd96a8db06d36b50b33')
Sure you can fix it with more sed, but is it appropriate to go that far just for a simple result? Worse for those with more than one sum and line breaks, so I abandoned that idea entirely :)
[ "$CARCH" = "i686" ] && md5sums=('0c9c81f8f0b85fd96a8db06d36b50b33')
Then run your sed line :
sed -i".bak" "/md5sums=(/,/)$/d" PKGBUILD
here it deletes the next line, so that's anything but safe. If the next line is your build() function, that's gone.
Also I could fool your CARCH grep check by doing it on multiple lines :
[ "$CARCH" = "i686" ] \
&& md5sums=('0c9c81f8f0b85fd96a8db06d36b50b33')
That's why I prefer to not do the check and try to find out why sed does not work here.
md5sums=('cf40656600b8a587e82a801f05fa2d95')
[ "$CARCH" = "x86_64" ] && md5sums=('c9827059697001fa61518e56fdc24e93')
build() {
But also fails on something like:
md5sums=('cf40656600b8a587e82a801f05fa2d95')
[ "$CARCH" = "x86_64" ] && md5sums=('c9827059697001fa61518e56fdc24e93')
[ "$CARCH" = "any" ] && md5sums=('su8270596970033456t965676fdc24e9')
The CARCH check is also an assumption (that nobody will write it any other way), so that's bad. I guess here there isn't any solution, since there a number of possibilities (and assumptions to be made).
I'd say -G would be disqualified, given the above :)
sed -i".bak" "/md5sums=(/,/)$/d" PKGBUILD
I don't know what /,/ is, how it works, and why it fails in the CARCH case.
Maybe someone could come up with a safer sed command (or another tool) that really only deletes the checksums and nothing else.
What we want to achieve is to strip following regexp (which can be spread on multiple lines...) : {md5,sha1,...}sums=([^)]*)
We cannot implement -G until we have a good and safe way to do this.
Edit : I just realized now that the original report included a different sed command. I will try it and report back :)
sed "/md5sums=([^)]*)/d"
But it had trouble with multiple lines or more copies of sums.
For the one in the patches:
sed "/PATTERN1/,/PATTERN2/d" - Delete only part containing first match PATTERN1 and continue (across more than one line if needed) until PATTERN2
I have no idea why it's not working in the above cases either.
$ sed -ne '1h;1!H;${;g;s/md5sums=([^)]*)/'$(makepkg -g 2>/dev/null)'/g;p;}' PKGBUILD
sed: -e expression #1, char 73: unterminated `s' command
The best one so far actually seems to be the awk one that Pierre shared :
{ rm PKGBUILD; awk '$0 ~ /^md5sums/ {i = 1; system("makepkg -g 2>/dev/null")}; !i {print}; $0 ~ /\)/ {i = 0}' > PKGBUILD; } < PKGBUILD
And it seems this is best run outside of makepkg.. So well, I am giving up with the idea to include this inside makepkg.
And..I've never heard of "implementing" an "unsupported" feature. IIRC that's called "tainting" =p
md5sums=('update' 'cf40656600b8a587e82a801f05fa2d95')
[ "$CARCH" = "x86_64" ] && md5sums=('update:x86_64' 'c9827059697001fa61518e56fdc24e93')
[ "$CARCH" = "any" ] && md5sums=('update:any' 'su8270596970033456t965676fdc24e9')