From: Thomas De Schampheleire <patrickdepinguin@gmail.com>
To: buildroot@busybox.net
Subject: [Buildroot] [TO-BE-TESTED] support/download/hg: implement repository cache
Date: Tue, 5 Feb 2019 21:24:33 +0100 [thread overview]
Message-ID: <20190205202433.25292-1-patrickdepinguin@gmail.com> (raw)
From: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
Similar to the git download helper, implement a repository cache for
Mercurial repositories.
The code is mostly guided by the implementation for git, with certain parts
copied almost verbatim.
Signed-off-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
---
support/download/hg | 81 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 78 insertions(+), 3 deletions(-)
Note: this patch only got limited testing so far and needs to be tested further.
But I already wanted to send it out for feedback and for those of you that want
to help test it.
diff --git a/support/download/hg b/support/download/hg
index efb515fca5..bb5cc87969 100755
--- a/support/download/hg
+++ b/support/download/hg
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# We want to catch any unexpected failure, and exit immediately
-set -e
+set -E
# Download helper for hg, to be called from the download wrapper script
#
@@ -10,11 +10,39 @@ set -e
# -o FILE Generate archive in FILE.
# -u URI Clone from repository at URI.
# -c CSET Use changeset (or revision) CSET.
+# -d DLDIR Download directory path.
# -n NAME Use basename NAME.
#
# Environment:
# HG : the hg command to call
+# Save our path and options in case we need to call ourselves again
+myname="${0}"
+declare -a OPTS=("${@}")
+
+# This function is called when an error occurs. Its job is to attempt a clone
+# from scratch (only once!) in case the hg tree is borked, or in case an
+# unexpected and unsupported situation arises with uncommitted stuff (e.g. if
+# the user manually mucked around in the hg cache).
+# Note that this function would also be triggered by connection errors during
+# the clone/pull.
+_on_error() {
+ local ret=${?}
+
+ printf "Detected a possibly corrupted hg cache.\n" >&2
+ if ${BR_HG_BACKEND_FIRST_FAULT:-false}; then
+ printf "This is the second time in a row; bailing out\n" >&2
+ exit ${ret}
+ fi
+ export BR_HG_BACKEND_FIRST_FAULT=true
+
+ printf "Removing it and starting afresh.\n" >&2
+
+ rm -rf "${hg_cache}"
+
+ exec "${myname}" "${OPTS[@]}" || exit ${ret}
+}
+
verbose=
while getopts "${BR_BACKEND_DL_GETOPTS}" OPT; do
case "${OPT}" in
@@ -22,6 +50,7 @@ while getopts "${BR_BACKEND_DL_GETOPTS}" OPT; do
o) output="${OPTARG}";;
u) uri="${OPTARG}";;
c) cset="${OPTARG}";;
+ d) dl_dir="${OPTARG}";;
n) basename="${OPTARG}";;
:) printf "option '%s' expects a mandatory argument\n" "${OPTARG}"; exit 1;;
\?) printf "unknown option '%s'\n" "${OPTARG}" >&2; exit 1;;
@@ -36,8 +65,54 @@ _hg() {
eval ${HG} "${@}"
}
-_hg clone ${verbose} "${@}" --noupdate "'${uri}'" "'${basename}'"
+# Create and cd into the directory that will contain the local hg cache
+hg_cache="${dl_dir}/hg"
+mkdir -p "${hg_cache}"
+
+# Any error now should try to recover
+trap _on_error ERR
+
+# Create a warning file, that the user should not use the hg cache.
+# It's ours. Our precious.
+cat <<-_EOF_ >"${dl_dir}/hg.readme"
+ IMPORTANT NOTE!
+
+ The hg tree located in this directory is for the exclusive use
+ by Buildroot, which uses it as a local cache to reduce bandwidth
+ usage.
+
+ Buildroot *will* trash any changes in that tree whenever it needs
+ to use it. Buildroot may even remove it in case it detects the
+ repository may have been damaged or corrupted.
+
+ Do *not* work in that directory; your changes will eventually get
+ lost. Do *not* even use it as a remote, or as the source for new
+ worktrees; your commits will eventually get lost.
+_EOF_
+
+if ! [ -d "${hg_cache}/.hg" ]; then
+ # While it would be possible to create an empty repo and use pull
+ # subsequently, we intentionally use clone the first time as it could be
+ # faster than pull thanks to clonebundles, if enabled on the server.
+ printf "Cloning repository from '${uri}' into '${hg_cache}'\n"
+ _hg clone ${verbose} "${@}" --noupdate "'${uri}'" "'${hg_cache}'"
+else
+ printf "Pulling repository from '${uri}' into '${hg_cache}'\n"
+ _hg pull ${verbose} "${@}" --repository "'${hg_cache}'" "'${uri}'"
+fi
+
+# Check that the changeset does exist. If it does not, re-cloning from
+# scratch won't help, so we don't want to trash the repository for a
+# missing commit. We just exit without going through the ERR trap.
+if ! _hg identify --repository "'${hg_cache}'" --rev "'${cset}'" >/dev/null 2>&1; then
+ printf "Commit '%s' does not exist in this repository\n." "${cset}"
+ exit 1
+fi
+
+# Make sure that there is no working directory. This will clear any user
+# temptation to work in this directory.
+_hg update --repository "'${hg_cache}'" null >/dev/null 2>&1
-_hg archive ${verbose} --repository "'${basename}'" --type tgz \
+_hg archive ${verbose} --repository "'${hg_cache}'" --type tgz \
--prefix "'${basename}'" --rev "'${cset}'" \
- >"${output}"
--
2.19.2
next reply other threads:[~2019-02-05 20:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-05 20:24 Thomas De Schampheleire [this message]
2019-02-07 21:33 ` [Buildroot] [TO-BE-TESTED] support/download/hg: implement repository cache Arnout Vandecappelle
2019-02-08 16:54 ` Yann E. MORIN
2019-02-08 19:27 ` Arnout Vandecappelle
2019-02-08 19:54 ` Yann E. MORIN
2019-02-08 20:54 ` Arnout Vandecappelle
2019-02-08 21:18 ` Yann E. MORIN
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190205202433.25292-1-patrickdepinguin@gmail.com \
--to=patrickdepinguin@gmail.com \
--cc=buildroot@busybox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox