egscripts/egdrupalhelpers/egdrupalsymlinks

293 lines
8.6 KiB
Text
Raw Normal View History

#!/bin/bash
CORE="6.x"
BASE_URL="http://updates.drupal.org/release-history"
TARGET_BASE=/home/drupal/contrib
CORE_BASE=/home/drupal/core
UPDATE_XML_CONF=/etc/egscripts/update-xml.conf
# Mode of operation
LIST=0
READ=0
FIND=0
MISSING=0
CONTRIBLIST=0
DOWNLOAD=0
VERSIONLIST=0
AUTODOWNLOAD=0
usage() {
cat <<EOT
Usage: `basename $0` [ OPTIONS ] module [ version ] | -r
Create a symlink to a Drupal module in the server wide module directory from
the current directory.
If no specific version is specified, the recommended version for this core
release will be symlinked.
OPTIONS
-b dir - Specify target base directory. (default: $TARGET_BASE)
-c core - Specify the required core compatability. (default: $CORE)
-d - Download the specified module to the target base directory.
-f - Find links to a module, effectively listing all sites which use
the named module. If no version is specified, all versions are
listed.
-h - Show this help.
-l - List available versions for module in the target base directory.
-L - List available versions for module at drupal.org or the update
source specified by -x or -X.
-m - Fix missing. Looks for broken symlinks in the current directory
and downloads the missing versions to the target directory.
-r - Read modules from stdin. One module per line, with the version
number as an optional second parameter on each line. If -d was
specified, the modules will be downloaded to the target base
directory. Otherwise, they will be symlinked in the current
directory.
-v - List versions of all modules in current directory in a format
suitable for -r mode.
-x url - Specify the XML feed URL to check for updates. (default: $BASE_URL)
-X repo - Specify a known XML feed URL by short name, see $UPDATE_XML_CONF
EOT
}
# Returns the base URL for the updates XML feed. If an argument is passed,
# will look for an info file in the given directory and see if it has an
# overridden update URL. This is used by the feature server.
#
# Otherwise just returns the default.
get_base_url() {
module=$1
if [ -n "$module" ] && [ -f "$module/$module.info" ] ; then
override=`awk -F'"' '/^project status url/{print $2}' $module/$module.info`
if [ -n "$override" ] ; then
echo $override
else
echo $BASE_URL
fi
else
echo $BASE_URL
fi
}
symlink_module() {
module=$1
version=$2
base_url=`get_base_url $module`
if [ -z "$version" ] ; then
# No specific version given, so just get recommended
recommended=`xmlstarlet sel --net --text --template --match "/project/recommended_major" --value-of . --nl $base_url/$module/$CORE`
if [ -z "$recommended" ] ; then
echo "Can't find recommened major version for $module"
return
fi
# This will grab the version string of the first release for the recommended
# major version number
version=`xmlstarlet sel --net --text --template --match "/project/releases/release[version_major='$recommended'][position()=1]/version" --value-of . --nl $base_url/$module/$CORE`
if [ -z "$recommended" ] ; then
echo "Can't find recommened version for $module major version $recommended"
return
fi
fi
target_dir=$TARGET_BASE/$module/$version
if [ ! -d $target_dir ] ; then
if [ $AUTODOWNLOAD -eq 1 ] ; then
get_module $module $version
else
echo "$target_dir not present."
while read -n1 -p "Do you want to fetch $module-$version? (y/n)" answer ; do
case $answer in
y) echo ; get_module $module $version; break ;;
n) echo ; return ;;
esac
done
fi
fi
if [ -e "$module" ] ; then
if [ ! -L "$module" ] ; then
echo "$module exists and is not a symlink ... skipping"
return
else
link=`readlink $module`
if [ "$link" == "$target_dir" ] ; then
echo "$module already links to $target_dir ... skipping"
return
else
echo "$module currently links to $link"
while read -n1 -p "Do you want to change it to $module-$version? (y/n)" answer ; do
case $answer in
y) echo ; rm -v $module ; break ;;
n) echo ; return ;;
esac
done
fi
fi
fi
ln -vs $target_dir $module
}
get_module() {
module=$1
version=$2
base_url=`get_base_url $module`
if [ -z "$version" ] ; then
# No specific version given, so just get recommended
recommended=`xmlstarlet sel --net --text --template --match "/project/recommended_major" --value-of . --nl $base_url/$module/$CORE`
if [ -z "$recommended" ] ; then
echo "Can't find recommened major version for $module"
return
fi
# This will grab the version string of the first release for the recommended
# major version number
version=`xmlstarlet sel --net --text --template --match "/project/releases/release[version_major='$recommended'][position()=1]/version" --value-of . --nl $base_url/$module/$CORE`
if [ -z "$recommended" ] ; then
echo "Can't find recommened version for $module major version $recommended"
return
fi
fi
target_dir=$TARGET_BASE/$module/$version
if [ -d $target_dir ] ; then
echo "$target_dir already present ... skipping"
return
fi
url=`xmlstarlet sel --net --text --template --match "/project/releases/release[version='$version']/download_link" --value-of . --nl $base_url/$module/$CORE`
if [ -z "$url" ] ; then
echo "Unable to determine download URL for $module version $version"
return
fi
mkdir -vp $target_dir
echo "Downloading $module ($version) to $target_dir"
wget --quiet -O - $url | tar -z -x -f - -C $target_dir --strip 1
}
find_update_xml_url() {
awk -v shortname="$1" '{if($1 == shortname){print $2;exit}}' $UPDATE_XML_CONF
}
while getopts "c:b:x:X:fdlLrhvm" OPT ; do
case $OPT in
c) CORE=$OPTARG ;;
b) TARGET_BASE=$OPTARG ;;
x) BASE_URL=$OPTARG ;;
X) BASE_URL=`find_update_xml_url $OPTARG` ;;
l) LIST=1 ;;
L) CONTRIBLIST=1 ;;
m) MISSING=1 ; AUTODOWNLOAD=1 ;;
r) READ=1 ; AUTODOWNLOAD=1 ;;
f) FIND=1 ;;
d) DOWNLOAD=1 ;;
v) VERSIONLIST=1 ;;
h) usage ; exit 0 ;;
*) usage ; exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $READ -eq 0 ] && [ $VERSIONLIST -eq 0 ] ; then
if [ $# -lt 1 ] && [ $READ -eq 0 ] && [ $MISSING -eq 0 ] ; then
usage
exit 1
fi
fi
module=$1
version=$2
if [ $(($LIST + $READ + $FIND + $CONTRIBLIST + $VERSIONLIST + $MISSING)) -gt 1 ] ; then
echo "Incompatible options used"
usage
exit 1
fi
if [ $LIST -eq 1 ] ; then
if [ -d "$TARGET_BASE/$module" ] ; then
echo "Available versions of $module for core $CORE:"
ls $TARGET_BASE/$module
exit 0
else
echo "$module not present in $TARGET_BASE"
exit 1
fi
elif [ $CONTRIBLIST -eq 1 ] ; then
echo "Available releases of $module for core $CORE:"
xmlstarlet sel --net --text --template --match '/project/releases/release/version' --value-of . --nl $BASE_URL/$module/$CORE
exit 0
elif [ $READ -eq 1 ] ; then
if [ $DOWNLOAD -eq 1 ] ; then
while read module version ; do
get_module $module $version
done
else
while read module version ; do
symlink_module $module $version
done
fi
exit 0
elif [ $FIND -eq 1 ] ; then
if [ -z "$version" ] ; then
versions=`ls $TARGET_BASE/$module | xargs -n 1 basename`
else
versions=$version
fi
for version in $versions ; do
find $CORE_BASE -lname $TARGET_BASE/$module/$version
done
exit 0
elif [ $DOWNLOAD -eq 1 ] ; then
get_module $module $version
elif [ $VERSIONLIST -eq 1 ] ; then
for module in * ; do
if [ ! -d $module ] ; then
echo "$module is not a directory ... skipping" >&2
continue
fi
infofile="$module/$module.info"
if [ ! -f "$infofile" ] ; then
infofile=`find $module/ -name '*.info' | head -n 1`
if [ -z "$infofile" ] || [ ! -f "$infofile" ] ; then
echo "Can't find a .info file for '$module'" >&2
continue
fi
fi
echo -n $module
awk -F= '/^version/{version=$2}END{print version}' $infofile | sed -e 's/"//g'
done
elif [ $MISSING -eq 1 ] ; then
for module in * ; do
if [ ! -L $module ] ; then
continue
fi
target=`readlink $module`
if [ ! -d "$target" ] ; then
version=`basename $target`
dirname=`dirname $target`
module=`basename $dirname`
if [ -z "$module" ] || [ -z "$version" ] ; then
echo "Can't determine module info from symlink $target" >&2
continue
fi
get_module $module $version
fi
done
else
symlink_module $module $version
fi