Skip to content

Require explicit truthy values for SKIP and FORCE env vars#926

Open
justin808 wants to merge 7 commits intomainfrom
jg/889-truthy-env-check-installer
Open

Require explicit truthy values for SKIP and FORCE env vars#926
justin808 wants to merge 7 commits intomainfrom
jg/889-truthy-env-check-installer

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Feb 16, 2026

Summary

  • Previously, any set value for ENV["SKIP"] or ENV["FORCE"] (including "false" or "0") would activate skip/force mode in the installer
  • Now only "true", "1", and "yes" (case-insensitive) are treated as truthy
  • Extracts a truthy_env? helper in template.rb, reused by binstubs.rb via apply

Closes #889

Test plan

  • Run SKIP=true rails shakapacker:install — should skip conflicting files
  • Run SKIP=false rails shakapacker:install — should NOT skip (prompts for conflicts)
  • Run SKIP=0 rails shakapacker:install — should NOT skip
  • Run FORCE=1 rails shakapacker:install — should force overwrite
  • Run FORCE=no rails shakapacker:install — should NOT force

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added SKIP=true installer option to preserve existing files and create only missing ones during installation.
  • Bug Fixes

    • Installer now only recognizes explicit truthy environment values (true/1/yes) for SKIP and FORCE; FORCE takes precedence if both are set.
  • Documentation

    • Installation docs and changelog updated to include SKIP and clarify conflict-resolution behavior.

Note

Low Risk
Low risk: installer conflict-handling now only enables FORCE/SKIP for explicit truthy values, which may change behavior for scripts relying on any non-empty value to trigger these modes.

Overview
Installer conflict handling now supports SKIP=true (skip conflicting files) and makes FORCE/SKIP opt-in via a new truthy_env? check (only true/1/yes, case-insensitive), with FORCE taking precedence.

Docs were updated (README + CHANGELOG) to describe the new SKIP mode and the stricter env var parsing behavior.

Written by Cursor Bugbot for commit 1d3c1ba. Configure here.

justin808 and others added 4 commits February 15, 2026 12:17
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renames the variable to better reflect its purpose now that it handles
both FORCE and SKIP modes. Adds a note that FORCE takes precedence
when both are set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, any set value for ENV["SKIP"] or ENV["FORCE"] (including
"false" or "0") would activate skip/force mode. Now only "true", "1",
and "yes" (case-insensitive) are treated as truthy.

Extracts a truthy_env? helper in template.rb, reused by binstubs.rb.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d3c1ba and 75e20fb.

📒 Files selected for processing (1)
  • lib/install/binstubs.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/install/binstubs.rb

Walkthrough

Adds a SKIP=true installer mode and a truthy_env? helper; changes conflict-resolution to prefer FORCE when truthy, otherwise honor SKIP, and applies the new conflict_option ({ force: true } / { skip: true } / {}) across installer templates and binstub copying.

Changes

