Skip to content

Fix executable discovery on Windows#12

Merged
alec-c4 merged 2 commits intoalec-c4:masterfrom
mapp113:master
Apr 8, 2026
Merged

Fix executable discovery on Windows#12
alec-c4 merged 2 commits intoalec-c4:masterfrom
mapp113:master

Conversation

@mapp113
Copy link
Copy Markdown
Contributor

@mapp113 mapp113 commented Apr 6, 2026

On Windows, File.executable? requires the full file name including the extension (e.g., .exe). This PR updates the search logic to append the extension when running on Windows to ensure binaries are correctly located.

Summary by CodeRabbit

  • New Features

    • Honor explicit environment-variable overrides for external binaries.
  • Bug Fixes

    • Improved cross-platform binary detection using system lookups and platform-specific fallback locations.
    • Non-executable override values now fall through to system discovery instead of failing.
    • Consolidated multi-OS install guidance when binaries are not found.
  • Tests

    • Expanded coverage for configuration detection, timeout default, encoder handling, caching/reset, and environment-variable test helper.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5daa5be5-acf1-40ec-8213-759fd862a081

📥 Commits

Reviewing files that changed from the base of the PR and between cc95d66 and d786b68.

📒 Files selected for processing (2)
  • lib/ffmpeg_core/configuration.rb
  • spec/ffmpeg_core/configuration_spec.rb

📝 Walkthrough

Walkthrough

Refactors binary detection into a staged pipeline: check FFMPEGCORE_<NAME> env override, then perform OS-native system lookup (which/where) and validate executability, then fall back to platform-specific known install paths (including Windows Chocolatey/Scoop/C:/ffmpeg and common macOS/Linux locations); on failure raises BinaryNotFoundError with consolidated multi-OS install guidance.

Changes

Cohort / File(s) Summary
Binary Detection Logic
lib/ffmpeg_core/configuration.rb
Rewrote detect_binary(name) to: 1) prefer FFMPEGCORE_<NAME> env override, 2) use OS-native lookup (which/where) and verify File.executable?, 3) search platform-specific known paths (macOS/Linux and Windows including Chocolatey/Scoop/C:/ffmpeg). Raises BinaryNotFoundError with multi-OS install hints when none found.
Specs / Tests
spec/ffmpeg_core/configuration_spec.rb
Added tests: default timeout == 30; env-override detection (executable and non-executable fallthrough); raising BinaryNotFoundError with platform-install message; detection from known paths; encoders returns empty Set when ffmpeg_binary is nil; added with_env helper; asserted .configuration caching, .configure yields config, and .reset_configuration! replaces instance.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as "Caller (initialize)"
  participant Env as "Environment (FFMPEGCORE_<NAME>)"
  participant System as "OS Lookup (which/where)"
  participant FS as "Known Paths (filesystem)"
  participant Config as "Configuration"

  Caller->>Config: initialize -> detect_binary(name)
  Config->>Env: check FFMPEGCORE_<NAME>
  Env-->>Config: path or nil
  alt env provided & executable
    Config-->>Caller: return env path
  else not provided or not executable
    Config->>System: which/where lookup
    System-->>Config: path or nil
    alt system found & executable
      Config-->>Caller: return system path
    else not found/executable
      Config->>FS: iterate known_paths (macOS/Linux/Windows)
      FS-->>Config: path or nil
      alt known path found & executable
        Config-->>Caller: return known path
      else none found
        Config-->>Caller: raise BinaryNotFoundError (multi-OS install hints)
      end
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I sniff the paths with careful care,
Env, system, then folders laid bare,
If none reply, I sing a cross-OS tune,
Hopping hints for mac, linux, and Windows soon,
A carrot, a test, and a happy rune.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix executable discovery on Windows' accurately reflects the main objective of the pull request, which addresses Windows-specific binary detection by appending file extensions.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

@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.

🧹 Nitpick comments (2)
lib/ffmpeg_core/configuration.rb (2)

46-47: Logic is correct; consider multi-line for readability.

The fix correctly appends .exe on Windows where File.executable? requires the full filename. The inline conditional is functional but long. A multi-line format would improve readability.

✨ Optional: multi-line format for clarity
-        binary = if Gem.win_platform? then File.join(path, name + ".exe") else File.join(path, name) end
+        exe_name = Gem.win_platform? ? "#{name}.exe" : name
+        binary = File.join(path, exe_name)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/ffmpeg_core/configuration.rb` around lines 46 - 47, The inline
conditional that builds `binary` is correct but hard to read; refactor the
expression "binary = if Gem.win_platform? then File.join(path, name + '.exe')
else File.join(path, name) end" into a multi-line if/else block that assigns
`binary` on separate lines (using `Gem.win_platform?`, `File.join(path, ...)`)
and keep the existing `return binary if File.executable?(binary)` check
unchanged to preserve behavior.

42-48: Windows-specific code path lacks test coverage.

The Gem.win_platform? branch is untested. The existing specs in spec/ffmpeg_core/configuration_spec.rb initialize Configuration on the actual platform without stubbing, so CI (likely Linux/macOS) never exercises the .exe logic.

Consider adding a unit test that stubs Gem.win_platform? to return true and mocks File.executable? to verify the correct path is checked.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/ffmpeg_core/configuration.rb` around lines 42 - 48, Add a unit test
exercising the Windows branch of detect_binary: stub Gem.win_platform? to return
true, stub ENV["PATH"] to a predictable value, and mock File.executable? to
assert it is called with paths that append ".exe" (i.e., File.join(path, name +
".exe")); then initialize Configuration (or call detect_binary via the
appropriate method) and assert the returned binary path is the expected .exe
path. Target the spec in spec/ffmpeg_core/configuration_spec.rb and reference
detect_binary, Gem.win_platform?, and File.executable? in the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/ffmpeg_core/configuration.rb`:
- Around line 46-47: The inline conditional that builds `binary` is correct but
hard to read; refactor the expression "binary = if Gem.win_platform? then
File.join(path, name + '.exe') else File.join(path, name) end" into a multi-line
if/else block that assigns `binary` on separate lines (using
`Gem.win_platform?`, `File.join(path, ...)`) and keep the existing `return
binary if File.executable?(binary)` check unchanged to preserve behavior.
- Around line 42-48: Add a unit test exercising the Windows branch of
detect_binary: stub Gem.win_platform? to return true, stub ENV["PATH"] to a
predictable value, and mock File.executable? to assert it is called with paths
that append ".exe" (i.e., File.join(path, name + ".exe")); then initialize
Configuration (or call detect_binary via the appropriate method) and assert the
returned binary path is the expected .exe path. Target the spec in
spec/ffmpeg_core/configuration_spec.rb and reference detect_binary,
Gem.win_platform?, and File.executable? in the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6460f9b8-2d16-43db-ad99-f5e5bdf5783b

📥 Commits

Reviewing files that changed from the base of the PR and between 08babdc and 00c1ab2.

📒 Files selected for processing (1)
  • lib/ffmpeg_core/configuration.rb

@alec-c4 alec-c4 merged commit 15a4224 into alec-c4:master Apr 8, 2026
4 checks passed
@alec-c4
Copy link
Copy Markdown
Owner

alec-c4 commented Apr 8, 2026

@mapp113 I've improved your code a bit, check it please

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.

2 participants