aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-04-08 14:36:30 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-04-08 14:41:39 +0000
commitfa97c553713e920e0904a330a1e32d8e41df7fb0 (patch)
tree5f5af3674d90a598f0b578e0c0583b3fba7f5942
parent05194ff18a1a6820d6caa126c6fe46a0b3201331 (diff)
downloadaports-fa97c553713e920e0904a330a1e32d8e41df7fb0.tar.bz2
aports-fa97c553713e920e0904a330a1e32d8e41df7fb0.tar.xz
main/abuild: upgrade to git snapshot 20150408
with xattr support for new paxmarking style
-rw-r--r--main/abuild/0001-abuild-fix-CXXFLAGS-for-debug.patch24
-rw-r--r--main/abuild/0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch36
-rw-r--r--main/abuild/APKBUILD21
-rw-r--r--main/abuild/git.patch727
4 files changed, 736 insertions, 72 deletions
diff --git a/main/abuild/0001-abuild-fix-CXXFLAGS-for-debug.patch b/main/abuild/0001-abuild-fix-CXXFLAGS-for-debug.patch
deleted file mode 100644
index 35f78b7331..0000000000
--- a/main/abuild/0001-abuild-fix-CXXFLAGS-for-debug.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 756a9e0c0466e79d914e563068ed345f47a8092f Mon Sep 17 00:00:00 2001
-From: Natanael Copa <ncopa@alpinelinux.org>
-Date: Wed, 28 Jan 2015 13:09:24 +0000
-Subject: [PATCH] abuild: fix CXXFLAGS for debug
-
----
- abuild.in | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/abuild.in b/abuild.in
-index 68f6afd..655c1a9 100644
---- a/abuild.in
-+++ b/abuild.in
-@@ -1995,6 +1995,7 @@ fi
- # if we want build debug package
- if [ -n "$DEBUG" ] || subpackage_types_has "dbg"; then
- CFLAGS="$CFLAGS -g"
-+ CXXFLAGS="$CXXFLAGS -g"
- options="$options !strip"
- fi
-
---
-2.2.2
-
diff --git a/main/abuild/0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch b/main/abuild/0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
deleted file mode 100644
index c87c83d0be..0000000000
--- a/main/abuild/0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From a6150cc7e064f009537e4a3a444a9eb83c667113 Mon Sep 17 00:00:00 2001
-From: Natanael Copa <ncopa@alpinelinux.org>
-Date: Wed, 14 Jan 2015 15:26:58 +0000
-Subject: [PATCH] abuild: fix move of .a file to -dev subpackage
-
-seems like new version of busybox find would stop if lib/ dir does not
-exist.
----
- abuild.in | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/abuild.in b/abuild.in
-index e4e5091..68f6afd 100644
---- a/abuild.in
-+++ b/abuild.in
-@@ -1294,6 +1294,8 @@ default_dev() {
- done
-
- cd "$pkgdir" || return 0
-+ local libdirs=usr/
-+ [ -d lib/ ] && libdirs="lib/ $libdirs"
- for i in usr/include usr/lib/pkgconfig usr/share/aclocal\
- usr/share/gettext usr/bin/*-config \
- usr/share/vala/vapi usr/share/gir-[0-9]*\
-@@ -1301,7 +1303,7 @@ default_dev() {
- usr/lib/qt*/mkspecs \
- usr/lib/cmake \
- $(find . -name include -type d) \
-- $(find lib/ usr/ -name '*.[acho]' \
-+ $(find $libdirs -name '*.[acho]' \
- -o -name '*.prl' 2>/dev/null); do
- if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
- d="$subpkgdir/${i%/*}" # dirname $i
---
-2.2.2
-
diff --git a/main/abuild/APKBUILD b/main/abuild/APKBUILD
index 6004877063..906f8fa9ef 100644
--- a/main/abuild/APKBUILD
+++ b/main/abuild/APKBUILD
@@ -1,13 +1,14 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=abuild
-pkgver=2.21.0
+pkgver=2.21.0_git20150408
_ver=${pkgver%_git*}
-pkgrel=2
+pkgrel=0
pkgdesc="Script to build Alpine Packages"
url="http://git.alpinelinux.org/cgit/abuild/"
arch="all"
license="GPL2"
-depends="fakeroot sudo pax-utils openssl apk-tools>=2.0.7-r1 libc-utils"
+depends="fakeroot sudo pax-utils openssl apk-tools>=2.0.7-r1 libc-utils
+ attr tar"
if [ "$CBUILD" = "$CHOST" ]; then
depends="$depends curl"
fi
@@ -18,9 +19,8 @@ install="$pkgname.pre-install $pkgname.pre-upgrade"
subpackages="apkbuild-cpan:cpan"
options="suid"
pkggroups="abuild"
-source="http://dev.alpinelinux.org/archive/abuild/abuild-$pkgver.tar.xz
- 0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
- 0001-abuild-fix-CXXFLAGS-for-debug.patch
+source="http://dev.alpinelinux.org/archive/abuild/abuild-$_ver.tar.xz
+ git.patch
"
_builddir="$srcdir/$pkgname-$_ver"
@@ -60,11 +60,8 @@ cpan() {
}
md5sums="126cbde6e4fdf537571a03a97d01d348 abuild-2.21.0.tar.xz
-eea48116812c648c3b16acfe2f027b15 0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
-fa5de956ef50716388fed26dd8fc6c82 0001-abuild-fix-CXXFLAGS-for-debug.patch"
+453ee698af510fc0cf10a33020e37e73 git.patch"
sha256sums="08689cbf8818c81d9e52e3397529adcb0e279a21d33dfe4f0678d0ef778767f3 abuild-2.21.0.tar.xz
-6c0fbe9c4e3b8d85723d4ff8e1338ae5fc789af2607fe089ae979df462b40e31 0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
-e878f17f98c7e6ad43e20d069fc4a23a91086ff09fb6bb05f0b31c68b8ecf852 0001-abuild-fix-CXXFLAGS-for-debug.patch"
+7e7f9a837c2c6a2bddb2db80f86b2cad212cbb0cc8f2a8b63534dd5a3bc52318 git.patch"
sha512sums="b304dbb82563ec8ae23376c17ee27b3d49e9c1b74bd14b7a912ca88239ed3c7b2fabeb6209a6d4485c6dbab8491abb8b42f801f5fd9310691da60e630061646b abuild-2.21.0.tar.xz
-3693b28a030c4d97fa0927ab5ac517176b9f9ad34b6c018bd77be8355f1127e09751edf5c3b30299427bb8e6afa0f8149da2cdd6d3c191fabc8f94886fa5b172 0001-abuild-fix-move-of-.a-file-to-dev-subpackage.patch
-19f77dd76909edceaf41b14a66ce46ee81e31654e07ccc935d3db0bf711ca4caae083d3fc5e3ccf44d58cce602923bcc3259364d4b811f6c288200531ebfd40c 0001-abuild-fix-CXXFLAGS-for-debug.patch"
+6ab114cd383d29244124e5cf440ef17f292e01a683d21c153f808d7757e38e1b575384d5d4b2a3314c17a5656c64361703c3f746577266ae4403edcf353cc5e8 git.patch"
diff --git a/main/abuild/git.patch b/main/abuild/git.patch
new file mode 100644
index 0000000000..4c0f9c3f96
--- /dev/null
+++ b/main/abuild/git.patch
@@ -0,0 +1,727 @@
+diff --git a/Makefile b/Makefile
+index ccfed0d..7053e2d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -9,7 +9,8 @@ datadir ?= $(prefix)/share/$(PACKAGE)
+ abuildrepo ?= ~/.cache/abuild
+
+ SCRIPTS := abuild buildrepo abuild-keygen abuild-sign newapkbuild \
+- abump apkgrel buildlab apkbuild-cpan checkapk
++ abump apkgrel buildlab apkbuild-cpan checkapk \
++ apkbuild-gem-resolver
+ USR_BIN_FILES := $(SCRIPTS) abuild-tar abuild-sudo
+ SAMPLES := sample.APKBUILD sample.initd sample.confd \
+ sample.pre-install sample.post-install
+diff --git a/abuild-tar.c b/abuild-tar.c
+index 4a88882..2f29d30 100644
+--- a/abuild-tar.c
++++ b/abuild-tar.c
+@@ -1,6 +1,6 @@
+ /* abuild-tar.c - A TAR mangling utility for .APK packages
+ *
+- * Copyright (C) 2009 Timo Teräs <timo.teras@iki.fi>
++ * Copyright (C) 2009-2014 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+@@ -89,6 +89,19 @@ static void put_octal(char *s, size_t l, size_t value)
+ *(ptr--) = '0';
+ }
+
++static void tarhdr_checksum(struct tar_header *hdr)
++{
++ const unsigned char *src;
++ size_t chksum, i;
++
++ /* Recalculate checksum */
++ memset(hdr->chksum, ' ', sizeof(hdr->chksum));
++ src = (const unsigned char *) hdr;
++ for (i = chksum = 0; i < sizeof(*hdr); i++)
++ chksum += src[i];
++ put_octal(hdr->chksum, sizeof(hdr->chksum)-1, chksum);
++}
++
+ static int usage(void)
+ {
+ fprintf(stderr,
+@@ -120,7 +133,7 @@ static ssize_t full_read(int fd, void *buf, size_t count)
+ } while (1);
+
+ if (total == 0 && n < 0)
+- return -1;
++ return -errno;
+
+ return total;
+ }
+@@ -142,7 +155,7 @@ static ssize_t full_write(int fd, const void *buf, size_t count)
+ } while (1);
+
+ if (total == 0 && n < 0)
+- return -1;
++ return -errno;
+
+ return total;
+ }
+@@ -163,82 +176,182 @@ static ssize_t full_splice(int from_fd, int to_fd, size_t count)
+ } while (1);
+
+ if (total == 0 && n < 0)
+- return -1;
++ return -errno;
+
+ return total;
+ }
+
+-static int do_it(const EVP_MD *md, int cut)
++#define BUF_INITIALIZER {0}
++struct buf {
++ char *ptr;
++ size_t size;
++ size_t alloc;
++};
++
++static void buf_free(struct buf *b)
++{
++ free(b->ptr);
++}
++
++static int buf_resize(struct buf *b, size_t newsize)
+ {
+- struct tar_header hdr;
+- size_t size, aligned_size;
+ void *ptr;
+- int dohash = 0, r;
++
++ if (b->alloc >= newsize) return 0;
++ ptr = realloc(b->ptr, newsize);
++ if (!ptr) return -ENOMEM;
++ b->ptr = ptr;
++ b->alloc = newsize;
++ return 0;
++}
++
++static int buf_padto(struct buf *b, size_t alignment)
++{
++ size_t oldsize, newsize;
++ oldsize = b->size;
++ newsize = (oldsize + alignment - 1) & -alignment;
++ if (buf_resize(b, newsize)) return -ENOMEM;
++ b->size = newsize;
++ memset(b->ptr + oldsize, 0, newsize - oldsize);
++ return 0;
++}
++
++static int buf_read_fd(struct buf *b, int fd, size_t size)
++{
++ ssize_t r;
++
++ r = buf_resize(b, size);
++ if (r) return r;
++
++ r = full_read(fd, b->ptr, size);
++ if (r == size) {
++ b->size = r;
++ return 0;
++ }
++ b->size = 0;
++ if (r < 0) return r;
++ return -EIO;
++}
++
++static int buf_write_fd(struct buf *b, int fd)
++{
++ ssize_t r;
++ r = full_write(fd, b->ptr, b->size);
++ if (r == b->size) return 0;
++ if (r < 0) return r;
++ return -ENOSPC;
++}
++
++static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const char *value, int valuelen)
++{
++ size_t oldsize = b->size;
++ int i, len;
++
++ /* "%u %s=%s\n" */
++ len = 1 + 1 + strlen(hdr) + 1 + valuelen*2 + 1;
++ for (i = len; i > 9; i /= 10) len++;
++
++ if (buf_resize(b, b->size + len)) return -ENOMEM;
++ b->size += snprintf(&b->ptr[b->size], len, "%u %s=", len, hdr);
++ for (i = 0; i < valuelen; i++)
++ b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)(unsigned char)value[i]);
++ b->ptr[b->size++] = '\n';
++
++ return 0;
++}
++
++static void add_legacy_checksum(struct tar_header *hdr, const EVP_MD *md, const char *digest)
++{
+ struct {
+ char id[4];
+ uint16_t nid;
+ uint16_t size;
+ } mdinfo;
+
+- if (md != NULL) {
+- memcpy(mdinfo.id, "APK2", 4);
+- mdinfo.nid = EVP_MD_nid(md);
+- mdinfo.size = EVP_MD_size(md);
+- }
++ memcpy(mdinfo.id, "APK2", 4);
++ mdinfo.nid = EVP_MD_nid(md);
++ mdinfo.size = EVP_MD_size(md);
++ memcpy(&hdr->linkname[3], &mdinfo, sizeof(mdinfo));
++ memcpy(&hdr->linkname[3+sizeof(mdinfo)], digest, mdinfo.size);
++ tarhdr_checksum(hdr);
++}
++
++static int do_it(const EVP_MD *md, int cut)
++{
++ char checksumhdr[32], digest[EVP_MAX_MD_SIZE];
++ struct buf data = BUF_INITIALIZER, pax = BUF_INITIALIZER;
++ struct tar_header hdr, paxhdr;
++ size_t size, aligned_size;
++ int dohash = 0, r, ret = 1;
++
++ if (md) snprintf(checksumhdr, sizeof(checksumhdr), "APK-TOOLS.checksum.%s", EVP_MD_name(md));
+
+ do {
+ if (full_read(STDIN_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr))
+- return 0;
++ goto err;
+
+ if (cut && hdr.name[0] == 0)
+- return 0;
++ break;
+
+ size = GET_OCTAL(hdr.size);
+ aligned_size = (size + 511) & ~511;
+
+- if (md != NULL)
+- dohash = (hdr.typeflag == '0' || hdr.typeflag == '7');
++ if (hdr.typeflag == 'x') {
++ memcpy(&paxhdr, &hdr, sizeof(hdr));
++ if (buf_read_fd(&pax, STDIN_FILENO, aligned_size)) goto err;
++ pax.size = size;
++ continue;
++ }
++
++ dohash = md && (hdr.typeflag == '0' || hdr.typeflag == '7' || hdr.typeflag == '2');
+ if (dohash) {
+- const unsigned char *src;
+- int chksum, i;
+-
+- ptr = malloc(aligned_size);
+- if (full_read(STDIN_FILENO, ptr, aligned_size) != aligned_size)
+- return 1;
+-
+- memcpy(&hdr.linkname[3], &mdinfo, sizeof(mdinfo));
+- EVP_Digest(ptr, size, &hdr.linkname[3+sizeof(mdinfo)],
+- NULL, md, NULL);
+-
+- /* Recalculate checksum */
+- memset(hdr.chksum, ' ', sizeof(hdr.chksum));
+- src = (const unsigned char *) &hdr;
+- for (i = chksum = 0; i < sizeof(hdr); i++)
+- chksum += src[i];
+- put_octal(hdr.chksum, sizeof(hdr.chksum)-1, chksum);
++ if (buf_read_fd(&data, STDIN_FILENO, aligned_size)) goto err;
++
++ if (hdr.typeflag != '2') {
++ EVP_Digest(data.ptr, size, digest, NULL, md, NULL);
++ add_legacy_checksum(&hdr, md, digest);
++ } else {
++ EVP_Digest(hdr.linkname, strlen(hdr.linkname), digest, NULL, md, NULL);
++ }
++
++ buf_add_ext_header_hexdump(&pax, checksumhdr, digest, EVP_MD_size(md));
++ PUT_OCTAL(paxhdr.size, pax.size);
++ tarhdr_checksum(&paxhdr);
++ }
++
++ if (pax.size) {
++ /* write pax header + content */
++ if (full_write(STDOUT_FILENO, &paxhdr, sizeof(paxhdr)) != sizeof(paxhdr) ||
++ buf_padto(&pax, 512) ||
++ buf_write_fd(&pax, STDOUT_FILENO)) goto err;
+ }
+
+- if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr))
+- return 2;
++ if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr)) goto err;
+
+ if (dohash) {
+- if (full_write(STDOUT_FILENO, ptr, aligned_size) != aligned_size)
+- return 2;
+- free(ptr);
++ if (buf_write_fd(&data, STDOUT_FILENO)) goto err;
+ } else if (aligned_size != 0) {
+ r = full_splice(STDIN_FILENO, STDOUT_FILENO, aligned_size);
+ if (r == -1) {
+ while (aligned_size > 0) {
+ if (full_read(STDIN_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr))
+- return 1;
++ goto err;
+ if (full_write(STDOUT_FILENO, &hdr, sizeof(hdr)) != sizeof(hdr))
+- return 2;
++ goto err;
+ aligned_size -= sizeof(hdr);
+ }
+- } else if (r != aligned_size)
+- return 2;
++ } else if (r != aligned_size) goto err;
+ }
++
++ memset(&paxhdr, 0, sizeof(paxhdr));
++ pax.size = 0;
+ } while (1);
++
++ ret = 0;
++err:
++ buf_free(&data);
++ buf_free(&pax);
++ return ret;
+ }
+
+ int main(int argc, char **argv)
+diff --git a/abuild.in b/abuild.in
+index 5459a9b..93c723d 100644
+--- a/abuild.in
++++ b/abuild.in
+@@ -616,13 +616,12 @@ postcheck() {
+ return 1
+ fi
+ fi
+- # look for *.la files
+- i=$(find "$dir" -name '*.la' | sed "s|^$dir|\t|")
+- if [ -n "$i" ] && ! options_has "libtool"; then
+- error "Libtool archives (*.la) files found and \$options has no 'libtool' flag:"
+- echo "$i"
+- return 1
++
++ # remove *.la files if libtool is not set
++ if ! options_has "libtool"; then
++ find "$dir" -name '*.la' -type f -delete
+ fi
++
+ # look for /usr/lib/charset.alias
+ if [ -e "$dir"/usr/lib/charset.alias ] \
+ && ! options_has "charset.alias"; then
+@@ -816,18 +815,13 @@ EOF
+ echo "replaces_priority = $replaces_priority" >> "$pkginfo"
+ fi
+
+- for i in $license; do
+- echo "license = $i" >> "$pkginfo"
+- done
++ echo "license = $license" >> "$pkginfo"
+ for i in $replaces; do
+ echo "replaces = $i" >> "$pkginfo"
+ done
+ for i in $deps; do
+ echo "depend = $i" >> "$pkginfo"
+ done
+- for i in $conflicts; do
+- echo "conflict = $i" >> "$pkginfo"
+- done
+ for i in $provides; do
+ echo "provides = $i" >> "$pkginfo"
+ done
+@@ -1140,7 +1134,7 @@ create_apks() {
+ touch .dummy
+ set -- .dummy
+ fi
+- tar -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz
++ tar --xattrs -c "$@" | abuild-tar --hash | gzip -9 >"$dir"/data.tar.gz
+
+ msg "Create checksum..."
+ # append the hash for data.tar.gz
+@@ -1298,6 +1292,8 @@ default_dev() {
+ done
+
+ cd "$pkgdir" || return 0
++ local libdirs=usr/
++ [ -d lib/ ] && libdirs="lib/ $libdirs"
+ for i in usr/include usr/lib/pkgconfig usr/share/aclocal\
+ usr/share/gettext usr/bin/*-config \
+ usr/share/vala/vapi usr/share/gir-[0-9]*\
+@@ -1305,7 +1301,7 @@ default_dev() {
+ usr/lib/qt*/mkspecs \
+ usr/lib/cmake \
+ $(find . -name include -type d) \
+- $(find lib/ usr/ -name '*.[acho]' \
++ $(find $libdirs -name '*.[acho]' \
+ -o -name '*.prl' 2>/dev/null); do
+ if [ -e "$pkgdir/$i" ] || [ -L "$pkgdir/$i" ]; then
+ d="$subpkgdir/${i%/*}" # dirname $i
+@@ -1532,7 +1528,7 @@ deptrace() {
+
+ # build and install dependencies
+ builddeps() {
+- local pkg= i= missing= conflicts=
++ local pkg= i= missing=
+ local hostdeps= builddeps= installed_hostdeps= installed_builddeps=
+ [ -n "$nodeps" ] && return 0
+ msg "Analyzing dependencies..."
+@@ -1562,27 +1558,20 @@ builddeps() {
+
+ # find which deps are missing
+ for i in $builddeps; do
+- if [ "${i#\!}" != "$i" ]; then
+- $APK info --quiet --installed "${i#\!}" \
+- && conflicts="$conflicts ${i#\!}"
++ if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed "${i#\!}"; then
++ error "Conflicting package installed: ${i#\!}"
+ elif ! deplist_has $i $installed_builddeps || [ -n "$upgrade" ]; then
+ missing="$missing $i"
+ fi
+ done
+ for i in $hostdeps; do
+- if [ "${i#\!}" != "$i" ]; then
+- $APK info --quiet --installed --root "$CBUILDROOT" "${i#\!}" \
+- && conflicts="$conflicts ${i#\!}"
++ if [ "${i#\!}" != "$i" ] && $APK info --quiet --installed --root "$CBUILDROOT" "${i#\!}"; then
++ error "Conflicting package installed: ${i#\!}"
+ elif ! deplist_has $i $installed_hostdeps || [ -n "$upgrade" ]; then
+ missing="$missing $i"
+ fi
+ done
+
+- if [ -n "$conflicts" ]; then
+- error "Conflicting package(s) installed:$conflicts"
+- return 1
+- fi
+-
+ if [ -z "$install_deps" ] && [ -z "$recursive" ]; then
+ # if we dont have any missing deps we are done now
+ [ -z "$missing" ] && return 0
+@@ -1687,7 +1676,11 @@ stripbin() {
+ msg "Stripping binaries"
+ scanelf --recursive --nobanner --etype "ET_DYN,ET_EXEC" . \
+ | sed -e 's:^ET_DYN ::' -e 's:^ET_EXEC ::' \
+- | xargs -r ${CROSS_COMPILE}strip
++ | while read filename; do
++ XATTR=$(getfattr -d "${filename}")
++ ${CROSS_COMPILE}strip "${filename}"
++ [ -n "$XATTR" ] && (echo "$XATTR" | setfattr --restore=-)
++ done
+ }
+
+ # simply list target apks
+@@ -2004,6 +1997,7 @@ fi
+ # if we want build debug package
+ if [ -n "$DEBUG" ] || subpackage_types_has "dbg"; then
+ CFLAGS="$CFLAGS -g"
++ CXXFLAGS="$CXXFLAGS -g"
+ options="$options !strip"
+ fi
+
+diff --git a/apkbuild-gem-resolver.in b/apkbuild-gem-resolver.in
+new file mode 100644
+index 0000000..b93525e
+--- /dev/null
++++ b/apkbuild-gem-resolver.in
+@@ -0,0 +1,302 @@
++#!/usr/bin/ruby
++
++# APKBUILD dependency resolver for RubyGems
++# Copyright (C) 2014 Kaarle Ritvanen
++
++require 'augeas'
++require 'optparse'
++require 'rubygems/dependency'
++require 'rubygems/resolver'
++require 'rubygems/spec_fetcher'
++
++class Aport
++ RUBY_SUBPACKAGES = {
++ '2.0.0_p353' => {
++ 'ruby-minitest' => ['minitest', '4.3.2'],
++ 'ruby-rake' => ['rake', '0.9.6'],
++ 'ruby-rdoc' => ['rdoc', '4.0.0', 'ruby-json']
++ },
++ '2.0.0_p481' => {
++ 'ruby-minitest' => ['minitest', '4.3.2'],
++ 'ruby-rake' => ['rake', '0.9.6'],
++ 'ruby-rdoc' => ['rdoc', '4.0.0', 'ruby-json']
++ },
++ '2.1.5' => {
++ 'ruby-json' => ['json', '1.8.1'],
++ 'ruby-minitest' => ['minitest', '4.7.5'],
++ 'ruby-rake' => ['rake', '10.1.0'],
++ 'ruby-rdoc' => ['rdoc', '4.1.0', 'ruby-json']
++ },
++ '2.2.1' => {
++ 'ruby-json' => ['json', '1.8.1'],
++ 'ruby-minitest' => ['minitest', '5.4.3'],
++ 'ruby-rake' => ['rake', '10.4.2'],
++ 'ruby-rdoc' => ['rdoc', '4.2.0', 'ruby-json'],
++ 'ruby-io-console' => [ 'io-console', '0.4.2'] # its actually 0.4.3 but
++ # that version is not
++ # published on network
++ }
++ }
++
++ @@aports = {}
++ @@subpackages = []
++
++ def self.initialize testing
++ Augeas::open(nil, nil, Augeas::NO_MODL_AUTOLOAD) do |aug|
++ dir = Dir.pwd
++ aug.transform(:lens => 'Shellvars.lns', :incl => dir + '/*/ruby*/APKBUILD')
++ aug.load
++
++ apath = '/files' + dir
++ fail if aug.match("/augeas#{apath}//error").length > 0
++
++ repos = ['main']
++ repos << 'testing' if testing
++ for repo in repos
++ for aport in aug.match "#{apath}/#{repo}/*"
++ FileAport.new(aug, aport) unless aport.end_with? '/ruby'
++ end
++ end
++
++ for name, attrs in RUBY_SUBPACKAGES[
++ aug.get("#{apath}/main/ruby/APKBUILD/pkgver")
++ ]
++ gem, version, *deps = attrs
++ aport = new name, gem, version
++ for dep in deps
++ aport.add_dependency dep
++ end
++ @@subpackages << aport
++ end
++ end
++
++ @@aports.each_value do |aport|
++ aport.depends do |dep|
++ dep.add_user aport
++ end
++ end
++ end
++
++ def self.get name
++ aport = @@aports[name]
++ raise 'Invalid package name: ' + name unless aport
++ aport
++ end
++
++ def self.ruby_subpkgs
++ for pkg in @@subpackages
++ yield pkg
++ end
++ end
++
++ def initialize name, gem, version
++ @name = name
++ @gem = gem
++ @version = version
++ @depends = []
++ @users = []
++ @@aports[name] = self
++ end
++
++ def add_dependency name
++ @depends << name
++ end
++
++ attr_reader :gem, :name, :version
++
++ def depends
++ for dep in @depends
++ unless @@aports.has_key? dep
++ raise "Dependency for #{@name} does not exist: #{dep}"
++ end
++ yield @@aports[dep]
++ end
++ end
++
++ def users
++ for user in @users
++ yield user
++ end
++ end
++
++ def add_user user
++ @users << user
++ end
++end
++
++class FileAport < Aport
++ def initialize aug, path
++ name = path.split('/')[-1]
++
++ get = proc{ |param|
++ res = aug.get(path + '/APKBUILD/' + param)
++ raise param + ' not defined for ' + name unless res
++ res
++ }
++
++ super name, get.call('_gemname'), get.call('pkgver')
++
++ for dep in `echo #{get.call('depends')}`.split
++ # ruby-gems: workaround for v2.6
++ add_dependency dep if dep.start_with?('ruby-') && dep != 'ruby-gems'
++ end
++ end
++end
++
++
++class Update
++ def initialize
++ @gems = {}
++ @deps = []
++ end
++
++ def require_version name, version
++ gem = assign(Aport.get(name).gem, name)
++ @deps << gem.dependency if gem.require_version version
++ end
++
++ def resolve
++ Aport.ruby_subpkgs do |pkg|
++ require_version pkg.name, pkg.version unless @gems[pkg.gem]
++ end
++
++ def check_deps
++ @gems.clone.each_value do |gem|
++ gem.check_deps
++ end
++ end
++
++ check_deps
++
++ for req in Gem::Resolver.new(@deps).resolve
++ spec = req.spec
++ gem = @gems[spec.name]
++ gem.require_version spec.version.version if gem
++ end
++
++ check_deps
++
++ for name, gem in @gems
++ if gem.updated?
++ gem.aport.users do |user|
++ ugem = @gems[user.gem]
++ if !ugem || ugem.aport.name != user.name
++ Gem::Resolver.new(
++ [gem.dependency, Gem::Dependency.new(user.gem, user.version)]
++ ).resolve
++ end
++ end
++ end
++ end
++ end
++
++ def each
++ @gems.each_value do |gem|
++ obs = gem.obsolete_deps
++ obs = obs.length == 0 ? nil : " (obsolete dependencies: #{obs.join ', '})"
++
++ if gem.updated? || obs
++ yield "#{gem.aport.name}-#{gem.version}#{obs}"
++ end
++ end
++ end
++
++ def assign name, aport
++ aport = Aport.get aport
++
++ if @gems.has_key? name
++ gem = @gems[name]
++ return gem if aport == gem.aport
++ raise "Conflicting packages for gem #{name}: #{gem.aport.name} and #{aport.name}"
++ end
++
++ gem = AportGem.new self, name, aport
++ @gems[name] = gem
++ gem
++ end
++
++ private
++
++ class AportGem
++ def initialize update, name, aport
++ @update = update
++ @name = name
++ @aport = aport
++ end
++
++ attr_reader :aport, :obsolete_deps
++
++ def require_version version
++ if @version
++ return false if version == @version
++ raise "Conflicting versions for gem #{@name}: #{@version} and #{version}"
++ end
++ @version = version
++ true
++ end
++
++ def version
++ @version || @aport.version
++ end
++
++ def updated?
++ version != @aport.version
++ end
++
++ def dependency
++ Gem::Dependency.new(@name, version)
++ end
++
++ def check_deps
++ specs, errors = Gem::SpecFetcher::fetcher.spec_for_dependency(dependency)
++ raise "Invalid gem: #{@name}-#{version}" if specs.length == 0
++ fail if specs.length > 1
++ deps = specs[0][0].runtime_dependencies
++
++ @obsolete_deps = []
++
++ @aport.depends do |dep|
++ gem = @update.assign(dep.gem, dep.name)
++ gem.check_deps
++ unless deps.reject! { |sdep| sdep.match? dep.gem, gem.version }
++ @obsolete_deps << dep.name
++ end
++ end
++
++ if deps.length > 0
++ raise 'Undeclared dependencies in ' + @aport.name + deps.inject('') {
++ |s, dep| "#{s}\n#{dep.name} #{dep.requirements_list.join ' '}"
++ }
++ end
++ end
++ end
++end
++
++
++testing = false
++OptionParser.new do |opts|
++ opts.on('-t', '--testing') do |t|
++ testing = t
++ end
++end.parse! ARGV
++Aport.initialize testing
++
++latest = {}
++for source, gems in Gem::SpecFetcher::fetcher.available_specs(:latest)[0]
++ for gem in gems
++ latest[gem.name] = gem.version.version
++ end
++end
++
++update = Update.new
++for arg in ARGV
++ match = /^(([^-]|-[^\d])+)(-(\d.*))?/.match arg
++ name = match[1]
++ update.require_version name, match[4] || latest[Aport.get(name).gem]
++end
++
++update.resolve
++
++for aport in update
++ puts aport
++end