Last active
December 11, 2023 00:53
-
-
Save tigerhawkvok/aad3f184b37bb869df5bd337d4b4c22e to your computer and use it in GitHub Desktop.
Get the installation path for a package installed by Chocolatey
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!python3 | |
""" | |
Script and function to get the path of a chocolatey install | |
matching the `pathComponent`, or, if none provided, the | |
last installed path. | |
@author Philip Kahn | |
@date 20230614 | |
@license MIT | |
@url https://gist.github.com/tigerhawkvok/aad3f184b37bb869df5bd337d4b4c22e | |
""" | |
import subprocess | |
import re | |
from pathlib import Path | |
import warnings | |
from typing import Optional | |
import argparse | |
# cSpell:words choco | |
def getChocoInstalledPath(pathComponent:Optional[str]= None) -> Path: | |
""" | |
Spawn a subprocess to get the last installed path of a chocolatey package. | |
Parameters | |
---------- | |
pathComponent : Optional[str] | |
A known path component of the path to be found. | |
If `None`, the last installed path is returned. | |
Returns | |
------- | |
Path | |
Raises | |
------ | |
ValueError | |
""" | |
if pathComponent == "": | |
pathComponent = None | |
# TODO be clever about Chocolatey install path | |
command = """(Get-Content "$env:PROGRAMDATA\chocolatey\logs\choco.summary.log") -match 'Software installed to'""" | |
if pathComponent is None: | |
command += " | Select-Object -Last 1" | |
result = subprocess.run(["powershell", "-Command", command], capture_output= True, text= True, encoding= "utf-8", shell= True, check= True) | |
stdout = result.stdout | |
if pathComponent is not None: | |
# Search for the path component | |
found = False | |
for entry in reversed(stdout.splitlines()): | |
# Search most recent first | |
if pathComponent in entry: | |
stdout = entry | |
found = True | |
break | |
if not found: | |
raise ValueError(f"No path found containing substring `{pathComponent}`") | |
# A single candidate line has been found | |
output = re.search(r"Software installed to '(.*)'", stdout) | |
if output is not None: | |
# Do some path validation | |
outPath = Path(output.group(1)) | |
if outPath.exists(): | |
if not outPath.is_dir(): | |
warnings.warn("The path found is not a directory") | |
return outPath | |
warnings.warn("The path found does not exist") | |
return outPath | |
raise ValueError("No path found") | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description= "Get the path of a chocolatey install matching the pathComponent, or, if none provided, the last installed path") | |
parser.add_argument('pathComponent', type= str, nargs= '?', | |
help='a known path component of the path to be found') | |
args = parser.parse_args() | |
print(getChocoInstalledPath(args.pathComponent)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment