-
Notifications
You must be signed in to change notification settings - Fork 988
Expand file tree
/
Copy pathenvironment.py
More file actions
106 lines (89 loc) · 3.02 KB
/
environment.py
File metadata and controls
106 lines (89 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from __future__ import annotations
import os
import platform
import shutil
from dataclasses import dataclass
from typing import Literal
from kaos.path import KaosPath
def _windows_shell_candidates() -> list[KaosPath]:
"""PowerShell executables to probe, in order.
Prefer PowerShell 7+ (`pwsh`) when present, then fall back to Windows PowerShell 5.1
(`powershell.exe`), matching common developer installs while remaining usable on systems
that only ship the inbox shell.
"""
candidates: list[KaosPath] = []
seen: set[str] = set()
def add(path: str) -> None:
normalized = os.path.normcase(os.path.normpath(path))
if normalized not in seen:
seen.add(normalized)
candidates.append(KaosPath(path))
pwsh = shutil.which("pwsh")
if pwsh:
add(pwsh)
program_files = os.environ.get("ProgramW6432") or os.environ.get(
"ProgramFiles", r"C:\Program Files"
)
add(os.path.join(program_files, "PowerShell", "7", "pwsh.exe"))
system_root = os.environ.get("SYSTEMROOT", r"C:\Windows")
add(
os.path.join(
system_root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"
)
)
powershell = shutil.which("powershell")
if powershell:
add(powershell)
add("powershell.exe")
return candidates
@dataclass(slots=True, frozen=True, kw_only=True)
class Environment:
os_kind: Literal["Windows", "Linux", "macOS"] | str
os_arch: str
os_version: str
shell_name: Literal["bash", "sh", "Windows PowerShell"]
shell_path: KaosPath
@staticmethod
async def detect() -> Environment:
match platform.system():
case "Darwin":
os_kind = "macOS"
case "Windows":
os_kind = "Windows"
case "Linux":
os_kind = "Linux"
case system:
os_kind = system
os_arch = platform.machine()
os_version = platform.version()
if os_kind == "Windows":
shell_name = "Windows PowerShell"
fallback_path = KaosPath("powershell.exe")
for path in _windows_shell_candidates():
if await path.is_file():
shell_path = path
break
else:
shell_path = fallback_path
else:
possible_paths = [
KaosPath("/bin/bash"),
KaosPath("/usr/bin/bash"),
KaosPath("/usr/local/bin/bash"),
]
fallback_path = KaosPath("/bin/sh")
for path in possible_paths:
if await path.is_file():
shell_name = "bash"
shell_path = path
break
else:
shell_name = "sh"
shell_path = fallback_path
return Environment(
os_kind=os_kind,
os_arch=os_arch,
os_version=os_version,
shell_name=shell_name,
shell_path=shell_path,
)