Initial RK1 media-center image project
This commit is contained in:
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
# shellcheck source=lib.sh
|
||||
. "${SCRIPT_DIR}/lib.sh"
|
||||
|
||||
LOCK_FILE="${RKMEDIA_ROOT}/sources.lock.json"
|
||||
DEST_DIR="${RKMEDIA_ROOT}/out/sources"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: fetch-sources.sh [--lock FILE] [--dest DIRECTORY]
|
||||
|
||||
Fetch every build input at the exact commit recorded in the source lock.
|
||||
Existing repositories are accepted only when their origin and HEAD match.
|
||||
EOF
|
||||
}
|
||||
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
--lock)
|
||||
[[ $# -ge 2 ]] || die "--lock requires a file"
|
||||
LOCK_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dest)
|
||||
[[ $# -ge 2 ]] || die "--dest requires a directory"
|
||||
DEST_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*) die "unknown argument: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
need_command git
|
||||
need_command jq
|
||||
LOCK_FILE="$(absolute_path "${LOCK_FILE}")"
|
||||
DEST_DIR="$(absolute_path "${DEST_DIR}")"
|
||||
[[ -f "${LOCK_FILE}" ]] || die "source lock not found: ${LOCK_FILE}"
|
||||
jq -e '.schema_version == 1 and (.sources | type == "array")' "${LOCK_FILE}" >/dev/null \
|
||||
|| die "invalid source lock: ${LOCK_FILE}"
|
||||
mkdir -p -- "${DEST_DIR}"
|
||||
|
||||
verify_checkout() {
|
||||
local dir="$1" expected_repo="$2" expected_commit="$3"
|
||||
local actual_repo actual_commit
|
||||
[[ -d "${dir}/.git" ]] || return 1
|
||||
actual_repo="$(git -C "${dir}" remote get-url origin 2>/dev/null || true)"
|
||||
actual_commit="$(git -C "${dir}" rev-parse HEAD 2>/dev/null || true)"
|
||||
[[ "${actual_repo}" == "${expected_repo}" && "${actual_commit}" == "${expected_commit}" ]]
|
||||
}
|
||||
|
||||
while IFS=$'\t' read -r name repository ref commit; do
|
||||
[[ "${name}" =~ ^[a-z0-9][a-z0-9._-]*$ ]] || die "unsafe source name in lock: ${name}"
|
||||
[[ "${commit}" =~ ^[0-9a-f]{40}$ ]] || die "invalid commit for ${name}: ${commit}"
|
||||
source_dir="${DEST_DIR}/${name}"
|
||||
|
||||
if verify_checkout "${source_dir}" "${repository}" "${commit}"; then
|
||||
log "source already verified: ${name} ${commit}"
|
||||
continue
|
||||
fi
|
||||
if [[ -e "${source_dir}" ]]; then
|
||||
die "${source_dir} exists but does not match the lock; move it aside and retry"
|
||||
fi
|
||||
|
||||
log "fetching ${name} at ${commit}"
|
||||
mkdir -p -- "${source_dir}"
|
||||
git -C "${source_dir}" init --quiet
|
||||
git -C "${source_dir}" remote add origin "${repository}"
|
||||
if ! git -C "${source_dir}" fetch --quiet --depth=1 origin "${commit}"; then
|
||||
log "direct commit fetch was unavailable; fetching history from ${ref}"
|
||||
git -C "${source_dir}" fetch --quiet --filter=blob:none origin "${ref}"
|
||||
fi
|
||||
git -C "${source_dir}" checkout --quiet --detach "${commit}"
|
||||
verify_checkout "${source_dir}" "${repository}" "${commit}" \
|
||||
|| die "checkout verification failed for ${name}"
|
||||
done < <(jq -r '.sources[] | select(.build == true) | [.name, .repository, .ref, .commit] | @tsv' "${LOCK_FILE}")
|
||||
|
||||
log "all locked sources are present in ${DEST_DIR}"
|
||||
|
||||
Reference in New Issue
Block a user