Skip to content

Commit 7b63034

Browse files
committed
feat: add support for scoop apps environment variables
1 parent 562372f commit 7b63034

2 files changed

Lines changed: 44 additions & 8 deletions

File tree

src/py_app_dev/core/scoop_wrapper.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def to_file(self, scoop_file: Path) -> None:
100100

101101

102102
@dataclass
103-
class InstalledApp:
103+
class InstalledScoopApp:
104104
#: App name
105105
name: str
106106
#: App version
@@ -111,6 +111,10 @@ class InstalledApp:
111111
bin_dirs: List[Path]
112112
#: List of directories relative to the app path
113113
env_add_path: List[Path]
114+
#: App scoop manifest file
115+
manifest_file: Path
116+
#: Environment variables defined in the manifest
117+
env_vars: Dict[str, Any] = field(default_factory=dict)
114118

115119
def get_bin_paths(self) -> List[Path]:
116120
"""Return the list of absolute bin paths."""
@@ -126,11 +130,9 @@ def get_all_required_paths(self) -> List[Path]:
126130
unique_paths = list(dict.fromkeys(all_paths))
127131
return unique_paths
128132

129-
130-
@dataclass
131-
class InstalledScoopApp(InstalledApp):
132-
#: App scoop manifest file
133-
manifest_file: Path
133+
def parse_env_vars(self, env_set: Dict[str, str]) -> None:
134+
"""Parse and populate environment variables from the manifest."""
135+
self.env_vars = {key: value.replace("$dir", str(self.path)) for key, value in env_set.items()}
134136

135137

136138
class ScoopWrapper:
@@ -202,14 +204,16 @@ def parse_manifest_file(self, manifest_file: Path) -> InstalledScoopApp:
202204
tool_version: str = manifest_data.get("version", None)
203205
bin_dirs: List[Path] = self.parse_bin_dirs(manifest_data.get("bin", []))
204206
env_add_path: List[Path] = self.parse_env_path_dirs(manifest_data.get("env_add_path", []))
205-
return InstalledScoopApp(
207+
installed_app = InstalledScoopApp(
206208
name=tool_name,
207209
version=tool_version,
208210
path=app_directory,
209211
manifest_file=manifest_file,
210212
bin_dirs=bin_dirs,
211213
env_add_path=env_add_path,
212214
)
215+
installed_app.parse_env_vars(manifest_data.get("env_set", {}))
216+
return installed_app
213217

214218
def get_installed_apps(self) -> List[InstalledScoopApp]:
215219
installed_tools: List[InstalledScoopApp] = []

tests/test_scoop_wrapper.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sys
33
import textwrap
44
from pathlib import Path
5-
from typing import List, Optional, Tuple, Type
5+
from typing import Any, Dict, List, Optional, Tuple, Type
66
from unittest.mock import Mock, patch
77

88
import pytest
@@ -468,3 +468,35 @@ def test_get_tools_to_be_installed(
468468
def test_semver_compare(v1: str, v2: str, expected: int) -> None:
469469
result = _semver_compare(v1, v2)
470470
assert result == expected, f"Comparison of '{v1}' and '{v2}' failed: Expected {expected}, Got {result}"
471+
472+
473+
@pytest.mark.parametrize(
474+
"env_set, expected_env_vars",
475+
[
476+
({"MY_COMP_ROOT": "$dir"}, {"MY_COMP_ROOT": "{path}"}),
477+
({"MY_LIB": "my_lib", "MY_COMP_BIN": "$dir/bin"}, {"MY_LIB": "my_lib", "MY_COMP_BIN": "{path}/bin"}),
478+
],
479+
)
480+
def test_env_vars_parsing(scoop_dir: Path, env_set: Dict[str, Any], expected_env_vars: Dict[str, Any]) -> None:
481+
scoop_wrapper = create_scoop_wrapper(scoop_dir / "scoop.ps1")
482+
483+
# Create a mock manifest file with env_set
484+
manifest_file = scoop_dir / "apps" / "app_with_env" / "1.0" / "manifest.json"
485+
manifest_file.parent.mkdir(parents=True)
486+
manifest_file.write_text(
487+
json.dumps(
488+
{
489+
"version": "1.0",
490+
"env_set": env_set,
491+
}
492+
)
493+
)
494+
495+
# Parse the manifest file
496+
installed_app = scoop_wrapper.parse_manifest_file(manifest_file)
497+
498+
# Format expected_env_vars with the actual path
499+
formatted_expected_env_vars = {key: value.format(path=str(installed_app.path)) for key, value in expected_env_vars.items()}
500+
501+
# Assert the environment variables are correctly parsed
502+
assert installed_app.env_vars == formatted_expected_env_vars

0 commit comments

Comments
 (0)