Skip to content

Instantly share code, notes, and snippets.

@pmolodo
Last active May 23, 2025 23:41
Show Gist options
  • Save pmolodo/9550e0643645caf61e275a8b1298e775 to your computer and use it in GitHub Desktop.
Save pmolodo/9550e0643645caf61e275a8b1298e775 to your computer and use it in GitHub Desktop.
Installs the uv tool in a .uv subdirectory of this folder
#!/usr/bin/env python
"""Installs the uv tool in a .uv subdirectory of this folder"""
import argparse
import enum
import inspect
import os
import shutil
import subprocess
import sys
import traceback
import urllib.request
###############################################################################
# Constants
###############################################################################
THIS_FILE = os.path.abspath(inspect.getsourcefile(lambda: None) or __file__)
THIS_DIR = os.path.dirname(THIS_FILE)
DEFAULT_UV_DIR = os.path.join(THIS_DIR, ".uv")
# Note that even if you install with the .sh on windows, it will autodetect platform
# and download uv.exe
UV_FILENAME = "uv.exe" if sys.platform == "win32" else "uv"
INSTALL_SH_URL = "https://astral.sh/uv/install.sh"
INSTALL_PS1_URL = "https://astral.sh/uv/install.ps1"
###############################################################################
# Utilities
###############################################################################
def download_url(url: str, output_path: str):
with urllib.request.urlopen(url) as response, open(output_path, "wb") as out_file:
shutil.copyfileobj(response, out_file)
###############################################################################
# Core Functions
###############################################################################
class ScriptType(enum.Enum):
POWERSHELL = 1
SH = 2
@classmethod
def by_host(cls):
return cls.POWERSHELL if sys.platform == "win32" else cls.SH
def install_environ(uv_dir):
# $XDG_BIN_HOME will set the install directory
env = dict(os.environ)
env["XDG_BIN_HOME"] = uv_dir
env["UV_NO_MODIFY_PATH"] = "1"
return env
def uv_install(uv_dir=DEFAULT_UV_DIR, script_type: ScriptType | None = None, add_to_path=True):
uv_path = os.path.join(uv_dir, UV_FILENAME)
if os.path.isfile(uv_path):
return
if script_type is None:
script_type = ScriptType.by_host()
if not os.path.isdir(uv_dir):
os.makedirs(uv_dir)
match script_type:
case ScriptType.POWERSHELL:
install_script_filename = "install_uv.ps1"
install_url = INSTALL_PS1_URL
install_args = ["powershell", "-ExecutionPolicy", "ByPass"]
case ScriptType.SH:
install_script_filename = "install_uv.sh"
install_url = INSTALL_SH_URL
install_args = ["sh"]
case _:
raise ValueError(f"unrecognized script_type: {script_type}")
install_script_path = os.path.join(uv_dir, install_script_filename)
download_url(install_url, install_script_path)
install_args.append(install_script_path)
subprocess.run(install_args, env=install_environ(uv_dir=uv_dir))
os.remove(install_script_path)
if add_to_path:
# only adds to the path for the current python process
path = [x for x in os.environ.get("PATH", "").split(os.pathsep) if x]
if DEFAULT_UV_DIR not in path:
path.append(DEFAULT_UV_DIR)
os.environ["PATH"] = os.pathsep.join(path)
return uv_path
def uv(args, uv_dir=)
###############################################################################
# CLI
###############################################################################
def get_parser():
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"-u", "--uv-dir", help="Path to the folder to install the uv executable in", default=DEFAULT_UV_DIR
)
osgroup = parser.add_mutually_exclusive_group()
osgroup.add_argument(
"-s",
"--sh",
dest="script_type",
action="store_const",
const=ScriptType.SH,
help=f"Force install via {INSTALL_SH_URL}",
)
osgroup.add_argument(
"-p",
"--powershell",
dest="script_type",
action="store_const",
const=ScriptType.POWERSHELL,
help=f"Force install via {INSTALL_PS1_URL}",
)
return parser
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
parser = get_parser()
args = parser.parse_args(argv)
try:
uv_install(uv_dir=args.uv_dir, script_type=args.script_type)
except Exception: # pylint: disable=broad-except
traceback.print_exc()
return 1
return 0
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment