From 11913f259bd613261d3ccc0301874e26a4dcdbab Mon Sep 17 00:00:00 2001
From: Andreas Wacknitz <A.Wacknitz@gmx.de>
Date: Sun, 31 Mar 2024 18:36:29 +0200
Subject: [PATCH] nodejs-18: update to 18.20.0

---
 tools/python-integrate-project |  351 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 222 insertions(+), 129 deletions(-)

diff --git a/tools/python-integrate-project b/tools/python-integrate-project
index b1f98ca..63ea6f6 100755
--- a/tools/python-integrate-project
+++ b/tools/python-integrate-project
@@ -26,21 +26,23 @@
 function usage
 {
 	[[ -n "$1" ]] && printf "ERROR: %s\n\n" "$1" >&2
-	printf "Usage: %s [-d DIR] [-l VERSION] [-o OBSOLETE].. [-u] PROJECT\n" "$THIS" >&2
+	printf "Usage: %s [-d DIR] [-f] [-l VERSION] [-o OBSOLETE].. [-u] PROJECT\n" "$THIS" >&2
 	[[ -n "$1" ]] && exit 1
 	exit 0
 }
 
 
-VERSION=
+OPT_VERSION=
 OBSOLETE=
 UPGRADE_ONLY=0
 DIRECTORY=
-while getopts ":hd:l:o:u" OPT ; do
+FORCE=0
+while getopts ":hd:fl:o:u" OPT ; do
 	case "$OPT" in
 	"?"|"h")	usage ;;
 	"d")		DIRECTORY="$OPTARG" ;;
-	"l")		VERSION="$OPTARG" ;;
+	"f")		FORCE=1 ;;
+	"l")		OPT_VERSION="$OPTARG" ;;
 	"o")		OBSOLETE="$OBSOLETE $OPTARG" ;;
 	"u")		UPGRADE_ONLY=1 ;;
 	esac
@@ -67,13 +69,6 @@
 [[ -d "$BASE_DIR" ]] || usage "Directory $BASE_DIR not found"
 
 
-# Get data from pypi
-PYPI_PROJECT=$($CURL "$APIURL/$PROJECT/json")
-if (($? != 0)) || [[ -z "$PYPI_PROJECT" ]] ; then
-	printf "FATAL: Failed to get data from pypi\n" >&2
-	exit 1
-fi
-
 # Distribution match project
 DISTRIBUTION="$PROJECT"
 
@@ -81,47 +76,14 @@
 {
 	typeset ENTRY="$1"
 
-	[[ -f "$SOURCE_DIR/PKG-INFO" ]] || return
+	[[ -f "$SOURCE_DIR$COMPONENT_SUBDIR/PKG-INFO" ]] || return
 
-	cat "$SOURCE_DIR/PKG-INFO" \
+	cat "$SOURCE_DIR$COMPONENT_SUBDIR/PKG-INFO" \
 		| sed -e '/^$/,$d' \
 		| awk 'END{printf("\n")}/^[^:]+: /{$0="\n"$0}1' ORS=' ' \
 		| grep "^$ENTRY: " \
 		| sed -e "s/^$ENTRY: //" -e 's/ *$//'
 }
-
-# Get project homepage
-HOMEPAGE=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.home_page')
-if (($? != 0)) || [[ -z "$HOMEPAGE" || "$HOMEPAGE" == "null" ]] ; then
-	HOMEPAGE=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.project_urls.Homepage')
-	if (($? != 0)) || [[ -z "$HOMEPAGE" || "$HOMEPAGE" == "null" ]] ; then
-		printf "WARNING: Failed to get homepage for project %s from pypi\n" "$PROJECT" >&2
-		HOMEPAGE=$(get_PKGINFO_entry "Home-page")
-	fi
-fi
-
-# Find the latest version if not provided by user
-if [[ -z "$VERSION" ]] ; then
-	VERSION=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.version')
-	if (($? != 0)) || [[ -z "$VERSION" || "$VERSION" == "null" ]] ; then
-		printf "FATAL: Failed to get version for project %s from pypi\n" "$PROJECT" >&2
-		exit 1
-	fi
-fi
-
-# Get release data from pypi
-PYPI_PROJECT_RELEASE=$($CURL "$APIURL/$PROJECT/$VERSION/json")
-if (($? != 0)) || [[ -z "$PYPI_PROJECT_RELEASE" ]] ; then
-	printf "FATAL: Failed to get data for version %s from pypi\n" "$VERSION" >&2
-	exit 1
-fi
-
-# Get download url
-DOWNLOAD_URL=$(printf "%s" "$PYPI_PROJECT_RELEASE" | /usr/bin/jq -r '.urls[]|select(.packagetype=="sdist")|.url')
-if (($? != 0)) || [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]] ; then
-	printf "WARNING: Failed to get download url for project %s, version %s from pypi\n" "$PROJECT" "$VERSION" >&2
-	DOWNLOAD_URL=
-fi
 
 
 # Prepare the directory
@@ -132,15 +94,52 @@
 git restore --staged . > /dev/null 2>&1
 git checkout . > /dev/null 2>&1
 
+
+# Following variables could be set by the hook-begin snippet
+VERSION=
+HOMEPAGE=
+DOWNLOAD_URL=
+LICENSE_FILE=
+SUMMARY=
+
+# Execute hook-begin snippet
+if [[ -f "$CONF" ]] ; then
+	gsed -e '0,/^%hook-begin%/d' -e '/^%/,$d' < "$CONF" > "$SNIPPET"
+	. "./$SNIPPET"
+	rm -f "$SNIPPET"
+fi
+
+# Version specified as option takes precedence
+[[ -n "$OPT_VERSION" ]] && VERSION="$OPT_VERSION"
+
+
+# Get data from PyPI if needed
+if [[ -z "$VERSION" || -z "$HOMEPAGE" || -z "$SUMMARY" ]] ; then
+	PYPI_PROJECT=$($CURL "$APIURL/$PROJECT/json")
+	if (($? != 0)) || [[ -z "$PYPI_PROJECT" ]] ; then
+		printf 'WARNING: Failed to get data for project %s from PyPI\n' "$PROJECT" >&2
+		PYPI_PROJECT=
+	fi
+fi
+
+
+# Find the latest version if not already provided
+if [[ -z "$VERSION" ]] ; then
+	VERSION=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.version')
+	if (($? != 0)) || [[ -z "$VERSION" || "$VERSION" == "null" ]] ; then
+		printf "FATAL: Failed to get version for project %s from pypi\n" "$PROJECT" >&2
+		exit 1
+	fi
+fi
+
+
 # Is this new project, or just a rebuild?
 NEW=1
-REBUILD=0
 PREV_VER=
 PREV_HVER=
 PREV_REV=0
 if git ls-files --error-unmatch Makefile > /dev/null 2>&1 ; then
 	NEW=0
-	REBUILD=1
 	PREV_VER=$($GMAKE print-value-COMPONENT_VERSION 2>/dev/null)
 	(($? != 0)) && printf "FATAL: 'gmake print-value-COMPONENT_VERSION' failed!\n" >&2 && exit 1
 	PREV_REV=$($GMAKE print-value-COMPONENT_REVISION 2>/dev/null)
@@ -150,38 +149,86 @@
 	PREV_HVER=$($GMAKE print-value-HUMAN_VERSION 2>/dev/null)
 	((UPGRADE_ONLY)) && [[ "$PREV_HVER" == "$VERSION" ]] && exit 0
 
+	# Pre-flight environment checks
+	if ((FORCE == 0)) ; then
+		! $GMAKE env-check > /dev/null 2>&1 && printf "FATAL: Pre-flight 'gmake env-check' failed!\n" >&2 && exit 1
+		if [[ "$($GMAKE print-value-PYTHON_TEST_BOOTSTRAP)" != "yes" ]] ; then
+			! $GMAKE test-env-check > /dev/null 2>&1 && printf "FATAL: Pre-flight 'gmake test-env-check' failed!\n" >&2 && exit 1
+		fi
+	fi
+
 	$GMAKE clobber > /dev/null 2>&1
 fi
 
