debian-cd-clone/tools/merge_package_lists

148 lines
4.6 KiB
Bash
Executable File

#!/bin/sh
#
# merge_package_lists
#
# Quick, hacky script to merge the package lists for multiple arches
# together, with 2 priorities:
#
# 1. keep the ordering of the original files wherever possible
# 2. collect together instances of the same package on multiple arches
#
# expects multiple files containing lines of the form, one arch per file
#
# <arch>:<pkgname>
#
# and will output similar
#
# The files MUST be passed by filename rather than simply piped in,
# otherwise the ordering constraint will be lost
#
# Things also get quite complicated here due to considering
# source. Depending on how things are being run:
#
# 1. If we're not doing source, life is easy - simply interleave the
# binary packages
# 2. If we're *only* doing source, then we won't be called at all -
# the Makefile will just dump the sources directly into "packages"
# without needing our help
# 3. If we're doing mixed source/binary discs, then we have to work
# quite hard here. We generate the list of sources from the
# binaries given to us. For each binary, we will attempt to place
# its source *first* onto the disc so we can make nice GPL-compliant
# media. However, we also need to check whether or not that source
# has already been placed due to an *earlier* binary package (a
# different binary built from the same source, or the same for
# another arch). To allow us to so that, we need to parse the Sources
# files first to build up the src<->bin relationship. Ick... :-/
#
# An added bit of grot: to make sure that sources are placed first, we
# *temporarily* call the source architecture "aaaaaaaaaaaaaaaaaa" to force
# it to sort first, then replace it woth "source" again later. *grin*
#
# Steve McIntyre <steve@einval.com> 2006, GPL v2
BDIR=$1
ADIR=$2
ARCHES="$3"
OUT="$4"
case "$ARCHES" in
*source*) source=yes;;
*) source=no;;
esac
for ARCH in $ARCHES_NOSRC
do
list="$list $BDIR/packages.$ARCH"
done
echo "# Starting merge at "`date` >> $BDIR/list.mid
if [ $source = "yes" ] ; then
echo "DONEDONE" > $BDIR/DONE
awk '
# First parse the Sources files
/^Package:/ {
srcname=$2
srcs_done++
}
/^Binary:/ {
bins=$0
gsub("^Binary:","",bins)
gsub(",","",bins)
nb=split(bins, binarray)
for (i=1; i <= nb; i++) {
bin2src[binarray[i]] = srcname
bins_done++
}
}
# Done reading the Sources
/^DONEDONE/ {
parsed=1
printf("# Parsed Sources files: %d sources producing %d binaries\n", srcs_done, bins_done)
next
}
# Now start placing source packages, depending on the order of the binary packages
/.*/ {
if (parsed) {
split($0,fields,":")
arch=fields[1]
pkg=fields[2]
source=bin2src[pkg]
if (!included[source]) {
printf("# Adding source %s at %d because of %s:%s\n",
source, FNR, arch, pkg)
included[source] = pkg
incarch[source] = arch
indexnr[source] = FNR
} else {
if (FNR < indexnr[source]) {
printf("# Updating source %s: was due to %d:%s:%s, now moved earlier because of %d:%s:%s\n",
source, indexnr[source],
incarch[source], included[source],
FNR, arch, pkg);
included[source] = pkg
incarch[source] = arch
indexnr[source] = FNR
} else {
printf("# Not adding pkg %s source (%d:%s:%s), already added due to %d:%s:%s\n", pkg, FNR, arch, source, indexnr[source], incarch[source], included[source])
}
}
printf("%d:%s\n", FNR, $0)
}
}
END {
for (source in included) {
printf("%d:aaaaaaaaaaaaaaaaaa:%s\n", indexnr[source], source)
}
}' $ADIR/$CODENAME-source/apt-state/lists/*Sources $BDIR/DONE $list | sort -nk 1 -t : >> $BDIR/list.mid
else
awk '{printf("%d:%s\n", FNR, $0)}' $list | sort -nk 1 -t : >> $BDIR/list.mid
fi
echo "# Ending merge pass 1 at "`date` >> $BDIR/list.mid
# We now have all the files stuck together, with line numbers
# prepended to allow us to shuffle them properly. Remove any comments
# logged from the awk code above, then sort and remove the line numbers
# again
grep -v ^# $BDIR/list.mid | awk -F : '
{
if (!($3 in add))
{
pkgname[number_packages++] = $3
}
gsub("aaaaaaaaaaaaaaaaaa", "source", $2) # Undo the source sorting hack
add[$3] = add[$3] $2 ":" $3 " "
}
END {
for (i = 0; i < number_packages; i++)
{
gsub(" $", "", add[pkgname[i]])
gsub(" ", "\n", add[pkgname[i]])
print add[pkgname[i]]
}
}' > $OUT
echo "# Ending merge pass 2 at "`date` >> $BDIR/list.mid