summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/ghc-bin/files/ghc-updater')
-rwxr-xr-xdev-lang/ghc-bin/files/ghc-updater329
1 files changed, 329 insertions, 0 deletions
diff --git a/dev-lang/ghc-bin/files/ghc-updater b/dev-lang/ghc-bin/files/ghc-updater
new file mode 100755
index 000000000000..32e3343c88ca
--- /dev/null
+++ b/dev-lang/ghc-bin/files/ghc-updater
@@ -0,0 +1,329 @@
+#!/bin/sh
+#
+# This script has been modified by kosmikus and is based on
+# python-updater by liquidx.
+#
+# It tries to update any package that provides a ghc library.
+# This script can be run as many times as you like. It will log the
+# results in /var/log/ghc-updater.log
+#
+# NEW_GHC_VER = new ghc version we are upgrading to
+# PKGS_EXCEPTIONS = packages that should NOT be re-emerged for any reason
+# PKGS_MANUAL = packages that should be re-emerged even if they don't
+# fit the criteria
+#
+# Runtime Variables:
+#
+# PKGS_TO_REMERGE = list of packages we deem to need re-emerging
+# PKGS_OK = list of packages that should be merged without any problems
+# PKGS_MISSING = list of packages that are installed, but cannot be merged
+# because they have been pruned from portage
+# PKGS_MASKED = list of packages that are installed, but masked.
+#
+
+shopt -s nullglob
+
+NEW_GHC_VER=$(ghc --version | sed 's:^.*version ::')
+NEW_GHC_LIBDIR=$(ghc --print-libdir)
+
+PKGS_EXCEPTIONS="dev-lang/ghc dev-lang/ghc-bin"
+PKGS_MANUAL=""
+LOGFILE="/var/log/ghc-updater.log"
+
+# portage variables
+PKG_DBDIR=/var/db/pkg
+
+# moved the portageq checks into a function to make command
+# line parsing immediate
+
+setup_portdir() {
+ PORTDIR=`portageq portdir`
+ PORTDIR_OVERLAYS=`portageq portdir_overlay`
+}
+
+PRETEND=0
+PKGS_TO_REMERGE=""
+PKGS_COUNT_REMERGE=0
+PORTAGE_PYTHON="/usr/bin/python"
+
+usage() {
+ echo "usage: ghc-updater [options]"
+ echo " -h, -?, --help help"
+ echo " -p, --pretend pretend (don't do anything)"
+}
+
+#
+#
+# Command Line Parsing
+#
+#
+while [ -n "$1" ]; do
+ case "$1" in
+ -h | -\? | --help)
+ usage
+ exit 0
+ ;;
+ -p | --pretend)
+ PRETEND=1
+ ;;
+ *)
+ usage
+ echo "unrecognised option: $1"
+ ;;
+ esac
+ shift
+done
+
+# load the gentoo-style info macros, but hack to get around
+# it thinking this is an rc script
+EBUILD="1"
+source /sbin/functions.sh
+
+# misc helper functions
+eloginfo() {
+ einfo $*
+ DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
+ (echo "${DATESTRING} - ${*}" >> ${LOGFILE}) 2>/dev/null
+}
+
+elogecho() {
+ echo -n " "
+ echo $*
+ DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
+ (echo "${DATESTRING} - ${*}" >> ${LOGFILE}) 2>/dev/null
+}
+
+elogerr() {
+ eerror $*
+ DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
+ (echo "${DATESTRING} ! ${*}" >> ${LOGFILE}) 2>/dev/null
+}
+
+elog() {
+ DATESTRING=`date +"%Y/%m/%d %H:%M:%S"`
+ (echo "${DATESTRING} - ${*}" >> ${LOGFILE}) 2>/dev/null
+}
+
+#
+# Sanity check
+#
+
+setup_portdir
+
+find_in_portdir() {
+ local f
+ for f in ${PORTDIR} ${PORTDIR_OVERLAYS}; do
+ if [[ -f "${f}/${1}" ]]; then
+ echo "${f}/${1}"
+ return 0
+ fi
+ done
+ return 1
+}
+
+if [ -z "${PORTDIR}" ]; then
+ eerror "Unable to proceed. Can not find PORTDIR. Make sure the command:"
+ eerror " "
+ eerror " portageq portdir"
+ eerror " "
+ eerror "returns a value. If it doesn't, make sure you have updated to"
+ eerror "latest portage version."
+ eerror " "
+ eerror "Report bugs to http://bugs.gentoo.org/"
+ exit 1
+fi
+
+#
+#
+# Find all packages that have installed something in
+# directories of the form
+# /usr/lib/ghc-<version>
+# or similar.
+#
+# /usr/lib/ghc-bin-<version>
+# is included because an old ghc-bin ebuild was buggy and
+# installed to a wrong dir.
+#
+OLD_PACKAGES_DIR=""
+# Exclude new library dir and lib symlinks:
+for d in /{usr,opt/ghc}/lib{,64}/ghc{,-bin}-*; do
+ [[ "${d}" == ${NEW_GHC_LIBDIR} ]] || [[ -L ${d%/*} ]] || OLD_PACKAGES_DIR="${OLD_PACKAGES_DIR}${d} "
+done
+
+eloginfo "Starting GHC Updater to $(which ghc), version ${NEW_GHC_VER} :"
+eloginfo "Searching for packages with files in the directories:"
+eloginfo "${OLD_PACKAGES_DIR}"
+
+# iterate thru all the installed package's contents
+for content in `find ${PKG_DBDIR} -name CONTENTS`; do
+ # extract the category, package name and package version
+ CATPKGVER=$(echo ${content} | sed "s:${PKG_DBDIR}/\(.*\)/CONTENTS:\1:")
+
+ # exclude packages that are an exception, like portage and python itself.
+ exception=0
+ for exp in ${PKGS_EXCEPTIONS}; do
+ if [ -n "$(echo ${CATPKGVER} | grep ${exp})" ]; then
+ exception=1
+ break;
+ fi
+ done
+
+ if [ ${exception} = 1 ]; then
+ continue;
+ fi
+
+ for d in ${OLD_PACKAGES_DIR}; do
+ if fgrep "${d}/" ${content} > /dev/null; then
+ PKGS_TO_REMERGE="${PKGS_TO_REMERGE} ${CATPKGVER}"
+ elogecho "${CATPKGVER} has files in ${d}"
+ fi
+ done
+done
+
+# now we have to do each emerge seperately because if an installed version
+# does not have the corresponding ebuild in portage, then it will bail.
+
+eloginfo "Calculating Upgrade Package List .."
+
+PKGS_OK=""
+PKGS_MASKED=""
+PKGS_BLOCKED=""
+PKGS_MISSING=""
+
+MASKED_STRING="been masked"
+BLOCKED_STRING="is blocking"
+MISSING_STRING='there are no ebuilds to satisfy'
+
+for pkg in ${PKGS_TO_REMERGE}; do
+ emerge_output="$(emerge -p '>='$pkg 2>&1)"
+ if $(echo "${emerge_output}" | grep "${MASKED_STRING}" > /dev/null); then
+ PKGS_MASKED="${PKGS_MASKED} $pkg"
+ elogecho ">=$pkg is masked"
+ elif $(echo "${emerge_output}" | grep "${BLOCKED_STRING}" > /dev/null); then
+ PKGS_BLOCKED="${PKGS_BLOCKED} $pkg"
+ elogecho ">=$pkg is blocked"
+ elif $(echo "${emerge_output}" | grep "${MISSING_STRING}" > /dev/null); then
+ PKGS_MISSING="${PKGS_MISSING} $pkg"
+ elogecho ">=$pkg is missing from portage"
+ else
+ PKGS_OK="${PKGS_OK} $pkg"
+ PKGS_COUNT_REMERGE=$((PKGS_COUNT_REMERGE + 1))
+ fi
+done
+
+#
+# Use my super dumb package reordering algorithm that works most of the time
+#
+
+eloginfo "Re-ordering packages to merge .."
+
+DEPSORT=$(find_in_portdir "dev-lang/ghc/files/depsort.py")
+if [[ -z ${DEPSORT} ]]; then
+ eerror "Fatal error: File dev-lang/ghc/files/depsort.py in portage tree."
+ exit 1
+fi
+PKGS_OK_SORTED="$(${PORTAGE_PYTHON} ${DEPSORT} ${PKGS_OK} | xargs)"
+
+if [[ -n ${PRETEND} ]]; then
+ eloginfo "These are the packages that would be merged, in order:"
+else
+ eloginfo "Preparing to merge these packages in this order:"
+fi
+for pkg in $PKGS_OK_SORTED; do
+ elogecho ">=$pkg"
+done
+
+# we emerge each package seperately to ensure we know exactly which ones might
+# cause an error, and then report it at the end
+
+COUNT=1
+PKGS_FAILED=""
+if [ "${PRETEND}" != "1" ]; then
+ for pkg in ${PKGS_OK_SORTED}; do
+ eloginfo "Starting to merge ($COUNT/$PKGS_COUNT_REMERGE) $pkg .."
+ if ! emerge --oneshot --nodeps '>='$pkg; then
+ PKGS_FAILED="${PKGS_FAILED} $pkg"
+ elogerr "Failed merging $pkg ($COUNT/$PKGS_COUNT_REMERGE)!"
+ fi
+ COUNT=$((COUNT+1))
+ done
+fi
+
+# final output stuff
+OUTPUT_PKGS_MASKED=""
+for pkg in ${PKGS_MASKED}; do OUTPUT_PKGS_MASKED="${OUTPUT_PKGS_MASKED} '>='$pkg"; done
+OUTPUT_PKGS_BLOCKED=""
+for pkg in ${PKGS_BLOCKED}; do OUTPUT_PKGS_BLOCKED="${OUTPUT_PKGS_BLOCKED} $pkg"; done
+OUTPUT_PKGS_MISSING=""
+for pkg in ${PKGS_MISSING}; do OUTPUT_PKGS_MISSING="${OUTPUT_PKGS_MISSING} $pkg"; done
+OUTPUT_PKGS_FAILED=""
+for pkg in ${PKGS_FAILED}; do OUTPUT_PKGS_FAILED="${OUTPUT_PKGS_FAILED} '>='$pkg"; done
+
+if [ -n "${PKGS_FAILED}" -o -n "${PKGS_MISSING}" -o -n "${PKGS_MASKED}" ]; then
+ echo
+ ewarn "************************************************************"
+ ewarn "* Packages that still need to be manually emerged : *"
+ ewarn "************************************************************"
+ if [ -n "${OUTPUT_PKGS_MASKED}" ]; then
+ echo
+ ewarn " Masked Packages:"
+ ewarn " ----------------"
+ ewarn " Unmask the following packages (at your own risk) and "
+ ewarn " emerge them using this command after removing the '-p'"
+ ewarn " parameter."
+ echo
+ ewarn " emerge -p ${OUTPUT_PKGS_MASKED}"
+ echo
+ fi
+ if [ -n "${OUTPUT_PKGS_BLOCKED}" ]; then
+ echo
+ ewarn " Blocked Packages:"
+ ewarn " -----------------"
+ ewarn " These packages are currently blocked; they might not yet"
+ ewarn " be compatible with the current ghc. You can run ghc-updater"
+ ewarn " again at a later time."
+ echo
+ for x in ${OUTPUT_PKGS_BLOCKED}; do
+ echo " ${x}"
+ done
+ fi
+ if [ -n "${OUTPUT_PKGS_MISSING}" ]; then
+ echo
+ ewarn " Missing Packages:"
+ ewarn " -----------------"
+ ewarn " These packages cannot be updated because they do not exist"
+ ewarn " in portage anymore."
+ echo
+ for x in ${OUTPUT_PKGS_MISSING}; do
+ echo " ${x}"
+ done
+ fi
+ if [ -n "${OUTPUT_PKGS_FAILED}" ]; then
+ echo
+ ewarn " Failed Packages:"
+ ewarn " ----------------"
+ ewarn " These packages have failed and need to be re-emerged again."
+ ewarn " Alternatively, try re-running this script again to see if it"
+ ewarn " can be fixed."
+ echo
+ ewarn " emerge -p ${OUTPUT_PKGS_FAILED}"
+ echo
+ fi
+
+ elog "Python update completed with errors."
+ elog "Masked Packages:"
+ for x in ${PKGS_MASKED}; do
+ elog $x
+ done
+ elog "Missing Packages:"
+ for x in ${PKGS_MISSING}; do
+ elog $x
+ done
+ elog "Failed Packages:"
+ for x in ${PKGS_FAILED}; do
+ elog $x
+ done
+ elog "Update script completed."
+else
+ eloginfo "GHC update completed successfully."
+fi