292 lines
8.6 KiB
Bash
Executable file
292 lines
8.6 KiB
Bash
Executable file
#!/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
|