You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
osync/packaging/ARCH/mksrcinfo

280 lines
6.7 KiB
Bash

#!/bin/bash
shopt -s extglob
array_build() {
local dest=$1 src=$2 i keys values
# it's an error to try to copy a value which doesn't exist.
declare -p "$2" &>/dev/null || return 1
# Build an array of the indicies of the source array.
eval "keys=(\"\${!$2[@]}\")"
# Clear the destination array
eval "$dest=()"
# Read values indirectly via their index. This approach gives us support
# for associative arrays, sparse arrays, and empty strings as elements.
for i in "${keys[@]}"; do
values+=("printf -v '$dest[$i]' %s \"\${$src[$i]}\";")
done
eval "${values[*]}"
}
funcgrep() {
{ declare -f "$1" || declare -f package; } 2>/dev/null | grep -E "$2"
}
# extract_global_var function compatible with bash 4.2
extract_global_var() {
# $1: variable name
# $2: multivalued
# $3: name of output var
local attr=$1 isarray=$2 outputvar=$3 ref
if (( isarray )); then
array_build ref "$attr"
[[ ${ref[@]} ]] && array_build "$outputvar" "$attr"
else
[[ ${!attr} ]] && printf -v "$outputvar" %s "${!attr}"
fi
}
# extract global_var function compatible with bash 4.3+
old_extract_global_var() {
# $1: variable name
# $2: multivalued
# $3: name of output var
local attr=$1 isarray=$2 outputvar=$3
if (( isarray )); then
declare -n ref=$attr
# Still need to use array_build here because we can't handle the scoping
# semantics that would be included with the use of 'declare -n'.
[[ ${ref[@]} ]] && array_build "$outputvar" "$attr"
else
[[ ${!attr} ]] && printf -v "$outputvar" %s "${!attr}"
fi
}
extract_function_var() {
# $1: function name
# $2: variable name
# $3: multivalued
# $4: name of output var
local funcname=$1 attr=$2 isarray=$3 outputvar=$4 attr_regex= decl= r=1
if (( isarray )); then
printf -v attr_regex '^[[:space:]]* %s\+?=\(' "$2"
else
printf -v attr_regex '^[[:space:]]* %s\+?=[^(]' "$2"
fi
while read -r; do
# strip leading whitespace and any usage of declare
decl=${REPLY##*([[:space:]])}
eval "${decl/#$attr/$outputvar}"
# entering this loop at all means we found a match, so notify the caller.
r=0
done < <(funcgrep "$funcname" "$attr_regex")
return $r
}
pkgbuild_get_attribute() {
# $1: package name
# $2: attribute name
# $3: multivalued
# $4: name of output var
local pkgname=$1 attrname=$2 isarray=$3 outputvar=$4
printf -v "$outputvar" %s ''
if [[ $pkgname ]]; then
extract_global_var "$attrname" "$isarray" "$outputvar"
extract_function_var "package_$pkgname" "$attrname" "$isarray" "$outputvar"
else
extract_global_var "$attrname" "$isarray" "$outputvar"
fi
}
srcinfo_open_section() {
printf '%s = %s\n' "$1" "$2"
}
srcinfo_close_section() {
echo
}
srcinfo_write_attr() {
# $1: attr name
# $2: attr values
local attrname=$1 attrvalues=("${@:2}")
# normalize whitespace, strip leading and trailing
attrvalues=("${attrvalues[@]//+([[:space:]])/ }")
attrvalues=("${attrvalues[@]#[[:space:]]}")
attrvalues=("${attrvalues[@]%[[:space:]]}")
printf "\t$attrname = %s\n" "${attrvalues[@]}"
}
pkgbuild_extract_to_srcinfo() {
# $1: pkgname
# $2: attr name
# $3: multivalued
local pkgname=$1 attrname=$2 isarray=$3 outvalue=
if pkgbuild_get_attribute "$pkgname" "$attrname" "$isarray" 'outvalue'; then
srcinfo_write_attr "$attrname" "${outvalue[@]}"
fi
}
srcinfo_write_section_details() {
local attr package_arch a
local multivalued_arch_attrs=(source provides conflicts depends replaces
optdepends makedepends checkdepends
{md5,sha{1,224,256,384,512}}sums)
for attr in "${singlevalued[@]}"; do
pkgbuild_extract_to_srcinfo "$1" "$attr" 0
done
for attr in "${multivalued[@]}"; do
pkgbuild_extract_to_srcinfo "$1" "$attr" 1
done
pkgbuild_get_attribute "$1" 'arch' 1 'package_arch'
for a in "${package_arch[@]}"; do
# 'any' is special. there's no support for, e.g. depends_any.
[[ $a = any ]] && continue
for attr in "${multivalued_arch_attrs[@]}"; do
pkgbuild_extract_to_srcinfo "$1" "${attr}_$a" 1
done
done
}
srcinfo_write_global() {
local singlevalued=(pkgdesc pkgver pkgrel epoch url install changelog)
local multivalued=(arch groups license checkdepends makedepends
depends optdepends provides conflicts replaces
noextract options backup
source {md5,sha{1,224,256,384,512}}sums)
srcinfo_open_section 'pkgbase' "${pkgbase:-$pkgname}"
srcinfo_write_section_details ''
srcinfo_close_section
}
srcinfo_write_package() {
local singlevalued=(pkgdesc url install changelog)
local multivalued=(arch groups license checkdepends depends optdepends
provides conflicts replaces options backup)
srcinfo_open_section 'pkgname' "$1"
srcinfo_write_section_details "$1"
srcinfo_close_section
}
srcinfo_write() {
local pkg
srcinfo_write_global
for pkg in "${pkgname[@]}"; do
srcinfo_write_package "$pkg"
done
}
clear_environment() {
local environ
mapfile -t environ < <(compgen -A variable |
grep -xvF "$(printf '%s\n' "$@")")
# expect that some variables marked read only will complain here
unset -v "${environ[@]}" 2>/dev/null
}
srcinfo_write_from_pkgbuild() {(
clear_environment PATH
shopt -u extglob
. "$1" || exit 1
shopt -s extglob
srcinfo_write
)}
usage() {
printf '%s\n' \
'mksrcinfo v8' \
'' \
'mksrcinfo reads the target PKGBUILD and writes an equivalent .SRCINFO.' \
'Without passing any arguments, mksrcinfo will read from $PWD/PKGBUILD' \
'and write to $PWD/.SRCINFO.' \
'' \
'Usage: mksrcinfo [/path/to/pkgbuild]' \
' -h display this help message and exit' \
' -o <file> write output to <file>'
}
error() {
printf "==> ERROR: $1\n" "${@:2}" >&2
}
die() {
error "$@"
exit 1
}
write_srcinfo_header() {
local timefmt='%a %b %e %H:%M:%S %Z %Y'
# fiddle with the environment to ensure we get the a consistent language and
# timezone.
TZ=UTC LC_TIME=C \
printf "# Generated by mksrcinfo %s\n# %($timefmt)T\n" 'v8' -1
}
srcinfo_dest=$PWD/.SRCINFO
while getopts ':o:h' flag; do
case $flag in
o)
srcinfo_dest=$OPTARG
;;
:)
die "option '-%s' requires an argument" "$OPTARG"
;;
h)
usage
exit 0
;;
\?)
die "invalid option -- '-%s' (use -h for help)" "$OPTARG"
;;
esac
done
shift $(( OPTIND - 1 ))
[[ -f PKGBUILD ]] || die 'PKGBUILD not found in current directory'
# TODO: replace this with 'makepkg --printsrcinfo' once makepkg>=4.3 is released.
{
write_srcinfo_header
srcinfo_write_from_pkgbuild "${1:-$PWD/PKGBUILD}"
} >"$srcinfo_dest"
# vim: set et ts=2 sw=2: