linux observer
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Capture PATH into systemd unit at install time

install-service now writes Environment=PATH=... into the generated
unit file, with the venv bin directory prepended and duplicates removed.
Falls back to /usr/local/bin:/usr/bin:/bin when PATH is absent or empty.

+90
+7
src/solstone_linux/cli.py
··· 16 16 import asyncio 17 17 import json 18 18 import logging 19 + import os 19 20 import shutil 20 21 import socket 21 22 import subprocess ··· 146 147 ) 147 148 return 1 148 149 150 + venv_bin = str(Path(binary).resolve().parent) 151 + raw_path = os.environ.get("PATH") or "/usr/local/bin:/usr/bin:/bin" 152 + path_entries = [venv_bin] + raw_path.split(":") 153 + service_path = ":".join(dict.fromkeys(path_entries)) 154 + 149 155 unit_dir = Path.home() / ".config" / "systemd" / "user" 150 156 unit_dir.mkdir(parents=True, exist_ok=True) 151 157 unit_path = unit_dir / "solstone-linux.service" ··· 160 166 Type=simple 161 167 ExecStart={binary} run 162 168 PassEnvironment=DISPLAY WAYLAND_DISPLAY DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIR XDG_CURRENT_DESKTOP 169 + Environment=PATH={service_path} 163 170 Restart=on-failure 164 171 RestartSec=10 165 172 StartLimitIntervalSec=300
+83
tests/test_cli.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + 4 + import argparse 5 + import os 6 + from pathlib import Path 7 + from unittest.mock import patch 8 + 9 + from solstone_linux.cli import cmd_install_service 10 + 11 + 12 + def test_cmd_install_service_uses_environment_path(tmp_path: Path): 13 + binary = "/home/user/.local/pipx/venvs/solstone-linux/bin/solstone-linux" 14 + unit_path = tmp_path / ".config" / "systemd" / "user" / "solstone-linux.service" 15 + env = { 16 + "PATH": "/home/user/.local/pipx/venvs/solstone-linux/bin:/usr/local/bin:/usr/bin:/bin:/home/user/.local/bin" 17 + } 18 + 19 + with patch.dict(os.environ, env, clear=True): 20 + with patch("solstone_linux.cli.shutil.which", return_value=binary): 21 + with patch("solstone_linux.cli.Path.home", return_value=tmp_path): 22 + with patch("solstone_linux.cli.subprocess.run"): 23 + with patch("solstone_linux.cli.Path.is_dir", return_value=False): 24 + assert cmd_install_service(argparse.Namespace()) == 0 25 + 26 + unit_content = unit_path.read_text() 27 + path_line = next( 28 + line 29 + for line in unit_content.splitlines() 30 + if line.startswith("Environment=PATH=") 31 + ) 32 + service_path = path_line.removeprefix("Environment=PATH=").split(":") 33 + 34 + assert service_path[0] == "/home/user/.local/pipx/venvs/solstone-linux/bin" 35 + assert service_path == list(dict.fromkeys(service_path)) 36 + 37 + 38 + def test_cmd_install_service_uses_default_path_when_missing(tmp_path: Path): 39 + binary = "/home/user/.local/pipx/venvs/solstone-linux/bin/solstone-linux" 40 + unit_path = tmp_path / ".config" / "systemd" / "user" / "solstone-linux.service" 41 + 42 + with patch.dict(os.environ, {}, clear=True): 43 + with patch("solstone_linux.cli.shutil.which", return_value=binary): 44 + with patch("solstone_linux.cli.Path.home", return_value=tmp_path): 45 + with patch("solstone_linux.cli.subprocess.run"): 46 + with patch("solstone_linux.cli.Path.is_dir", return_value=False): 47 + assert cmd_install_service(argparse.Namespace()) == 0 48 + 49 + unit_content = unit_path.read_text() 50 + path_line = next( 51 + line 52 + for line in unit_content.splitlines() 53 + if line.startswith("Environment=PATH=") 54 + ) 55 + 56 + assert ( 57 + path_line 58 + == "Environment=PATH=/home/user/.local/pipx/venvs/solstone-linux/bin:/usr/local/bin:/usr/bin:/bin" 59 + ) 60 + 61 + 62 + def test_cmd_install_service_uses_default_path_when_empty(tmp_path: Path): 63 + binary = "/home/user/.local/pipx/venvs/solstone-linux/bin/solstone-linux" 64 + unit_path = tmp_path / ".config" / "systemd" / "user" / "solstone-linux.service" 65 + 66 + with patch.dict(os.environ, {"PATH": ""}, clear=True): 67 + with patch("solstone_linux.cli.shutil.which", return_value=binary): 68 + with patch("solstone_linux.cli.Path.home", return_value=tmp_path): 69 + with patch("solstone_linux.cli.subprocess.run"): 70 + with patch("solstone_linux.cli.Path.is_dir", return_value=False): 71 + assert cmd_install_service(argparse.Namespace()) == 0 72 + 73 + unit_content = unit_path.read_text() 74 + path_line = next( 75 + line 76 + for line in unit_content.splitlines() 77 + if line.startswith("Environment=PATH=") 78 + ) 79 + 80 + assert ( 81 + path_line 82 + == "Environment=PATH=/home/user/.local/pipx/venvs/solstone-linux/bin:/usr/local/bin:/usr/bin:/bin" 83 + )