-# Remove everything from git (except known patches, history, and $CONF)
-touch "$CONF"
-grep "^%patch%" "$CONF" | while read TAG PATCH ; do rm -f "patches/$PATCH" ; done
+
+# Get project homepage if not already provided
+if [[ -z "$HOMEPAGE" ]] ; then
+	HOMEPAGE=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.home_page')
+	if (($? != 0)) || [[ -z "$HOMEPAGE" || "$HOMEPAGE" == "null" ]] ; then
+		HOMEPAGE=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.project_urls.Homepage')
+		if (($? != 0)) || [[ -z "$HOMEPAGE" || "$HOMEPAGE" == "null" ]] ; then
+			printf "WARNING: Failed to get homepage for project %s from pypi\n" "$PROJECT" >&2
+			HOMEPAGE=$(get_PKGINFO_entry "Home-page")
+		fi
+	fi
+fi
+
+# Get download url if not already provided
+if [[ -z "$DOWNLOAD_URL" ]] ; then
+	# Get release data from pypi
+	PYPI_PROJECT_RELEASE=$($CURL "$APIURL/$PROJECT/$VERSION/json")
+	if (($? != 0)) || [[ -z "$PYPI_PROJECT_RELEASE" ]] ; then
+		printf "FATAL: Failed to get data for version %s from pypi\n" "$VERSION" >&2
+		exit 1
+	fi
+
+	# Get download url
+	DOWNLOAD_URL=$(printf "%s" "$PYPI_PROJECT_RELEASE" | /usr/bin/jq -r '.urls[]|select(.packagetype=="sdist")|.url')
+	if (($? != 0)) || [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]] ; then
+		printf "WARNING: Failed to get download url for project %s, version %s from pypi\n" "$PROJECT" "$VERSION" >&2
+		DOWNLOAD_URL=
+	fi
+fi
+
+
+# Remove everything that is not in git
+rm -rf *
+git checkout . > /dev/null 2>&1
+# Remove everything from git (except known patches, files, history, and $CONF)
+[[ -f "$CONF" ]] && grep "^%patch%" "$CONF" | while read TAG PATCH ; do rm -f "patches/$PATCH" ; done
+[[ -f "$CONF" ]] && grep "^%file%" "$CONF" | while read TAG FILE ; do rm -f "files/$FILE" ; done
 rm -f history "$CONF"
 find . -type f | while read f ; do git rm "$f" > /dev/null 2>&1 ; done
 rm -rf "$DIR" 2>/dev/null
 git checkout history > /dev/null 2>&1
 git checkout "$CONF" > /dev/null 2>&1
-touch "$CONF"
-grep "^%patch%" "$CONF" | while read TAG PATCH ; do
+[[ -f "$CONF" ]] && grep "^%patch%" "$CONF" | while read TAG PATCH ; do
 	git checkout "patches/$PATCH" > /dev/null 2>&1
 	[[ -f "patches/$PATCH" ]] || printf "WARNING: Patch %s not found\n" "$PATCH" >&2
+done
+[[ -f "$CONF" ]] && grep "^%file%" "$CONF" | while read TAG FILE ; do
+	git checkout "files/$FILE" > /dev/null 2>&1
+	[[ -f "files/$FILE" ]] || printf "WARNING: File %s not found\n" "$FILE" >&2
 done
 
 
 # Makefile template
