From ea936c75f792ebdcc5af1b18bd0a62ccbb31e562 Mon Sep 17 00:00:00 2001 From: Matthew Mellor Date: Mon, 11 May 2026 00:33:02 -0500 Subject: [PATCH] fix(makefile): tipsyhive v1.11 sync issues (#41, #42, #43) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three real bugs surfaced when tipsyhive synced its Makefile to v1.11.0. All small, all related to Ruby/yq path issues. Issue #41 — Makefile yq invocation: LANGUAGES read via `yq '.languages[]'` without `-r`. yq v3 (kislyuk's Python wrapper, shipped as `yq` on Debian/Ubuntu) returns JSON-quoted scalars by default; HAS_RUBY filter then matches against `"ruby"` and finds nothing, so RUBY_DOCKER_ENV doesn't apply BUNDLE_APP_CONFIG and bundler fails to find project gems. Add `-r` — works in yq v3 and v4 alike. Issue #43 — `rubocop --check`: the _format recipe passed `--check` to rubocop. Not a valid rubocop flag. Every Rails project with rubocop in its Gemfile saw _format fail with "invalid option: --check". Default rubocop behaviour is already "report, don't autocorrect"; just drop the flag. `--fail-level error` still gates the exit code. Issue #42 — Container BUNDLE_PATH envvar: the Dockerfile exported BUNDLE_PATH=/usr/local/bundle at runtime. Per Bundler precedence (envvar beats project .bundle/config), consumer projects with `BUNDLE_PATH: vendor/bundle` had it silently overridden — so `bundle exec` for project-pinned gems hit Bundler::GemNotFound. Drop the envvar from the Dockerfile. Bundler now respects the project's `.bundle/config`. GEM_HOME + PATH at `/usr/local/bundle/bin` keep the container's own bundled tools (rubocop, reek, rspec, etc.) reachable via direct invocation. Validation: - bash tests/smoke-rails.sh — 4/4 (lint scoping, bundle install, .bundle/config override, rubocop --check fix implicitly) - make check on dev-toolchain itself — pass - `bundle config` inside container — BUNDLE_PATH no longer shown - Direct `rubocop --version`, `reek --version`, `brakeman --version` all resolve from /usr/local/bundle Filed by matthew-on-git from a downstream tipsyhive sync. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 21 +++++++++++++++++++++ Dockerfile | 9 ++++++++- Makefile | 4 ++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0e8bd..117f26d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- **Issue #41:** Makefile's `LANGUAGES` invocation of `yq` now uses `-r` + (raw output). yq v3 (kislyuk's Python wrapper, packaged as `yq` on + Debian/Ubuntu) returns JSON-formatted scalars by default — without + `-r`, `.languages[]` returned `"ruby"` (quoted) and `HAS_RUBY` never + matched. With `-r`, behaviour is identical between yq v3 and v4. +- **Issue #42:** Container no longer exports `BUNDLE_PATH=/usr/local/bundle` + at runtime. Bundler precedence rule (envvar beats project + `.bundle/config`) was silently overriding consumer projects with + `BUNDLE_PATH: vendor/bundle`, breaking `bundle exec` for + project-pinned gems with `Bundler::GemNotFound`. With the envvar + unset, the project's `.bundle/config` wins; direct gem invocations + (`rubocop`, `reek`, `rspec`) still resolve from `/usr/local/bundle` + via `GEM_HOME` and the `PATH` entry for `/usr/local/bundle/bin`. +- **Issue #43:** Makefile's `_format` no longer passes `--check` to + `rubocop` — it's not a valid rubocop flag and broke every Rails + project with rubocop in its Gemfile. Default rubocop behaviour is + already "report, don't autocorrect"; `--fail-level error` (still + passed) gates the exit code. + ## [1.11.0] - 2026-05-05 ### Added diff --git a/Dockerfile b/Dockerfile index 5737673..32755d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -187,8 +187,15 @@ COPY --from=ruby-builder /usr/local/bundle /usr/local/bundle RUN ln -sf libruby.so.3.4 /usr/local/lib/libruby.so.3.4.0 \ && ln -sf libruby.so.3.4 /usr/local/lib/libruby.so \ && ldconfig +# Bundler envvars. We DO NOT export BUNDLE_PATH at runtime — Bundler's +# precedence is envvar > project `.bundle/config`, which silently +# overrides a consumer's `BUNDLE_PATH: vendor/bundle` and breaks +# `bundle exec` for project-pinned gems (Issue #42). With BUNDLE_PATH +# unset, Bundler falls back to GEM_HOME — direct `rubocop` / `reek` / +# `rspec` invocations from `/usr/local/bundle/bin` (already on PATH) +# still resolve the container's bundled gems, and `bundle exec` in a +# consumer project honours the project's `.bundle/config`. ENV GEM_HOME=/usr/local/bundle -ENV BUNDLE_PATH=/usr/local/bundle ENV BUNDLE_SILENCE_ROOT_WARNING=1 ENV BUNDLE_APP_CONFIG=/usr/local/bundle diff --git a/Makefile b/Makefile index ab6e288..93ebe0f 100644 --- a/Makefile +++ b/Makefile @@ -85,7 +85,7 @@ RUBY_EXEC_FOR = $(if $(and $(wildcard Gemfile.lock),$(shell grep -m1 -E "^[[:spa # Computed before DOCKER_RUN so HAS_ can influence container env (e.g. # BUNDLE_APP_CONFIG override for Ruby projects — issue #30). # --------------------------------------------------------------------------- -LANGUAGES := $(shell yq '.languages[]' $(DEVRAIL_CONFIG) 2>/dev/null) +LANGUAGES := $(shell yq -r '.languages[]' $(DEVRAIL_CONFIG) 2>/dev/null) HAS_PYTHON := $(filter python,$(LANGUAGES)) HAS_BASH := $(filter bash,$(LANGUAGES)) HAS_TERRAFORM := $(filter terraform,$(LANGUAGES)) @@ -656,7 +656,7 @@ _format: _plugins-load for p in $(RUBY_PATHS); do [ -d "$$p" ] && ruby_paths="$$ruby_paths $$p"; done; \ ruby_paths=$${ruby_paths# }; \ if [ -n "$$ruby_paths" ]; then \ - $(call RUBY_EXEC_FOR,rubocop)rubocop --check --fail-level error $$ruby_paths || { overall_exit=1; failed_languages="$${failed_languages}\"ruby\","; }; \ + $(call RUBY_EXEC_FOR,rubocop)rubocop --fail-level error $$ruby_paths || { overall_exit=1; failed_languages="$${failed_languages}\"ruby\","; }; \ else \ echo '{"level":"info","msg":"skipping ruby format: none of RUBY_PATHS exist (override with RUBY_PATHS=...)","language":"ruby"}' >&2; \ fi; \