|
| 1 | +# venv-cli - A CLI tool to create and manage virtual python environments. |
| 2 | + |
| 3 | +## Overview |
| 4 | +`venv-cli` is a CLI tool to help create and manage virtual python environments. |
| 5 | +It uses `pip` and `python -m venv` underneath, and so only requires core python. This alleviates the bootstrapping problem of needing to install a python package using your system python and pip before you are able to create virtual environments. |
| 6 | + |
| 7 | +You also don't need `conda`, `pyenv`, `pythonz` etc. to manage your python versions. Just make sure the correct version of python is installed on your system, then reference that specific version when creating the virtual environment, and everything just works. No shims, no path hacks, just the _official_ `python` build. |
| 8 | + |
| 9 | +## Installation |
| 10 | + |
| 11 | +Clone this repository, then add a line to your `~/.bashrc` (or `~/.zshrc`, etc) that sources the `src/venv-cli/venv.sh` file: |
| 12 | + |
| 13 | +```bash |
| 14 | +if [ -f ~/venv-cli/src/venv-cli/venv.sh ]; then |
| 15 | + . ~/venv-cli/src/venv-cli/venv.sh |
| 16 | +fi |
| 17 | +``` |
| 18 | + |
| 19 | +This makes the `venv` command avaiable in your terminal. To check if it works, restart the terminal and run |
| 20 | +```console |
| 21 | +$ venv --version |
| 22 | +venv-cli 1.0.0 |
| 23 | +``` |
| 24 | + |
| 25 | +## Usage |
| 26 | + |
| 27 | +To see the help menu, along with a list of available commands, run `venv -h/--help`. |
| 28 | + |
| 29 | +**In the following sections it is assumed that the working directory is the folder `~/project`.** |
| 30 | +### Create virtual environment |
| 31 | +To create a virtual environment, use the command |
| 32 | +```console |
| 33 | +$ venv create <python-version> |
| 34 | +``` |
| 35 | +e.g. |
| 36 | +```console |
| 37 | +$ venv create 3.9 |
| 38 | +``` |
| 39 | + |
| 40 | +This creates a virtual environment using the `python3.9` executable on `$PATH`. The name of the virtual environment will be the name of the current folder (in this case, `project` ), unless you specify a name when creating the environment: |
| 41 | + |
| 42 | +```console |
| 43 | +$ venv create 3.9 venv-name |
| 44 | +``` |
| 45 | + |
| 46 | +If you don't have the specific version of python installed yet, you can get it by running |
| 47 | +```console |
| 48 | +$ sudo apt install python<version>-venv |
| 49 | +``` |
| 50 | +e.g. |
| 51 | +```console |
| 52 | +$ sudo apt install python3.10-venv |
| 53 | +``` |
| 54 | + |
| 55 | +The `-venv` part is necessary to be able to use this system python to create virtual environments. |
| 56 | + |
| 57 | +## Activating and deactivating the virtual environment |
| 58 | +To activate the virtual environment, from the folder containing `.venv` run |
| 59 | +```console |
| 60 | +$ venv activate |
| 61 | +``` |
| 62 | + |
| 63 | +To deactivate it again, run |
| 64 | +```console |
| 65 | +$ venv deactivate |
| 66 | +``` |
| 67 | + |
| 68 | +## Install packages/requirements |
| 69 | +The proper way to install packages in the virtual environment is to add them to a `requirements.txt` file and then install from that: |
| 70 | + |
| 71 | +```console |
| 72 | +$ echo "pandas ~= 1.5" >> requirements.txt |
| 73 | + |
| 74 | +$ venv install requirements.txt |
| 75 | + |
| 76 | +Installing requirements from requirements.txt |
| 77 | +Collecting pandas~=1.5 |
| 78 | + Using cached pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.1 MB) |
| 79 | +Collecting python-dateutil>=2.8.1 |
| 80 | + Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB) |
| 81 | +Collecting numpy>=1.21.0 |
| 82 | + Using cached numpy-1.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.6 MB) |
| 83 | +Collecting pytz>=2020.1 |
| 84 | + Using cached pytz-2023.3-py2.py3-none-any.whl (502 kB) |
| 85 | +Collecting six>=1.5 |
| 86 | + Using cached six-1.16.0-py2.py3-none-any.whl (11 kB) |
| 87 | +Installing collected packages: pytz, six, numpy, python-dateutil, pandas |
| 88 | +Successfully installed numpy-1.25.1 pandas-1.5.3 python-dateutil-2.8.2 pytz-2023.3 six-1.16.0 |
| 89 | +``` |
| 90 | + |
| 91 | +In fact, if you don't specify the file name, `venv` will assume that you want to install from `requirements.txt`, so |
| 92 | +```console |
| 93 | +$ venv install |
| 94 | + |
| 95 | +$ venv install requirements.txt |
| 96 | +``` |
| 97 | +are equivalent. |
| 98 | + |
| 99 | +The installed packages are then _locked_ into the corresponding `.lock`-file, e.g. running `venv install dev-requirements.txt` will lock those installed packages into `dev-requirements.lock`. |
| 100 | + |
| 101 | +Installing packages this way makes sure that they are "tracked", since installing them with `pip install` will keep no record of which packages have been installed in the environment, making it difficult to reproduce later on. |
| 102 | + |
| 103 | +### Development packages |
| 104 | +If you have both production and development package requirements, keep them in separate requirements-files, e.g. `requirements.txt` for production and `dev-requirements.txt` for development. An example of these could be: |
| 105 | +```bash |
| 106 | +# requirements.txt |
| 107 | +numpy |
| 108 | +pandas ~= 1.5 |
| 109 | + |
| 110 | + |
| 111 | +# dev-requirements.txt |
| 112 | +-r requirements.txt |
| 113 | +jupyter |
| 114 | +matplotlib |
| 115 | +``` |
| 116 | + |
| 117 | +The `-r requirements.txt` will make sure that installing development requirements also install production requirements. |
| 118 | + |
| 119 | +## Reproducing environment |
| 120 | +To install a reproducible environment, you need to install from a `.lock`-file, since those have all versions of all requirements locked. From a clean environment (no packages installed yet), run |
| 121 | +```console |
| 122 | +$ venv install requirements.lock |
| 123 | +``` |
| 124 | + |
| 125 | +If you don't have a clean environment, but still want to recreate the environment as it was when the requirements were locked, you can run |
| 126 | +```console |
| 127 | +$ venv sync requirements.lock |
| 128 | +``` |
| 129 | + |
| 130 | +This will first remove all installed packages, then run `venv install requirements.lock`. |
| 131 | + |
| 132 | +**NOTE: Since this command is meant to create a reproducable environment, you cannot `sync` to a `.txt` file; it has to be a `.lock` file.** |
| 133 | + |
| 134 | +## Clearing the environment |
| 135 | +If you want to manually clear the environment, you can run |
| 136 | +```console |
| 137 | +$ venv clear |
| 138 | +``` |
| 139 | + |
| 140 | +This will uninstall all installed packages from the environment. This is useful if you have installed development packages, and then need to get back to a production environment, e.g. |
| 141 | + |
| 142 | +```console |
| 143 | +$ venv install dev-requirements.txt |
| 144 | + |
| 145 | +# Later |
| 146 | +$ venv clear |
| 147 | +$ venv install requirements.txt |
| 148 | +``` |
| 149 | + |
| 150 | +## Contributing |
| 151 | + |
| 152 | +As this is meant to be a lightweight tool providing simple, QoL improvements to working with `pip` and `python -m venv`, we will not be adding a lot of big, additional features. |
| 153 | + |
| 154 | +That said, pull requests are welcome. For bigger changes, please open an issue first to discuss what you would like to change. |
| 155 | + |
| 156 | +To contribute, clone the repo, create a virtual environment (preferably using `venv-cli`) and install `dev-requirements.txt`. When you are done with your changes, run the test suite with |
| 157 | +```console |
| 158 | +$ pytest . |
| 159 | +``` |
| 160 | + |
| 161 | +Every subcommand has its own test file `tests/test_venv_<command>.py` Please make sure to add/update tests as appropriate. |
| 162 | + |
| 163 | +## License |
| 164 | + |
| 165 | +[MIT](https://choosealicense.com/licenses/mit/) |
0 commit comments