+GENERATE_CMD="\$WS_TOOLS/$THIS"
+[[ "$DIRECTORY" != "python/$DISTRIBUTION" ]] && GENERATE_CMD="$GENERATE_CMD -d $DIRECTORY"
+GENERATE_CMD="$GENERATE_CMD $PROJECT"
 (
 cat $WS_TOP/transforms/copyright-template | sed -e '/^$/,$d'
 cat <<EOF
 
 #
 # This file was automatically generated using the following command:
-#   \$WS_TOOLS/$THIS $PROJECT
+#   $GENERATE_CMD
 #
 
 BUILD_STYLE = pyproject
 USE_COMMON_TEST_MASTER = no
 EOF
-gsed -e '0,/^%include-1%/d' -e '/^%/,$d' < "$CONF"
+[[ -f "$CONF" ]] && gsed -e '0,/^%include-1%/d' -e '/^%/,$d' < "$CONF"
 cat <<EOF
 
 include ../../../make-rules/shared-macros.mk
@@ -192,7 +239,7 @@
 COMPONENT_SUMMARY =		$PROJECT - TODO
 EOF
 [[ -n "$HOMEPAGE" ]] && printf "COMPONENT_PROJECT_URL =\t\t%s\n" "$HOMEPAGE"
-[[ -n "$DOWNLOAD_URL" ]] && printf 'COMPONENT_ARCHIVE_URL =\t\t\\\n\t%s\n' "$DOWNLOAD_URL"
+[[ -n "$DOWNLOAD_URL" ]] && printf 'DOWNLOAD_URL =\t\t\\\n\t%s\n' "$DOWNLOAD_URL"
 cat <<EOF
 COMPONENT_ARCHIVE_HASH =	\\
 	sha256:TODO
@@ -201,15 +248,34 @@
 
 _TEST_STYLE = TODO
 EOF
-cat "$CONF" | gsed -e '0,/^%include-2%/d' -e '/^%/,$d' | gsed -e '1s/^./\n&/'
+[[ -f "$CONF" ]] && cat "$CONF" | gsed -e '0,/^%include-2%/d' -e '/^%/,$d' | gsed -e '1s/^./\n&/'
 printf "\ninclude \$(WS_MAKE_RULES)/common.mk\n"
-cat "$CONF" | gsed -e '0,/^%include-3%/d' -e '/^%/,$d' | gsed -e '1s/^./\n&/'
+[[ -f "$CONF" ]] && cat "$CONF" | gsed -e '0,/^%include-3%/d' -e '/^%/,$d' | gsed -e '1s/^./\n&/'
 printf "\n"
 ) > Makefile
 
+# If the automatically constructed COMPONENT_ARCHIVE_URL points to the same
+# location as DOWNLOAD_URL then we should use it
+if [[ -n "$DOWNLOAD_URL" ]] ; then
+	COMPONENT_ARCHIVE_URL=$($GMAKE print-value-COMPONENT_ARCHIVE_URL)
+	[[ "$COMPONENT_ARCHIVE_URL" == "$DOWNLOAD_URL" ]] && DOWNLOAD_URL=
+fi
+# The default COMPONENT_ARCHIVE_URL usually redirects to DOWNLOAD_URL so check
+# that too
+if [[ -n "$DOWNLOAD_URL" ]] ; then
+	[[ $($CURL --head --write-out "%{redirect_url}\n" --output /dev/null \
+	    "$COMPONENT_ARCHIVE_URL") == "$DOWNLOAD_URL" ]] && DOWNLOAD_URL=
+fi
+# Use either DOWNLOAD_URL or default COMPONENT_ARCHIVE_URL
+if [[ -n "$DOWNLOAD_URL" ]] ; then
+	sed -i -e $'s/^DOWNLOAD_URL =/COMPONENT_ARCHIVE_URL =/' Makefile
+else
+	sed -i -e $'/^DOWNLOAD_URL =/,+1d' Makefile
+fi
+
 # Remove COMPONENT_REVISION if not needed
 COMPONENT_VERSION=$($GMAKE print-value-COMPONENT_VERSION)
-[[ "$PREV_VER" != "$COMPONENT_VERSION" ]] && REBUILD=0 && sed -i -e '/^COMPONENT_REVISION/d' Makefile
+[[ "$PREV_VER" != "$COMPONENT_VERSION" ]] && sed -i -e '/^COMPONENT_REVISION/d' Makefile
 git add Makefile
 
 # Calculate sham256 sum for source package
@@ -221,21 +287,39 @@
 sed -i -e 's/sha256:TODO/sha256:'"$SHA256"'/g' Makefile
 git add Makefile
 
-# Unpack sources
+# Unpack sources and apply patches
+! $GMAKE patch > /dev/null 2>&1 && printf "FATAL: 'gmake patch' failed!\n" >&2 && exit 1
+
+# Refresh patches
+if $GMAKE refresh-patches > /dev/null 2>&1 ; then
+	git add patches 2>/dev/null
+else
+	printf "ERROR: 'gmake refresh-patches' failed!\n" >&2
+	git checkout patches 2>/dev/null
+fi
+
+# Cleanup after patch refresh
+$GMAKE clobber > /dev/null 2>&1
+
+# Prepare sources
 ! $GMAKE prep > /dev/null 2>&1 && printf "FATAL: 'gmake prep' failed!\n" >&2 && exit 1
 SOURCE_DIR=$($GMAKE print-value-SOURCE_DIR)
+COMPONENT_SUBDIR=$($GMAKE print-value-COMPONENT_SUBDIR)
+[[ -n "$COMPONENT_SUBDIR" ]] && COMPONENT_SUBDIR="/$COMPONENT_SUBDIR"
 
-if [[ ! -f "$SOURCE_DIR/pyproject.toml" ]] ; then
-	[[ ! -f "$SOURCE_DIR/setup.py" ]] && printf "FATAL: Neither pyproject.toml nor setup.py found!\n" >&2 && exit 1
+if [[ ! -f "$SOURCE_DIR$COMPONENT_SUBDIR/pyproject.toml" ]] ; then
+	[[ ! -f "$SOURCE_DIR$COMPONENT_SUBDIR/setup.py" ]] && printf "FATAL: Neither pyproject.toml nor setup.py found!\n" >&2 && exit 1
 	sed -i -e 's/^\(BUILD_STYLE = \).*$/\1setup.py/' Makefile
 fi
 
-# Get summary
-SUMMARY=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.summary')
-if (($? != 0)) || [[ -z "$SUMMARY" || "$SUMMARY" == "null" ]] ; then
-	printf "WARNING: Failed to get summary for project %s from pypi\n" "$PROJECT" >&2
-	SUMMARY=$(get_PKGINFO_entry "Summary")
-	[[ -z "$SUMMARY" ]] && SUMMARY="TODO"
+# Get summary if not already provided
+if [[ -z "$SUMMARY" ]] ; then
+	SUMMARY=$(printf "%s" "$PYPI_PROJECT" | /usr/bin/jq -r '.info.summary')
+	if (($? != 0)) || [[ -z "$SUMMARY" || "$SUMMARY" == "null" ]] ; then
+		printf "WARNING: Failed to get summary for project %s from pypi\n" "$PROJECT" >&2
+		SUMMARY=$(get_PKGINFO_entry "Summary")
+		[[ -z "$SUMMARY" ]] && SUMMARY="TODO"
+	fi
 fi
 # Summary needs to be sanitized
 SUMMARY="${SUMMARY//\`/\\\\\`}"
@@ -259,11 +343,11 @@
 
 LICENSE=
 LICFILE=
-for f in $(get_PKGINFO_entry "License-File") LICENSE LICENSE.rst LICENSE.txt ; do
-	[[ -f "$SOURCE_DIR/$f" ]] || continue
+for f in $LICENSE_FILE $(get_PKGINFO_entry "License-File") LICENSE LICENSE.rst LICENSE.txt ; do
+	[[ -f "$SOURCE_DIR$COMPONENT_SUBDIR/$f" ]] || continue
 	LICFILE="$f"
 
-	detect_license LICENSE "$SOURCE_DIR/$LICFILE"
+	detect_license LICENSE "$SOURCE_DIR$COMPONENT_SUBDIR/$LICFILE"
 	[[ -n "$LICENSE" ]] && break
 
 	printf "WARNING: Failed to detect license type in %s file\n" "$f" >&2
@@ -276,9 +360,11 @@
 
 if [[ -z "$LICENSE" ]] ; then
 	# Execute hook-no-license snippet
-	gsed -e '0,/^%hook-no-license%/d' -e '/^%/,$d' < "$CONF" > "$SNIPPET"
-	. "./$SNIPPET"
-	rm -f "$SNIPPET"
+	if [[ -f "$CONF" ]] ; then
+		gsed -e '0,/^%hook-no-license%/d' -e '/^%/,$d' < "$CONF" > "$SNIPPET"
+		. "./$SNIPPET"
+		rm -f "$SNIPPET"
+	fi
 
 	if [[ -f "$DISTRIBUTION.license" ]] ; then
 		sed -i -e '/^COMPONENT_LICENSE_FILE/d' Makefile
@@ -294,13 +380,19 @@
 
 # detect TEST_STYLE
 TEST_STYLE=
-cd "$SOURCE_DIR"
+cd "$SOURCE_DIR$COMPONENT_SUBDIR"
 while true ; do
 	TOX_OUT=$(tox -l)
 	TOX_RET=$?
 	((TOX_RET == 0)) && ! printf "%s" "$TOX_OUT" | grep -q 'assuming empty tox\.ini' && TEST_STYLE="tox" && break
 
