summaryrefslogtreecommitdiff
path: root/scripts/functions
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/functions')
-rw-r--r--scripts/functions124
1 files changed, 99 insertions, 25 deletions
diff --git a/scripts/functions b/scripts/functions
index 2e875f7..272f368 100644
--- a/scripts/functions
+++ b/scripts/functions
@@ -13,7 +13,7 @@ CT_LoadConfig() {
# It also sets KERNEL/ARCH/... for file inclusion below. Does not handle
# recursive definitions yet. We don't need arrays at this point.
CT_TestOrAbort "Configuration file not found. Please create one." -r .config
- . .config
+ . ./.config # Prefixing with ./ prevents Bash from searching $PATH
# Include sub-scripts instead of calling them: that way, we do not have to
# export any variable, nor re-parse the configuration and functions files.
@@ -37,7 +37,7 @@ CT_LoadConfig() {
oldvals=""
try=0
while [ "$try" -le 10 ]; do
- . .config
+ . ./.config # Prefixing with ./ prevents Bash from searching $PATH
vals=`set | ${grep} -E '^CT_'`
if [ "$oldvals" = "$vals" ]; then
break
@@ -752,7 +752,9 @@ CT_DoGetFile()
}
# This function saves the specified to local storage if possible,
-# and if so, symlinks it for later usage
+# and if so, symlinks it for later usage. This function is called from
+# the `if' condition (via the CT_GetFile) and therefore must return
+# on error rather than relying on the shell's ERR trap to catch it.
# Usage: CT_SaveLocal </full/path/file.name>
CT_SaveLocal()
{
@@ -762,9 +764,22 @@ CT_SaveLocal()
if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
CT_DoLog EXTRA "Saving '${basename}' to local storage"
# The file may already exist if downloads are forced: remove it first
- CT_DoExecLog ALL rm -f "${CT_LOCAL_TARBALLS_DIR}/${basename}"
- CT_DoExecLog ALL mv -f "${file}" "${CT_LOCAL_TARBALLS_DIR}"
- CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${basename}" "${file}"
+ if ! CT_DoExecLog ALL rm -f "${CT_LOCAL_TARBALLS_DIR}/${basename}"; then
+ return 1
+ fi
+ if ! CT_DoExecLog ALL mv -f "${file}" "${CT_LOCAL_TARBALLS_DIR}"; then
+ # Move may have failed if the local tarball storage is on a different
+ # filesystem. Fallback to copy+delete.
+ if ! CT_DoExecLog ALL cp -f "${file}" "${CT_LOCAL_TARBALLS_DIR}"; then
+ return 1
+ fi
+ if ! CT_DoExecLog ALL rm -f "${file}"; then
+ return 1
+ fi
+ fi
+ if ! CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${basename}" "${file}"; then
+ return 1
+ fi
fi
}
@@ -887,7 +902,12 @@ CT_DoVerifySignature()
CT_Popd
# If we get here, verification succeeded.
- CT_SaveLocal "${CT_TARBALLS_DIR}/${sigfile}${ext}"
+ if ! CT_SaveLocal "${CT_TARBALLS_DIR}/${sigfile}${ext}"; then
+ CT_Popd
+ return 1
+ fi
+
+ return 0
}
# Download the file from one of the URLs passed as argument
@@ -972,7 +992,9 @@ CT_GetFile()
CT_DoExecLog ALL rm "${CT_TARBALLS_DIR}/${basename}${ext}"
return 1
fi
- CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}${ext}"
+ if ! CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}${ext}"; then
+ return 1
+ fi
return 0
fi
done
@@ -1794,7 +1816,6 @@ CT_GetVersion_hg()
# to clone if cset is not known and a branch is given.
if [ -z "${devel_revision}" ]; then
if [ -z "${devel_branch}" ]; then
- # Mercurial does not allow querying branches
devel_revision=`hg identify "${devel_url}"`
else
CT_DoLog WARN "${pkg_name}: Mercurial cannot query non-default branch, will clone"
@@ -1831,46 +1852,97 @@ CT_GetVersion_git()
CT_Abort "${pkg_name}: cannot specify both branch and changeset for Git"
fi
- devel_branch="${devel_branch:-master}"
+ # Do not modify devel_branch so that we can check if it has been set by user
+ # in CT_Download_git.
+ local branch="${devel_branch:-master}"
+
if [ -z "${devel_revision}" ]; then
- local matches=`git ls-remote --exit-code "${devel_url}" --refs "${devel_branch}" \
+ local matches=`git ls-remote --exit-code "${devel_url}" --refs "${branch}" \
|| echo "not found"`
local best using ref
# Cannot test $?, setting a trap on ERR prevents bash from returning the
# status code.
if [ "${matches}" = "not found" ]; then
- CT_Abort "Failed to find git ref ${devel_branch} at ${devel_url}"
+ CT_Abort "Failed to find git ref ${branch} at ${devel_url}"
fi
if [ `echo "${matches}" | wc -l` -gt 1 ]; then
- if echo "${matches}" | grep '[[:space:]]\(refs/heads/\)\?'"${devel_branch}\$" >/dev/null; then
+ if echo "${matches}" | grep '[[:space:]]\(refs/heads/\)\?'"${branch}\$" >/dev/null; then
# Try exact match, or prepended with "refs/heads". Some projects (e.g. binutils)
# have refs/original/refs/heads/master as well as refs/heads/master, and
# `git ls-remote refs/heads/master` prints both.
- best=`echo "${matches}" | grep '[[:space:]]\(refs/heads/\)\?'"${devel_branch}\$"`
+ best=`echo "${matches}" | grep '[[:space:]]\(refs/heads/\)\?'"${branch}\$"`
using="best match"
else
best=`echo "${matches}" | head -n1`
using="first"
fi
ref=`echo "${best}" | sed 's/.*[[:space:]]//'`
- CT_DoLog WARN "Ambiguous ref ${devel_branch} at ${devel_url}, using ${using} (${ref})"
+ CT_DoLog WARN "Ambiguous ref ${branch} at ${devel_url}, using ${using} (${ref})"
else
best="${matches}"
fi
- devel_revision=`echo "${best}" | cut -c1-8`
- CT_DoLog DEBUG "ref ${devel_branch} at ${devel_url} has cset of ${devel_revision}"
+ # Similarly, do not modify the devel_revision, we'll need to know if it
+ # has been set by the user in CT_Download_git.
+ unique_id=`echo "${best}" | cut -c1-8`
+ CT_DoLog DEBUG "ref ${branch} at ${devel_url} has cset of ${unique_id}"
+ else
+ unique_id=`echo "${devel_revision}" | cut -c1-8`
fi
- unique_id="${devel_revision}"
}
# Retrieve sources from Git.
CT_Download_git()
{
- # Git does not allow making a shallow clone of a specific commit.
- CT_DoExecLog ALL git clone "${devel_url}" "${pkg_name}"
- CT_Pushd "${pkg_name}"
- CT_DoExecLog ALL git checkout "${devel_revision}" --
+ local new_unique_id fetched=n shallow_id
+
+ # Some of these operations are part of a `git clone`, but fetching a specific commit
+ # (if it is supported by the server) is not expressable as a `git clone`.
+ CT_mkdir_pushd "${pkg_name}"
+ CT_DoExecLog ALL git init
+ CT_DoExecLog ALL git remote add origin "${devel_url}"
+
+ if [ -z "${devel_revision}" ]; then
+ # Configuration didn't care about a specific commit; we'll use the most recent
+ # commit on the branch and will update the unique_id (and warn the user) if it
+ # differs from what we've previously determined.
+ shallow_id="${devel_branch:-master}"
+ else
+ local tmp=`echo "${devel_revision}" | sed 's/^[0-9a-z]\{40\}//'`
+
+ if [ -z "${tmp}" ]; then
+ shallow_id="${devel_revision}"
+ else
+ CT_DoLog WARN "Git only allows full 40-character SHA-1 hashes to identify a commit for shallow clone."
+ fi
+ fi
+
+ if [ -n "${shallow_id}" ]; then
+ if CT_DoExecLog ALL git fetch --quiet --depth 1 origin "${shallow_id}"; then
+ CT_DoExecLog ALL git checkout --quiet FETCH_HEAD --
+ else
+ # Git 2.15 and newer (which must be the case on both the client and the server)
+ # allows fetching a single commit so long as the server is configured
+ # to allow it (by having uploadpack.allowReachableSHA1InWant=true set
+ # in its config).
+ CT_DoLog WARN "Shallow clone failed (likely disallowed on the server)."
+ shallow_id=
+ fi
+ fi
+
+ if [ -z "${shallow_id}" ]; then
+ # In this case, we already determined the changeset we need
+ CT_DoLog WARN "Falling back to full clone; may take some time..."
+ CT_DoExecLog ALL git fetch --quiet origin
+ CT_DoExecLog ALL git checkout --quiet "${unique_id}" --
+ fi
+
+ new_unique_id=`git rev-parse HEAD | cut -c1-8`
+ if [ "${new_unique_id}" != "${unique_id}" ]; then
+ CT_DoLog EXTRA "Revision being fetched changed to ${new_unique_id}; source repository had more revisions pushed?"
+ unique_id="${new_unique_id}"
+ fi
+
CT_DoExecLog ALL rm -rf .git
CT_Popd
}
@@ -1981,10 +2053,10 @@ CT_DoFetch()
if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then
CT_DoLog WARN "Downloads forbidden, not trying ${devel_vcs} retrieval"
- return 1
+ CT_Abort "${pkg_name}: cannot check out"
fi
- CT_DoLog EXTRA "Retrieving '${basename}' (${devel_vcs} ${devel_url} ${devel_branch} ${devel_revision})"
+ CT_DoLog EXTRA "Checking out '${basename}' (${devel_vcs} ${devel_url}${devel_branch:+, branch ${devel_branch}}${devel_revision:+, revision ${devel_revision}})"
CT_MktempDir tmp_dir
CT_Pushd "${tmp_dir}"
CT_Download_${devel_vcs}
@@ -1996,7 +2068,9 @@ CT_DoFetch()
CT_DoExecLog ALL mv "${pkg_name}${devel_subdir:+/${devel_subdir}}" "${basename}"
CT_DoExecLog ALL tar cjf "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${basename}"
- CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}.tar.bz2"
+ if ! CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}.tar.bz2"; then
+ CT_Abort "${pkg_name}: failed to save to local storage"
+ fi
CT_Popd
CT_DoExecLog ALL rm -rf "${tmp_dir}"