Cohort / File(s) Summary
Changelog & README
CHANGELOG.md, README.md
Documented the new SKIP=true installer option and clarified conflict-resolution guidance, noting FORCE precedence when both are set and updated wording around prompts.
Installer Template
lib/install/template.rb
Added truthy_env?(name) helper and replaced previous force_option with conflict_option that returns { force: true }, { skip: true }, or {} based on environment variables; applied to file-copy operations.
Binstubs Installer
lib/install/binstubs.rb
Replaced force_option with conflict_option so binstub copying respects FORCE and SKIP environment variables (uses same truthy check).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniff the env for truth and skip,
FORCE nudges forward, SKIP lets files sit.
A careful hop, a tidy sweep,
New bits arrive — old blooms we keep.
Hooray for peaceful installs! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and directly summarizes the main change: enforcing explicit truthy values for SKIP and FORCE environment variables in the installer.
Linked Issues check ✅ Passed The pull request fully implements the objectives from issue #889: adds SKIP mode with truthy_env? helper, updates documentation, prevents ambiguous env var parsing, and enables non-interactive callers to preserve existing files.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objectives: documentation updates describe the feature, code changes implement the truthy_env? helper and conflict_option logic, and changelog entries document the fix.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jg/889-truthy-env-check-installer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@CHANGELOG.md`:
- Line 16: Update the CHANGELOG entry that currently reads "Added `SKIP=true`
installer mode..." to link to the correct PR number by replacing the PR link and
reference from `#893` to [PR
`#926`](https://github.com/shakacode/shakapacker/pull/926) while keeping the
author reference as [justin808](https://github.com/justin808); also append a
short clause to the same entry mentioning the truthy-values behavioral change
(e.g., "also fixes handling of truthy values") so the description matches the PR
objectives title and conforms to the required `[PR
`#123`](https://github.com/.../pull/123) by
[username](https://github.com/username)` format.
🧹 Nitpick comments (1)
lib/install/template.rb (1)

30-30: Pre-existing inconsistency: USE_BABEL_PACKAGES check doesn't use truthy_env?.

Line 30 manually checks == "true" || == "1" but doesn't recognize "yes". Consider using the new truthy_env? helper for consistency, which would also add "yes" support.

♻️ Suggested change
-if ENV["USE_BABEL_PACKAGES"] == "true" || ENV["USE_BABEL_PACKAGES"] == "1"
+if truthy_env?("USE_BABEL_PACKAGES")

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 16, 2026

Greptile Summary

This PR fixes a bug where SKIP=false or FORCE=0 would incorrectly activate skip/force mode because any set value (including falsy strings) was treated as truthy. The implementation adds a truthy_env? helper that only accepts "true", "1", and "yes" (case-insensitive) as truthy values.

  • Extracted truthy_env? helper in template.rb, properly accessible in binstubs.rb via apply
  • Renamed force_option to conflict_option for better clarity
  • Updated README.md to document both FORCE=true and SKIP=true options with precedence behavior
  • Added appropriate changelog entry for the SKIP=true feature

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is clean, focused, and fixes a clear bug in environment variable parsing. The truthy_env? helper is simple and correctly handles all edge cases (nil, empty string, case-insensitivity). The precedence logic (FORCE before SKIP) is clearly documented and properly implemented. All files are appropriately updated including documentation.
  • No files require special attention

Important Files Changed

Filename Overview
lib/install/template.rb Added truthy_env? helper that only accepts "true", "1", or "yes" (case-insensitive) as truthy values, replacing previous behavior that treated any set value as truthy
lib/install/binstubs.rb Updated to use truthy_env? helper via apply from template.rb, renamed variable from force_option to conflict_option for clarity
README.md Updated documentation to mention both FORCE=true and SKIP=true options with precedence clarification
CHANGELOG.md Added changelog entry for SKIP=true installer mode feature

Flowchart

flowchart TD
    A[User runs rails shakapacker:install] --> B{Check ENV variables}
    B --> C{truthy_env? FORCE}
    C -->|true/1/yes| D[conflict_option = force: true]
    C -->|Other values| E{truthy_env? SKIP}
    E -->|true/1/yes| F[conflict_option = skip: true]
    E -->|Other values| G[conflict_option = empty]
    D --> H[copy_file/directory with options]
    F --> H
    G --> H
    H --> I{File exists?}
    I -->|Yes + force| J[Overwrite file]
    I -->|Yes + skip| K[Skip file]
    I -->|Yes + empty| L[Prompt user]
    I -->|No| M[Create file]
Loading

Last reviewed commit: 3c664b6

justin808 and others added 2 commits February 17, 2026 14:04
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is ON, but it could not run because Privacy Mode (Legacy) is turned on. To enable Bugbot Autofix, switch your privacy mode in the Cursor dashboard.

{ skip: true }
else
{}
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated conflict_option block across two files

Low Severity

The conflict_option computation is duplicated identically in both template.rb and binstubs.rb. Since apply shares instance state but not local variables, using @conflict_option in template.rb would make it available in binstubs.rb without duplication. As-is, any future change to conflict resolution logic (e.g., adding a new env var) requires updating both files in sync, risking divergence.

Additional Locations (1)

Fix in Cursor Fix in Web


### Added

- **Added `SKIP=true` installer mode to preserve existing files**. [PR #893](https://github.com/shakacode/shakapacker/pull/893) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong PR number. The SKIP=true support is being introduced in this PR (#926), not in PR #893. The link should point to #926.

Suggested change
- **Added `SKIP=true` installer mode to preserve existing files**. [PR #893](https://github.com/shakacode/shakapacker/pull/893) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.
- **Added `SKIP=true` installer mode to preserve existing files**. [PR #926](https://github.com/shakacode/shakapacker/pull/926) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.

# Install Shakapacker

force_option = ENV["FORCE"] ? { force: true } : {}
def truthy_env?(name)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The truthy_env? method is defined at the top level of the generator template, which in Rails generator context means it becomes an instance method on the generator object — that's the correct pattern here and it's why binstubs.rb can call it after apply.

One minor note: binstubs.rb recomputes conflict_option using truthy_env? rather than relying on the conflict_option local variable already computed in template.rb. This is intentional and correct — apply evaluates the file in the same generator instance (so instance methods like truthy_env? are shared) but with a new local variable scope (so conflict_option is not visible). A short comment explaining why the variable is duplicated would help future readers avoid "simplifying" it incorrectly.

# truthy_env? is defined in template.rb (the parent template).
# It is accessible here because apply shares the same generator instance.
# conflict_option must be recomputed because apply creates a new local variable scope.

@claude
Copy link

claude bot commented Feb 27, 2026

Review

The core change is correct and well-scoped — using truthy_env? to require explicit opt-in values for FORCE/SKIP is a clear improvement over the old ENV["FORCE"] ? truthiness check (which treated "false" and "0" as truthy).

Issues

CHANGELOG references wrong PR number (inline comment filed)
The "Added" entry on line 16 links to PR #893 but the SKIP support is introduced in this PR (#926). Should be PR #926.

conflict_option is duplicated in binstubs.rb (inline comment filed on template.rb:10)
This is actually correct behaviour — apply shares the generator instance (so truthy_env? is available) but creates a new local variable scope (so the conflict_option local from template.rb is not visible). The risk is that a future maintainer notices the apparent duplication and removes it from binstubs.rb, breaking the binstub install silently. A one-line comment explaining the scoping would prevent that.

Observations (non-blocking)

No unit tests for truthy_env?
The logic is simple but the change in semantics is a potential breaking change for anyone who relied on FORCE=false or FORCE=0 to do a no-op (rare but possible). A small RSpec unit test or isolated spec exercising the helper with truthy/falsy values would be valuable.

Other env vars in template.rb remain inconsistent
SKIP_COMMON_LOADERS, SHAKAPACKER_USE_TYPESCRIPT, and USE_BABEL_PACKAGES still use the old-style ENV[x] ? / == "true" checks. Now that truthy_env? exists, these could be migrated for consistency — but that is clearly out of scope for this PR. Worth filing a follow-up issue to keep the env-var semantics uniform across the installer.

Add truthy_env? helper to binstubs.rb so it works when loaded
independently via the shakapacker:binstubs rake task. Previously
the method was only defined in template.rb, causing NoMethodError
when binstubs.rb was applied outside of the full install flow.

Fixes CI failures in EngineRakeTasks specs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 27, 2026

Review Summary

Overall this is a solid improvement — fixing the bug where ENV["FORCE"] = "false" would still activate force mode is a real correctness issue worth addressing, and adding SKIP mode is useful. A few things to flag:

1. Wrong PR number in CHANGELOG

The "Added SKIP=true installer mode" entry links to PR #893, but that feature is being introduced in this PR (#926). The reference should be updated.

2. Duplicate ### Fixed section in CHANGELOG

The PR inserts a new ### Fixed heading before the existing ### Changed section, but a ### Fixed section already exists below ### Changed. This results in two ### Fixed headings in the [Unreleased] block. The new item should be merged into the existing ### Fixed section.

3. truthy_env? is duplicated across both files

The PR description says the helper is "extracted in template.rb, reused by binstubs.rb via apply", but the method is actually re-defined in binstubs.rb as well. When binstubs.rb is run via apply from template.rb, this causes a Ruby method-redefinition (which emits a warning in -W mode). The standalone-execution case does require the definition, but the framing of "reuse via apply" is inaccurate.

A cleaner approach would be to extract it into a shared helper file and apply that from both places — but that's a larger refactor. At minimum the comment/description should be corrected to say both files define the method independently.

4. No tests for the new falsy-value behavior

The generator spec always passes FORCE=true (which is truthy under both old and new logic), so it doesn't exercise the bug fix at all. A unit test or spec that verifies FORCE=false / FORCE=0 / SKIP=false are treated as inactive would prevent regressions.

5. Minor: no / off are common truthy-style negations

Some tooling (e.g., Ansible, GitHub Actions) treats no and off as canonical false values in boolean env var conventions. This PR correctly ignores them (they map to falsy), so no action needed — just worth documenting the accepted values in a comment for future readers.


### Added

- **Added `SKIP=true` installer mode to preserve existing files**. [PR #893](https://github.com/shakacode/shakapacker/pull/893) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong PR number: this feature is being introduced in this PR (#926), not #893. The reference should be [PR #926](https://github.com/shakacode/shakapacker/pull/926).


- **Added `SKIP=true` installer mode to preserve existing files**. [PR #893](https://github.com/shakacode/shakapacker/pull/893) by [justin808](https://github.com/justin808). Running `rails shakapacker:install SKIP=true` now skips conflicting files instead of overwriting them. This is useful for CI/CD pipelines and automated setups where you want to install only missing files without touching existing configuration.

### Fixed
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inserts a ### Fixed section here, but there is already a ### Fixed section later in the [Unreleased] block (below ### Changed). This results in two ### Fixed headings. The new entry should be merged into the existing ### Fixed section instead of creating a duplicate heading.

@@ -1,6 +1,16 @@
force_option = ENV["FORCE"] ? { force: true } : {}
def truthy_env?(name)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says this method is "reused via apply" from template.rb, but it's actually re-defined here independently. When binstubs.rb is evaluated via apply inside a running template.rb session, Ruby will emit a method-redefinition warning because truthy_env? was already defined.

For standalone execution of binstubs.rb the definition is necessary, but the two files are currently managing this independently. Consider either:

  1. Noting in a comment that the definition is intentionally duplicated for standalone-execution support, or
  2. Extracting to a shared helper file that both require/apply
# Defined here for standalone execution; template.rb defines the same method
# when this file is run via `apply` in the full install flow.
def truthy_env?(name)
  %w[true 1 yes].include?(ENV[name].to_s.downcase)
end

# Install Shakapacker

force_option = ENV["FORCE"] ? { force: true } : {}
def truthy_env?(name)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tests cover the falsy-value fix. The generator spec always invokes FORCE=true, which is truthy under both the old and new logic, so it doesn't exercise the actual bug being fixed. Consider adding a unit-level test that confirms FORCE=false, FORCE=0, and SKIP=false all produce an empty conflict_option.

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

Successfully merging this pull request may close these issues.

Add SKIP env var to installer for preserving existing config files

1 participant