Skip to content

Instantly share code, notes, and snippets.

@PetarKirov
Last active May 11, 2020 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PetarKirov/f36452fbb20d1a3a62cec3b61ea49e24 to your computer and use it in GitHub Desktop.
Save PetarKirov/f36452fbb20d1a3a62cec3b61ea49e24 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# The script clones and builds the main D repositories (comiler, runtime,
# standard library and auxiliary tools).
# In case one (or more) repository exists, the script will stash all uncommited
# changes (if any), checkout the desired branch, fetch from upstream and clean
# build the latest version.
# Fail on any error
set -euo pipefail
# Directory containing the dlang repos (the dir of this script is the default):
DLANG_DIR=$(cd ${DLANG_DIR:-$(dirname "${BASH_SOURCE[0]}")} && pwd)
# Path to pre-existing DMD-compatible compiler (dmd, ldmd/ldmd2, gdmd, etc.):
DMD="$(which ${DMD:-dmd})"
# Git branch to (checkout) and build:
BRANCH=${BRANCH:-master}
# Git remote name to pull from:
REMOTE=${REMOTE:-upstream}
# Base URL to clone from if repo doesn't exist locally:
UPSTREAM_BASE_URL=${UPSTREAM_BASE_URL:-'https://github.com/dlang'}
# Silent versions of `pushd` and `popd`:
pushd() {
command pushd "$@" > /dev/null
}
popd() {
command popd "$@" > /dev/null
}
indent() {
indent_txt=$(printf '%0.s ' $(seq 1 $1))
keep_first_line=$([[ "${2:-}" == "--all-but-1st-line" ]] && echo "1 !" || echo "")
sed "${keep_first_line}s/^/$indent_txt/"
}
main() {
pushd "$DLANG_DIR"
echo "[i] Base dir='$DLANG_DIR' | DMD='$DMD'"
echo "[i] Remote='$UPSTREAM_BASE_URL' | Branch='$BRANCH'"
echo "---------"
ensureRepo "dmd"
ensureRepo "druntime"
ensureRepo "phobos"
ensureRepo "tools"
echo "---------"
echo "Build completed successfully."
popd
}
ensureRepo() {
repo=$1
repo_dir="$DLANG_DIR/$repo"
echo "[>] Ensuring that '$repo' ('$repo_dir') has a build of the latest '$REMOTE/$BRANCH'..."
if [ -d "$repo_dir" ]; then
pushd "$repo_dir" > /dev/null
if repoCleanAndUpToDate; then
echo "[OK]" | indent 2
popd
return 0
else
echo "[i] Repository '$repo' found, but not clean or up-to-date." | indent 2
echo "[>] Cleaning..." | indent 2
cleanRepo | indent 6
echo "[DONE]" | indent 6
fi
else
echo "[i] Repository '$repo' does not exist." | indent 2
printf "[>] " | indent 2
git clone "$UPSTREAM_BASE_URL/$repo" 2>&1 | indent 6 --all-but-1st-line
echo "[DONE]" | indent 6
pushd "$repo_dir"
git remote rename origin upstream
fi
echo "[i] Repository '$repo' needs to be (re)build." | indent 2
echo "[>] Building..." | indent 2
buildRepo | indent 6
echo "[DONE]" | indent 6
popd
}
cleanRepo() {
make -f posix.mak -j8 HOST_DMD=$DMD SHELL='/usr/bin/env bash' clean
}
buildRepo() {
nixOsPhobosSetupemote='https://github.com/dlang'
/usr/bin/env time -v make -f posix.mak -j8 HOST_DMD=$DMD SHELL='/usr/bin/env bash'
}
repoCleanAndUpToDate() {
cleanAndUpToDate=true
printf "[>] Checking '$repo' for untracked changes..." | indent 2
if [ ! -z "$(git status --porcelain -uno)" ]; then
echo
echo "[!] Repo '$repo' contains uncommited changes." | indent 4
echo "[>] Stashing..." | indent 4
cleanAndUpToDate=false
git stash push | indent 8
echo "[DONE]" | indent 8
else
echo " [OK]"
fi
printf "[>] Checking if '$repo' is on branch '$BRANCH'..." | indent 2
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" != "$BRANCH" ]; then
echo
echo "[!] Repo '$repo' is on branch '$current_branch'." | indent 4
printf "[>] " | indent 4
cleanAndUpToDate=false
git checkout "$BRANCH" 2>&1 | indent 8 --all-but-1st-line
echo "[DONE]" | indent 8
else
echo " [OK]"
fi
echo "[>] Checking if local branch '$BRANCH' is up-to-date with '$REMOTE/$BRANCH'" | indent 2
git remote update 2>&1 | indent 6
if [ "$(git rev-parse HEAD)" != "$(git rev-parse "$REMOTE/$BRANCH")" ]; then
echo "[!] Local branch '$BRANCH' does not match '$REMOTE/$BRANCH'." | indent 4
echo "[>] Attempting fast-forward..." | indent 4
cleanAndUpToDate=false
git pull --ff-only "$REMOTE" "$BRANCH" 2>&1 | indent 8
echo "[DONE]" | indent 8
else
echo "[OK]" | indent 6
fi
eval $cleanAndUpToDate
return $?
}
nixOsPhobosSetup() {
if [ "$repo" == 'phobos' ] && [ -d '/nix/store' ]; then
# [NixOS specific] we need to provide the path to /share/zoneinfo/ and libcurl.so
# explicitly when building phobos
[ -f './TZDatabaseDirFile' ] || \
echo "$(nix eval --raw nixpkgs.tzdata.outPath)/share/zoneinfo/" \
> TZDatabaseDirFile
[ -f './LibcurlPathFile' ] || \
echo "$(nix eval --raw nixpkgs.curl.out)/lib/libcurl$(nix eval --raw nixpkgs.stdenv.hostPlatform.extensions.sharedLibrary)" \
> LibcurlPathFile
fi
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment