1# Create and activate a new virtualenv.
3# This is to prevent me from making a very common mistake, which is
4# creating the venv and then immediately running "pip install" without
7# This has to be a fish function, because I'm activating the venv.
9# See https://alexwlchan.net/2023/fish-venv/
11function venv --description "Create and activate a new virtual environment"
13 # I don't want venvs in my home directory; block it if I try
14 if test "$PWD" = "$HOME"
18 # I never want to create a virtual environment in the top level of
19 # one of my external volumes; block it if I try -- it means I've
20 # run a command in the wrong directory.
21 if test (dirname "$PWD") = /Volumes
22 print_error "Can’t create a virtualenv in $PWD!"
26 print_info "Creating virtual environment in "(pwd)"/.venv"
27 uv venv --quiet .venv --python 3.14
28 source .venv/bin/activate.fish
29 print_info "Using: "(python3 --version)
31 # Append .venv to the Git exclude file, but only if it's not
34 append_to_file_if_not_exists ".git/info/exclude" ".venv"
37 # Append some other common Python tool directories to the Git
38 # exclude file. These tools already write a `.gitignore` entry
39 # for all the files they contain, but not the folder.
41 # This is necessary for Nova, a macOS text editor I sometimes use.
43 append_to_file_if_not_exists ".git/info/exclude" ".mypy_cache"
44 append_to_file_if_not_exists ".git/info/exclude" ".pytest_cache"
45 append_to_file_if_not_exists ".git/info/exclude" ".ruff_cache"
46 append_to_file_if_not_exists ".git/info/exclude" "__pycache__"
49 # Tell Time Machine that it doesn't need to both backing up the
50 # virtualenv directory.
52 # Note: this is quite slow, so we only run it if we're in my home
53 # directory -- it won't get backed up otherwise.
54 if string match -q "$HOME/*" "$PWD"; and [ $(uname) = "Darwin" ]
55 tmutil addexclusion .venv
58 # Record the path to this venv in ~/.venv_registry.
60 # This is a text file with one directory per line, which records
61 # the location of all virtualenvs I've created. It allows me
62 # to scan all my virtualenvs later if necessary.
63 append_to_file_if_not_exists ~/.venv_registry "$PWD/.venv"