Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rubocop-daemon-wrapper logging #25

Open
gurgeous opened this issue Dec 15, 2020 · 0 comments
Open

rubocop-daemon-wrapper logging #25

gurgeous opened this issue Dec 15, 2020 · 0 comments

Comments

@gurgeous
Copy link

I am the go to guy on my team for tracking down linting/formatting issues. This isn't easy, considering that the chain goes from vscode => vscode-ruby => rubocop-daemon-wrapper => rubocop-daemon => rubocop. It would be nice if rubocop-daemon-wrapper had some optional logging. I added some stuff locally that probably isn't great, but here it is if you want to take a peek. I suck at bash, unfortunately. Search for amd.

I also wonder if it's worth rewriting this script in Ruby. I recognize that would add another 10ms to execution time, but maybe it would be worthwhile.

#!/bin/bash

set -e

# amd - logging
LOG=0
function log() {
  if [[ $LOG -eq 1 ]]; then
    echo "$(date +%H:%M:%S): $@" >> /tmp/rubocop-daemon-wrapper.txt
  fi
}
log ""
log "################################################################################"
log "$@"

COMMAND_PREFIX=""

if [ -n "$RUBOCOP_DAEMON_USE_BUNDLER" ]; then
  COMMAND_PREFIX="bundle exec"
fi

if ! command -v rubocop-daemon > /dev/null; then
  $COMMAND_PREFIX rubocop $@
  exit $?
fi

if [[ "$OSTYPE" == "linux-gnu" ]]; then
  if [ -f "/etc/fedora-release" ]; then
    NETCAT_CMD="nc"
  else
    NETCAT_CMD="nc -N"
  fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
  NETCAT_CMD="nc"
elif [[ "$OSTYPE" == "freebsd"* ]]; then
  # https://www.freebsd.org/cgi/man.cgi?query=netcat&manpath=SuSE+Linux/i386+11.3
  NETCAT_CMD="nc"
else
  echo "Sorry, we're not sure if the rubocop-daemon-wrapper script will work" \
    "on your OS: \"$OSTYPE\"" >&2
  echo "Try to comment out this message in the script, and use one of the following:" >&2
  echo >&2
  echo "NETCAT_CMD=\"nc\"" >&2
  echo "# Or" >&2
  echo "NETCAT_CMD=\"nc -N\"" >&2
  echo >&2
  echo "Then please leave a comment on this GitHub issue and" \
    "let us know which one worked:" >&2
  echo >&2
  echo "* https://github.com/fohte/rubocop-daemon/issues/4" >&2
  echo >&2
  exit 1
fi

find_project_root() {
  path=$(pwd -P)
  while [[ "$path" != "" && ! -f "$path/Gemfile" && ! -f "$path/gems.rb" ]]; do
    path=${path%/*}
  done
  echo "$path"
}

PROJECT_ROOT="$(find_project_root)"
if [ -z "$PROJECT_ROOT" ]; then
  # If we can't find a Gemfile, just use the current directory
  PROJECT_ROOT="$(pwd -P)"
fi

CACHE_DIR="$HOME/.cache/rubocop-daemon"
PROJECT_CACHE_KEY="$(echo ${PROJECT_ROOT:1} | tr '/' '+')"
PROJECT_CACHE_DIR="$CACHE_DIR/$PROJECT_CACHE_KEY"
TOKEN_PATH="$PROJECT_CACHE_DIR/token"
PORT_PATH="$PROJECT_CACHE_DIR/port"
STDIN_PATH="$PROJECT_CACHE_DIR/stdin"
STDOUT_PATH="$PROJECT_CACHE_DIR/stdout" # amd
STATUS_PATH="$PROJECT_CACHE_DIR/status"
LOCK_PATH="$CACHE_DIR/running.lock"
RUBOCOP_DAEMON="$COMMAND_PREFIX rubocop-daemon"

# If a lock file exist, wait up to 5 seconds.
i=0
while [ -d "$LOCK_PATH" ]; do
  # rubocop-daemon is already processing a request. Pause before trying again...
  sleep 1
  i=$((i + 1))
  if [ $i -ge 5 ]; then
    echo "rubocop-daemon-wrapper: Waited more than 5 seconds; ignoring the lock and proceeding." >&2
    break
  fi
done

unlock() {
  rm -r "$LOCK_PATH" 2> /dev/null
}

trap unlock EXIT

# Acquire a file lock before proceeding.
# Macs don't support the `lockfile` command, so just use mkdir.
mkdir -p "$LOCK_PATH"

# If -s or --stdin args are present, read stdin with `cat`
for ARG in $@; do
  if [ -z "$STDIN_CONTENT" ] && [ "$ARG" == "--stdin" ] || [ "$ARG" == "-s" ]; then
    # Preserve final new lines when ingesting from STDIN
    STDIN_CONTENT="$(cat; printf x)"
    STDIN_CONTENT=${STDIN_CONTENT%x}
  fi
done

if [ ! -f "$TOKEN_PATH" ]; then
  $RUBOCOP_DAEMON start
fi

run_rubocop_command() {
  TOKEN="$(cat "$TOKEN_PATH")"
  PORT="$(cat "$PORT_PATH")"
  COMMAND="$TOKEN $PROJECT_ROOT exec $@"
  # amd
  rm -f "$STDOUT_PATH" # Clear the previous stdout
  rm -f "$STATUS_PATH" # Clear the previous status

  # amd
  log "printf '%s\n%s' \"$COMMAND\" \"\$(cat ...)\" | $NETCAT_CMD localhost \"$PORT\""

  # amd
  # if printf '%s\n%s' "$COMMAND" "$STDIN_CONTENT" | $NETCAT_CMD localhost "$PORT"; then
  if printf '%s\n%s' "$COMMAND" "$STDIN_CONTENT" | $NETCAT_CMD localhost "$PORT" | tee $STDOUT_PATH; then
    if [ -f "$STATUS_PATH" ]; then
      # amd
      log "$(cat $STDOUT_PATH)"
      log "exit $(cat $STATUS_PATH)"
      exit "$(cat $STATUS_PATH)"
    else
      echo "rubocop-daemon-wrapper: server did not write status to $STATUS_PATH!" >&2
      exit 1
    fi
  fi
  return 1
}

...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant