Skip to content

Instantly share code, notes, and snippets.

@listochkin
Forked from thequux/README.md
Last active May 31, 2016 22:45
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 listochkin/ab664067e51d7c7f030ca146c2ef341d to your computer and use it in GitHub Desktop.
Save listochkin/ab664067e51d7c7f030ca146c2ef341d to your computer and use it in GitHub Desktop.
Multirust-compatible racer wrapper with OS X support

This wrapper automatically sets the RUST_SRC_DIRECTORY environment variable for whatever rust compiler is currently active, automatically creating a new checkout whenever necessary. This should be compatible with all of the multirust-alike tools, but it has only been tested with rustup.rs

Installation

Simply place this somewhere on your path before the main racer binary and set the execute bit.

Uninstallation

See rm(1).

Bugs

If you keep up to date with nightly, this will likely result in your disk slowly filling with copies of the rust source tree. While there are far worse uses for the disk space, you also likely have better. You may simply delete all directories beginning with rust- in $RUST_SOURCE_ROOT (${RUSTUP_HOME}/src or ${HOME}/.multirust/src, whichever is defined) to reclaim the disk space. (Strictly speaking, you can also remove the git directory, but it will automatically be redownloaded the next time the wrapper is run so this usually doens't make sense.)

Changes

  1. OSX support
  2. Pass correct CARGO_HOME variable to racer
#!/bin/bash
# Set a default for RUSTUP_HOME
: ${RUSTUP_HOME:=${HOME}/.multirust}
: ${RUST_SOURCE_ROOT:=${RUSTUP_HOME}/src}
[[ -d ${RUST_SOURCE_ROOT} ]] || mkdir -p "${RUST_SOURCE_ROOT}"
SELF_FOUND=0
# TODO: This doesn't deal well with path entries that contain spaces
for cmd in $(which -a "$(basename "$0")"); do
if (( $SELF_FOUND == 1 )); then
NEXT_RACER="${cmd}"
elif [[ "${cmd}" -ef "$0" ]]; then
SELF_FOUND=1
fi
done
if ! (( $SELF_FOUND )); then
: ${NEXT_RACER:=racer}
fi
function last_modified() {
FILE=$1
MODIFIED=0
if [[ "$OSTYPE" == "linux-gnu" ]]; then
MODIFIED=$(stat -c %Y "${FILE}")
elif [[ "$OSTYPE" == darwin* ]]; then
MODIFIED=$(stat -f %m "${FILE}")
else
# TODO: check BSD
# `man stat` on OS X says:
# > The stat utility appeared in NetBSD 1.6 and FreeBSD 4.10.
# so I assume it's safe to use same parameters as OSX
MODIFIED=$(stat -f %m "${FILE}")
fi
echo $MODIFIED
}
function vivify() {
HASH=$1
export GIT_DIR="$RUSTUP_HOME/src/git"
if ! [[ -d "${GIT_DIR}" ]]; then
git clone --bare --quiet https://github.com/rust-lang/rust "${GIT_DIR}"
fi
if (( $(date +%s) - 3600*12 > $(last_modified "${GIT_DIR}") )); then
git fetch --all
fi
TREE="$(git rev-parse --verify --quiet "${HASH}^{tree}")"
if [[ $? -ne 0 ]]; then
echo "Inable to resolve ${HASH}" >/dev/stderr
exit 1
fi
if ! [[ -d "${RUST_SOURCE_ROOT}/rust-${TREE}" ]]; then
git archive --prefix=rust-"${TREE}/" ${HASH} | tar xC "${RUST_SOURCE_ROOT}"
fi
echo "${RUST_SOURCE_ROOT}/rust-${TREE}"
}
function rust_version() {
# Get the current rust compiler version
local RUST_COMMIT="$(rustc -vV 2>/dev/null |awk '($1 == "commit-hash:") { print $2 }')"
if (( $? )); then
echo "Rust isn't installed!" >/dev/stderr
exit 2
fi
echo $RUST_COMMIT
}
exec env RUST_SRC_PATH="$(vivify "$(rust_version)")/src" CARGO_HOME="$HOME/.cargo/" "${NEXT_RACER}" "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment