rubocop-daemon icon indicating copy to clipboard operation
rubocop-daemon copied to clipboard

rubocop-daemon-wrapper logging

Open gurgeous opened this issue 4 years ago • 0 comments

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
}

...

gurgeous avatar Dec 15 '20 18:12 gurgeous