ghfw-build-extra/pacman-helper.sh

354 строки
7.3 KiB
Bash
Исходник Обычный вид История

#!/bin/sh
# This script helps Git for Windows developers to manage their Pacman
# repository and their local pacman package-database.
#
# A Pacman repository is like a Git repository, but for binary packages.
#
# This script supports seven commands:
#
# - 'fetch' to initialize (or update) a local mirror of the Pacman repository
#
# - 'add' to add packages to the local mirror
#
# - 'remove' to make the next 'push' skip the given package(s)
#
# - 'push' to synchronize local changes (after calling `repo-add`) to the
# remote Pacman repository
#
# - 'files' shows files that are not owned by any package.
#
# - 'dirs' shows directories that are not owned by any package.
#
# - 'orphans' removes any package that became an orphan.
die () {
printf "$*" >&2
exit 1
}
# temporary fifo files
fifo_find="/var/tmp/disowned.find"
fifo_pacman="/var/tmp/disowned.pacman"
# MSys2's mingw-w64-$arch-ca-certificates seem to lag behind ca-certificates
CURL_CA_BUNDLE=/usr/ssl/certs/ca-bundle.crt
export CURL_CA_BUNDLE
mode=
case "$1" in
fetch|add|remove|push|files|dirs|orphans)
mode="$1"
shift
;;
*)
die "Usage:\n" \
" $0 ( fetch | push | ( add | remove ) <package>... )\n" \
" $0 ( files | dirs | orphans )"
;;
esac
base_url=https://dl.bintray.com/git-for-windows/pacman
api_url=https://api.bintray.com
content_url=$api_url/content/git-for-windows/pacman
packages_url=$api_url/packages/git-for-windows/pacman
mirror=/var/local/pacman-mirror
architectures="i686 x86_64"
arch_dir () { # <architecture>
echo "$mirror/$1"
}
fetch () {
for arch in $architectures
do
arch_url=$base_url/$arch
dir="$(arch_dir $arch)"
mkdir -p "$dir"
(cd "$dir" &&
curl -sfO $arch_url/git-for-windows.db.tar.xz ||
continue
for name in $(package_list git-for-windows.db.tar.xz)
do
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
case "$name" in
mingw-w64-*)
filename=$name-any.pkg.tar.xz
;;
*)
filename=$name-$arch.pkg.tar.xz
;;
esac
test -f $filename ||
curl --cacert /usr/ssl/certs/ca-bundle.crt \
-sfLO $base_url/$arch/$filename ||
exit
done
)
done
}
upload () { # <package> <version> <arch> <filename>
curl --netrc -fT "$4" "$content_url/$1/$2/$3/$4" ||
die "Could not upload $4 to $1/$2/$3"
}
publish () { # <package> <version>
curl --netrc -fX POST "$content_url/$1/$2/publish" ||
die "Could not publish $2 in $1"
}
delete_version () { # <package> <version>
curl --netrc -fX DELETE "$packages_url/$1/versions/$2" ||
die "Could not delete version $2 of $1"
}
package_list () { # db.tar.xz
tar tf "$1" |
sed -n 's/\/$//p'
}
package_exists () { # package-name
case "$(curl --netrc -s "$packages_url/$1")" in
*\"name\":\""$1"\"*)
return 0
;;
*)
echo "Package $1 does not yet exist" >&2
return 1
;;
esac
}
db_version () {
json="$(curl --netrc -s \
"$packages_url/package-database/versions/_latest")"
latest="$(expr "$json" : '.*"name":"\([^"]*\)".*')"
test -n "$latest" ||
die "Could not determine latest version"
echo "$latest"
}
next_db_version () { # old version
today="$(date -u +%Y-%m-%d)"
case "$1" in
$today-*)
echo $today-$((${1##*-}+1))
;;
*)
echo $today-1
;;
esac
}
add () { # <file>
test $# -gt 0 ||
die "What packages do you want to add?"
for path
do
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
case "${path##*/}" in
mingw-w64-*.pkg.tar.xz)
arch=${path##*/}
arch=${arch##mingw-w64-}
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
arch=${arch%%-*}
;;
*-*.pkg.tar.xz)
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
arch=${path##*-}
arch=${arch%.pkg.tar.xz}
;;
*)
die "Invalid package name: $path"
;;
esac
case " $architectures " in
*" $arch "*)
# okay
;;
*)
die "Unknown architecture: $arch"
;;
esac
dir="$(arch_dir $arch)"
if test -d "$dir"
then
prefix="${path##*/}"
prefix="${prefix%%-[0-9][0-9.]*}"
(cd "$dir" &&
for file in "$prefix"-[0-9][0-9.]*
do
rm -v "$file"
done)
else
mkdir -p "$dir"
fi
cp "$path" "$dir/"
done
}
remove () { # <package>...
test $# -gt 0 ||
die "What packages do you want to add?"
for package
do
for arch in $architectures
do
(cd "$(arch_dir $arch)" &&
rm $package-*.pkg.tar.xz &&
repo-remove git-for-windows.db.tar.xz $package)
done
done
}
update_local_package_databases () {
for arch in $architectures
do
(cd "$(arch_dir $arch)" &&
repo-add --new git-for-windows.db.tar.xz *.pkg.tar.xz)
done
}
push () {
update_local_package_databases
for arch in $architectures
do
arch_url=$base_url/$arch
dir="$(arch_dir $arch)"
mkdir -p "$dir"
(cd "$dir" &&
echo "Getting $arch_url/git-for-windows.db.tar.xz" &&
curl -L $arch_url/git-for-windows.db.tar.xz > .remote
) ||
die "Could not get remote index for $arch"
done
old_list="$((for arch in $architectures
do
dir="$(arch_dir $arch)"
test -s "$dir/.remote" &&
package_list "$dir/.remote"
done) |
sort | uniq)"
new_list="$((for arch in $architectures
do
dir="$(arch_dir $arch)"
package_list "$dir/git-for-windows.db.tar.xz"
done) |
sort | uniq)"
to_upload="$(printf "%s\n%s\n%s\n" "$old_list" "$old_list" "$new_list" |
sort | uniq -u)"
test -n "$to_upload" || test "x$old_list" != "x$new_list" || {
echo "Nothing to be done" >&2
return
}
db_version="$(db_version)"
next_db_version="$(next_db_version "$db_version")"
test -z "$to_upload" || {
to_upload_basenames="$(echo "$to_upload" |
sed 's/-[0-9].*//' |
sort | uniq)"
# Verify that the packages exist already
for basename in $to_upload_basenames
do
case " $(echo "$old_list" | tr '\n' ' ')" in
*" $basename"-[0-9]*)
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
;;
*)
package_exists $basename ||
die "The package $basename does not yet exist... Add it at https://bintray.com/git-for-windows/pacman/new/package?pkgPath="
pacman-mirror: expect all MinGW packages architecture to be 'any' Pacman is nice enough to help users by preventing them from installing packages for an incompatible architecture. For example, on ARM Linux, you cannot install a MIPS openssh package. The same is true for MSys2 packages: an OpenSSH for, say, i686 cannot work in an environment where an x86_64 msys2-runtime is installed. However, it is not helpful to prevent MinGW packages for i686 from being installed in an x86_64 setup: these are standalone programs and they work just fine. That is the reason why MSys2 encodes the architecture of MinGW packages in their package name, but marks the package's architecture as 'any' (even if it is technically incorrect and might very well lead to problems with Windows 10 that does run on ARM processors, where mixing and matching different architectures is no longer a safe thing: you will not be able to run an i686 program on an ARM processor). For example, when building Git for Windows packages, this developer uses a setup where *both* mingw-w64-i686-toolchain and mingw-w64-x86_64-toolchain are installed. This works quite well and lets `makepkg-mingw` build the package for *both* architectures in one go. Up to now, the Git for Windows project handled the architecture of the mingw-w64-git package incorrectly by marking the packages' architecture as either i686 or x86_64 and thereby preventing users from installing a mingw-w64-git package for a different architecture than the current msys2-runtime one. However, with the mingw-w64-asciidoctor-extensions package being a build dependency, the problem cropped up that marking its architecture would prevent it to be installed for both architectures, breaking the paradigm where mingw-w64-git could be built for both architectures in one go. Therefore, we now build our MinGW packages also with the "any" architecture, just like upstream, and everybody is happy. This requires the change contained in this commit, though, because the packages are no longer named mingw-w64-i686-*-i686.pkg.tar.xz and mingw-w64-x86_64-*-x86_64.pkg.tar.xz, respectively, but instead mingw-w64-i686-*-any.pkg.tar.xz and mingw-w64-x86_64-*-any.pkg.tar.xz. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2015-04-15 17:59:17 +03:00
;;
esac
done
for name in $to_upload
do
basename=${name%%-[0-9]*}
version=${name#$basename-}
for arch in $architectures
do
case "$name" in
mingw-w64-*)
filename=$name-any.pkg.tar.xz
;;
*)
filename=$name-$arch.pkg.tar.xz
;;
esac
(cd "$(arch_dir $arch)" &&
if test -f $filename
then
upload $basename $version $arch $filename
fi) || exit
done
publish $basename $version
done
}
delete_version package-database "$db_version"
for arch in $architectures
do
(cd "$(arch_dir $arch)" &&
for suffix in db db.tar.xz files files.tar.xz
do
filename=git-for-windows.$suffix
test ! -f $filename ||
upload package-database $next_db_version $arch $filename
done
) || exit
done
publish package-database $next_db_version
}
reset_fifo_files () {
rm -f "$fifo_find"
rm -f "$fifo_pacman"
}
dirs () {
reset_fifo_files
find / \( -path '/dev' -o -path '/bin' -o -path '/usr/src' \
-o -path '/tmp' -o -path '/proc' -o -path '/home' \
-o -path '/var/lib/pacman' -o -path '/var/cache/pacman' \) \
-prune -o -type d -print | sed 's/\([^/]\)$/\1\//' | \
sort -u > "$fifo_find"
pacman -Qlq | sort -u > "$fifo_pacman"
comm -23 "$fifo_find" "$fifo_pacman"
reset_fifo_files
}
files () {
reset_fifo_files
find / \( -path '/dev' -o -path '/bin' -o -path '/usr/src' \
-o -path '/tmp' -o -path '/proc' -o -path "$fifo_find" \
-o -path '/home' -o -path '/var/lib/pacman' \
-o -path '/var/cache/pacman' \) -prune -o -type f -print | \
sort -u > "$fifo_find"
pacman -Qlq | sort -u > "$fifo_pacman"
comm -23 "$fifo_find" "$fifo_pacman"
reset_fifo_files
}
orphans () {
pacman -Rns $(pacman -Qtdq) 2> /dev/null || echo 'no orphans found..'
}
eval "$mode" "$@"