#! /usr/bin/ksh
|
#
|
#
|
# This file and its contents are supplied under the terms of the
|
# Common Development and Distribution License ("CDDL"), version 1.0.
|
# You may only use this file in accordance with the terms of version
|
# 1.0 of the CDDL.
|
#
|
# A full copy of the text of the CDDL should have accompanied this
|
# source. A copy of the CDDL is also available via the Internet at
|
# http://www.illumos.org/license/CDDL.
|
#
|
|
#
|
# Copyright 2022 Marcel Telka
|
#
|
|
function usage
|
{
|
[[ -n "$1" ]] && printf "ERROR: %s\n\n" "$1"
|
printf "Usage: perl-meta-deps WS_MACH BUILD_DIR [configure|build|test|runtime]... [suggests] PERL_VERSION\n" >&2
|
[[ -n "$1" ]] && exit 1
|
exit 0
|
}
|
|
|
(($# == 0)) && usage
|
|
WS_MACH="$1"
|
[[ -d "$WS_MACH" ]] && shift || usage "WS_MACH does not exist"
|
|
BUILD_DIR="$1"
|
[[ -d "$BUILD_DIR" ]] && shift || usage "BUILD_DIR does not exist"
|
|
PHASES=
|
while true ; do
|
case "$1" in
|
configure|build|test|runtime)
|
PHASES="$PHASES,.$1" && shift ;;
|
*) break ;;
|
esac
|
done
|
PHASES=${PHASES/#,}
|
[[ -z "$PHASES" ]] && PHASES=".configure,.build,.test,.runtime"
|
|
RELATION=".requires,.recommends"
|
[[ "$1" == "suggests" ]] && RELATION=".$1" && shift
|
|
(($# == 0)) && usage "PERL_VERSION missing"
|
PERLVER=$1 && shift
|
PLV=${PERLVER//.}
|
PERL=/usr/perl5/$PERLVER/bin/perl
|
[[ -x "$PERL" ]] || usage "Perl $PERLVER not found"
|
PERL_ARCH=$($PERL -e 'use Config; print $Config{archname}')
|
|
(($# != 0)) && usage "Too many arguments"
|
|
PERL_VERSION_CONVERT="$(dirname $0)/perl-version-convert"
|
[[ ! -x "$PERL_VERSION_CONVERT" ]] && printf "ERROR: perl-version-convert not found" && exit 1
|
|
CACHEDIR="$WS_MACH/perl-meta-deps-cache"
|
mkdir -p "$CACHEDIR"
|
# Remove old entries from the cache
|
find "$CACHEDIR" -type f -mtime +7 -exec rm -f {} \;
|
|
|
/usr/bin/jq -r '.prereqs|'"$PHASES"'|'"$RELATION"'|to_entries?|.[]|.key+" "+(.value|tostring)' | while read PREREQ VERSION ; do
|
# Convert perl version number to pkg(5) compatible form
|
VER=$("$PERL_VERSION_CONVERT" "$PREREQ" "$VERSION")
|
[[ "$VER" != "0" ]] && VER="@$VER" || VER=
|
|
CACHEFILE="$CACHEDIR/$PREREQ-$PERLVER"
|
|
# Resolve the dependency if not in cache already
|
if [[ ! -e "$CACHEFILE" || ("$RELATION" != ".suggests" && ! -s "$CACHEFILE") ]] ; then
|
# We must replace '::' by '-' otherwise 'pkgdepend resolve' fails
|
MANIFEST="$BUILD_DIR/META-${PREREQ//::/-}-$PERLVER"
|
|
# Prepare manifest
|
if [[ "$PREREQ" == "perl" ]] ; then
|
# "perl" is special case
|
cat <<#EOF > "$MANIFEST"
|
depend fmri=__TBD type=require pkg.debug.depend.file=$PREREQ \\
|
pkg.debug.depend.path=usr/perl5/$PERLVER/bin
|
EOF
|
else
|
cat <<#EOF > "$MANIFEST"
|
depend fmri=__TBD type=require pkg.debug.depend.file=${PREREQ//:://}.pm \\
|
pkg.debug.depend.path=usr/perl5/$PERLVER/lib \\
|
pkg.debug.depend.path=usr/perl5/$PERLVER/lib/$PERL_ARCH \\
|
pkg.debug.depend.path=usr/perl5/vendor_perl/$PERLVER \\
|
pkg.debug.depend.path=usr/perl5/vendor_perl/$PERLVER/$PERL_ARCH
|
EOF
|
fi
|
|
# Resolve dependency
|
if /usr/bin/pkgdepend resolve "$MANIFEST" ; then
|
# Remove version number and cache the result
|
cat "$MANIFEST.res" | sed -e 's/@[^ ]*//g' -e 's/-'$PLV'/-$(PLV)/g' > "$CACHEFILE"
|
else
|
if [[ "$RELATION" != ".suggests" ]] ; then
|
printf "ERROR: Prerequisite %s not found\n" "$PREREQ" >&2
|
cat "$MANIFEST"
|
fi
|
# Cache negative result
|
[[ ! -e "$CACHEFILE" ]] && > "$CACHEFILE"
|
fi
|
fi
|
|
# Use cached result, add required version number and drop runtime/perl
|
cat "$CACHEFILE" | sed -e 's/\(fmri=[^ ]*\)/\1'$VER'/g' -e '/fmri=pkg:\/runtime\/perl-\$(PLV)/d'
|
done | /usr/bin/pkgfmt -u | uniq | (
|
PREV_LINE_H=
|
PREV_FMRI=
|
PREV_VER=
|
PREV_LINE_T=
|
while read LINE ; do
|
# Copy verbatim lines without "fmri=pkg:" (e.g. unresolved lines)
|
[[ "${LINE//*fmri=pkg:*/FMRI}" != "FMRI" ]] && printf "%s\n" "$LINE" && continue
|
|
LINE_H=${LINE%%fmri=*}
|
LINE_T=${LINE#*fmri=}
|
FMRI=${LINE_T%% *}
|
LINE_T=${LINE_T#* }
|
[[ "$FMRI" == "$LINE_T" ]] && LINE_T=
|
VER=${FMRI##*@}
|
FMRI=${FMRI%%@*}
|
[[ "$FMRI" == "$VER" ]] && VER=
|
[[ -n "$VER" ]] && VER="@$VER"
|
FMRI="fmri=$FMRI"
|
|
if [[ "$PREV_LINE_H" != "$LINE_H" || "$PREV_FMRI" != "$FMRI" || "$PREV_LINE_T" != "$LINE_T" ]] ; then
|
[[ -n "$PREV_LINE_H$PREV_FMRI$PREV_VER$PREV_LINE_T" ]] && printf "%s%s%s%s\n" "$PREV_LINE_H" "$PREV_FMRI" "$PREV_VER" "$PREV_LINE_T"
|
PREV_LINE_H="$LINE_H"
|
PREV_FMRI="$FMRI"
|
PREV_VER="$VER"
|
PREV_LINE_T="$LINE_T"
|
continue
|
fi
|
|
# Select higher version
|
VER1=${PREV_VER#@}
|
VER2=${VER#@}
|
while true ; do
|
[[ -z "$VER1" ]] && PREV_VER="$VER" && break
|
[[ -z "$VER2" ]] && break
|
|
V1=${VER1%%.*} ; [[ "$V1" == "$VER1" ]] && VER1="$VER1."
|
V2=${VER2%%.*} ; [[ "$V2" == "$VER2" ]] && VER2="$VER2."
|
|
((V1 < V2)) && PREV_VER="$VER" && break
|
((V1 > V2)) && break
|
|
VER1=${VER1#*.}
|
VER2=${VER2#*.}
|
done
|
done
|
[[ -n "$PREV_LINE_H$PREV_FMRI$PREV_VER$PREV_LINE_T" ]] && printf "%s%s%s%s\n" "$PREV_LINE_H" "$PREV_FMRI" "$PREV_VER" "$PREV_LINE_T"
|
)
|
|
exit 0
|