-	pytest -p no:checkdocs --setup-plan
+	# Disable some pytest plugins that almost always collects tests to run
+	# even there are no pytest tests available otherwise.
+	#
+	# The system-statistics plugin is disabled because it often causes the
+	# pytest to fail.
+	# See also https://github.com/saltstack/pytest-system-statistics/issues/4
+	pytest -p no:black -p no:checkdocs -p no:cov -p no:mypy -p no:relaxed -p no:system-statistics --setup-plan
 	(($? != 5)) && TEST_STYLE="pytest" && break
 
 	[[ -f setup.py ]] && python setup.py test --help && TEST_STYLE="setup.py" && break
@@ -327,10 +419,10 @@
 fi
 
 # Warn if a testing tool is called directly by tox
-if [[ "$($GMAKE print-value-TEST_STYLE)" == "tox" && -f "$SOURCE_DIR/tox.ini" ]] ; then
+if [[ "$($GMAKE print-value-TEST_STYLE)" == "tox" && -f "$SOURCE_DIR$COMPONENT_SUBDIR/tox.ini" ]] ; then
 	TOX_CALL_INDIRECTLY=$($GMAKE print-value-TOX_CALL_INDIRECTLY)
 	for p in $TOX_CALL_INDIRECTLY ; do
-		sed -n -e '/^commands *=/,/^$/p' "$SOURCE_DIR/tox.ini" \
+		sed -n -e '/^commands *=/,/^$/p' "$SOURCE_DIR$COMPONENT_SUBDIR/tox.ini" \
 			| tr '\t' ' ' \
 			| grep -q '^\(commands *=\)\{0,1\} *'"$p"'\( \{1,\}.*\)\{0,1\}$' \
 		&& printf "WARNING: %s is called directly in tox.ini\n" "$p" >&2
@@ -349,17 +441,14 @@
 		> "$MANIFEST"
 
 	# Execute hook-manifest snippet
-	gsed -e '0,/^%hook-manifest%/d' -e '/^%/,$d' < "$CONF" > "$SNIPPET"
-	. "./$SNIPPET"
-	rm -f "$SNIPPET"
+	if [[ -f "$CONF" ]] ; then
+		gsed -e '0,/^%hook-manifest%/d' -e '/^%/,$d' < "$CONF" > "$SNIPPET"
+		. "./$SNIPPET"
+		rm -f "$SNIPPET"
+	fi
 
 	git add manifests/sample-manifest.p5m $MANIFEST
 fi
-
-
-# $CONF is no longer needed
-rm -f "$CONF"
-git checkout "$CONF" > /dev/null 2>&1
 
 
 # Generate REQUIRED_PACKAGES
@@ -374,6 +463,36 @@
 # Make sure the build environment is setup properly and we do have all
 # requirements installed.  Otherwise we cannot continue.
 ! $GMAKE env-check > /dev/null 2>&1 && printf "FATAL: 'gmake env-check' failed!\n" >&2 && exit 1
+
+
+# Handle history
+COMPONENT_FMRI=$($GMAKE print-value-COMPONENT_FMRI)
+PYTHON_VERSIONS_OBSOLETING=$($GMAKE print-value-PYTHON_VERSIONS_OBSOLETING)
+OV=
+OV_PLURAL=
+for o in $(echo $OBSOLETE $PYTHON_VERSIONS_OBSOLETING | LC_ALL=C sort -u) ; do
+	PYV=${o//.}
+	FMRI=$(pkg list -nvH "$COMPONENT_FMRI-$PYV" 2>/dev/null | egrep -v '(o|r)$' | sed -e 's|^.*\('"$COMPONENT_FMRI"'\)|\1|g' -e 's/:[^:]*$//g' -e 's/\(-[^-]*\)$/,5.11\1/g')
+	[[ -n "$FMRI" ]] || continue
+	FMRI_H=${FMRI%.*}
+	FMRI_T=${FMRI##*.}
+	if [[ "$FMRI_H" == "$FMRI" ]] ; then
+		printf "WARNING: Wrong fmri format: %s\n" "$FMRI" >&2
+		continue
+	fi
+	FMRI_T=$((FMRI_T + 1))
+	printf "%s.%s noincorporate\n" "$FMRI_H" "$FMRI_T" >> history
+
+	[[ -n "$OV" ]] && OV="${OV/ and /, } and " && OV_PLURAL="s"
+	OV="$OV$o"
+done
+if [[ -f history ]] ; then
+	LC_ALL=C sort -u history > history.new
+	mv history.new history
+	git add history
+
+	awk '$NF == "noincorporate" {printf("WARNING: Unincorporated package: %s\n", $1)}' < history >&2
+fi
 
 
 # Cleanup before we try to publish to make sure there are no leftovers from
@@ -452,56 +571,30 @@
 fi
 
 
-# Handle history
-COMPONENT_FMRI=$($GMAKE print-value-COMPONENT_FMRI)
-PYTHON_VERSIONS_OBSOLETING=$($GMAKE print-value-PYTHON_VERSIONS_OBSOLETING)
-OV=
-OV_PLURAL=
-for o in $(echo $OBSOLETE $PYTHON_VERSIONS_OBSOLETING | LC_ALL=C sort -u) ; do
-	PYV=${o//.}
-	FMRI=$(pkg list -nvH "$COMPONENT_FMRI-$PYV" 2>/dev/null | egrep -v '(o|r)$' | sed -e 's|^.*\('"$COMPONENT_FMRI"'\)|\1|g' -e 's/:[^:]*$//g' -e 's/\(-[^-]*\)$/,5.11\1/g')
-	[[ -n "$FMRI" ]] || continue
-	FMRI_H=${FMRI%.*}
-	FMRI_T=${FMRI##*.}
-	if [[ "$FMRI_H" == "$FMRI" ]] ; then
-		printf "WARNING: Wrong fmri format: %s\n" "$FMRI" >&2
-		continue
-	fi
-	FMRI_T=$((FMRI_T + 1))
-	printf "%s.%s noincorporate\n" "$FMRI_H" "$FMRI_T" >> history
-
-	[[ -n "$OV" ]] && OV="$OV and " && OV_PLURAL="s"
-	OV="$OV$o"
-done
-if [[ -f history ]] ; then
-	LC_ALL=C sort -u history > history.new
-	mv history.new history
-	git add history
-fi
-
-
 # Construct the commit message
 MSG=
 if ((NEW)) ; then
-	MSG="Add $PROJECT python project"
+	MSG="Add $PROJECT Python project"
 else
-	if ((REBUILD == 0)) ; then
-		[[ "$PREV_HVER" != "$VERSION" ]] && MSG="update to $VERSION" || MSG="change version format"
-	fi
-
-	NV=
-	for v in $PYTHON_VERSIONS ; do
-		PYV=${v//.}
-		pkg list -avH "$COMPONENT_FMRI-$PYV" 2>/dev/null | egrep -q -v '(o|r)$' && continue
-		[[ -n "$NV" ]] && NV="$NV and "
-		NV="$NV$v"
-	done
+	[[ "$PREV_VER" != "$COMPONENT_VERSION" ]] && MSG="change version format"
+	[[ "$PREV_HVER" != "$VERSION" ]] && MSG="update to $VERSION"
 
 	REBUILDMSG=
-	[[ -n "$NV" ]] && REBUILDMSG="rebuild for python $NV"
+
+	if [[ "$($GMAKE print-value-SINGLE_PYTHON_VERSION)" == "no" ]] ; then
+		NV=
+		for v in $PYTHON_VERSIONS ; do
+			PYV=${v//.}
+			pkg list -avH "$COMPONENT_FMRI-$PYV" 2>/dev/null | egrep -q -v '(o|r)$' && continue
+			[[ -n "$NV" ]] && NV="$NV and "
+			NV="$NV$v"
+		done
+		[[ -n "$NV" ]] && REBUILDMSG="rebuild for Python $NV"
+	fi
+
 	if [[ -n "$OV" ]] ; then
-		[[ -n "$REBUILDMSG" ]] && REBUILDMSG="$REBUILDMSG and" || REBUILDMSG="rebuild"
-		REBUILDMSG="$REBUILDMSG to get package$OV_PLURAL for python $OV obsoleted"
+		[[ -n "$REBUILDMSG" ]] && REBUILDMSG="$REBUILDMSG and "
+		REBUILDMSG="${REBUILDMSG}obsolete package$OV_PLURAL for Python $OV"
 	fi
 
 	if [[ -n "$REBUILDMSG" ]] ; then

--
Gitblit v1.9.3