Skip to content

Commit 624080d

Browse files
authored
Merge pull request #165 from thawn/copilot/fix-chrome-detection-mac-os
Add macOS Chrome/Chromium detection in .app bundle locations
2 parents aa2ff16 + efbe05a commit 624080d

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed

src/ttmp32gme/build/file_handler.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,42 @@ def get_executable_path(executable_name: str) -> Optional[str]:
378378
return str(chrome_path)
379379
# Add .exe extension for other Windows executables
380380
executable_name += ".exe"
381-
else:
382-
# Unix-like systems
381+
elif platform.system() == "Darwin": # macOS
382+
# macOS-specific Chrome/Chromium installation paths
383+
if executable_name in [
384+
"chrome",
385+
"google-chrome",
386+
"chromium",
387+
"chromium-browser",
388+
]:
389+
chrome_paths = [
390+
# Google Chrome in /Applications
391+
Path("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"),
392+
# Chromium in /Applications
393+
Path("/Applications/Chromium.app/Contents/MacOS/Chromium"),
394+
# Google Chrome in ~/Applications
395+
Path.home()
396+
/ "Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
397+
# Chromium in ~/Applications
398+
Path.home() / "Applications/Chromium.app/Contents/MacOS/Chromium",
399+
]
400+
for chrome_path in chrome_paths:
401+
if chrome_path.exists() and os.access(chrome_path, os.X_OK):
402+
return str(chrome_path)
403+
404+
# Check common Unix-like system paths (Linux and macOS)
405+
if platform.system() != "Windows":
383406
common_paths = [
384407
Path("/usr/local/bin"),
385408
Path("/usr/bin"),
386409
Path.home() / "bin",
387410
Path.home() / ".local" / "bin",
388411
]
389412

390-
for path in common_paths:
391-
full_path = path / executable_name
392-
if full_path.exists() and os.access(full_path, os.X_OK):
393-
return str(full_path)
413+
for path in common_paths:
414+
full_path = path / executable_name
415+
if full_path.exists() and os.access(full_path, os.X_OK):
416+
return str(full_path)
394417

395418
return None
396419

tests/unit/test_file_handler.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,74 @@ def test_delete_gme_tiptoi_not_found(self, mock_get_tiptoi):
328328

329329
assert result is False
330330

331+
@patch("ttmp32gme.build.file_handler.platform.system")
332+
@patch("ttmp32gme.build.file_handler.os.access")
333+
@patch("ttmp32gme.build.file_handler.shutil.which")
334+
@patch("ttmp32gme.build.file_handler.Path.home")
335+
def test_get_executable_path_chrome_macos_user_applications(
336+
self, mock_home, mock_which, mock_access, mock_system
337+
):
338+
"""Test finding Chrome in macOS ~/Applications directory."""
339+
mock_system.return_value = "Darwin"
340+
mock_which.return_value = None # Not in PATH
341+
mock_access.return_value = True # File is executable
342+
343+
with tempfile.TemporaryDirectory() as tmpdir:
344+
mock_home.return_value = Path(tmpdir)
345+
346+
# Create fake Chrome.app structure in ~/Applications
347+
chrome_app = (
348+
Path(tmpdir)
349+
/ "Applications"
350+
/ "Google Chrome.app"
351+
/ "Contents"
352+
/ "MacOS"
353+
)
354+
chrome_app.mkdir(parents=True)
355+
chrome_exe = chrome_app / "Google Chrome"
356+
chrome_exe.write_text("fake chrome")
357+
# Make it executable
358+
chrome_exe.chmod(0o755)
359+
360+
result = get_executable_path("google-chrome")
361+
362+
# Should find Chrome in ~/Applications
363+
assert result is not None
364+
assert "Google Chrome" in result
365+
assert str(chrome_exe) == result
366+
367+
@patch("ttmp32gme.build.file_handler.platform.system")
368+
@patch("ttmp32gme.build.file_handler.os.access")
369+
@patch("ttmp32gme.build.file_handler.shutil.which")
370+
@patch("ttmp32gme.build.file_handler.Path.home")
371+
def test_get_executable_path_chromium_macos_user_applications(
372+
self, mock_home, mock_which, mock_access, mock_system
373+
):
374+
"""Test finding Chromium in macOS ~/Applications directory."""
375+
mock_system.return_value = "Darwin"
376+
mock_which.return_value = None # Not in PATH
377+
mock_access.return_value = True # File is executable
378+
379+
with tempfile.TemporaryDirectory() as tmpdir:
380+
mock_home.return_value = Path(tmpdir)
381+
382+
# Create fake Chromium.app structure in ~/Applications
383+
chromium_app = (
384+
Path(tmpdir) / "Applications" / "Chromium.app" / "Contents" / "MacOS"
385+
)
386+
chromium_app.mkdir(parents=True)
387+
chromium_exe = chromium_app / "Chromium"
388+
chromium_exe.write_text("fake chromium")
389+
# Make it executable
390+
chromium_exe.chmod(0o755)
391+
392+
result = get_executable_path("chromium")
393+
394+
# Should find Chromium in ~/Applications
395+
assert result is not None
396+
assert "Chromium" in result
397+
assert str(chromium_exe) == result
398+
331399
@patch("ttmp32gme.build.file_handler.subprocess.run")
332400
@patch("ttmp32gme.build.file_handler.platform.system")
333401
def test_open_browser_linux(self, mock_system, mock_run):

0 commit comments

Comments
 (0)