Metadata-Version: 2.3
Name: uvlink
Version: 0.7.1
Summary: CLI helper for keeping Python venvs outside synced project folders
Author: Cory Chu
Author-email: Cory Chu <cory@gwlab.page>
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: rich>=14.2
Requires-Dist: typer>=0.20
Requires-Python: >=3.12
Project-URL: Changelog, https://c0rychu.github.io/uvlink/CHANGELOG/
Project-URL: Documentation, https://c0rychu.github.io/uvlink/
Project-URL: Homepage, https://github.com/c0rychu/uvlink
Project-URL: Issues, https://github.com/c0rychu/uvlink/issues
Project-URL: Repository, https://github.com/c0rychu/uvlink.git
Description-Content-Type: text/markdown

# uvlink
[![PyPI - Version](https://img.shields.io/pypi/v/uvlink)](https://pypi.org/project/uvlink/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/uvlink)](https://pypi.org/project/uvlink/)

`uvlink` is a CLI tool that moves `.venv` folders into a local cache and creates a symlink in your project, so cloud services like Dropbox or iCloud only sync your actual code—not hundreds of megabytes of dependencies.

- [Documentation](https://c0rychu.github.io/uvlink/)
- [Changelog](docs/CHANGELOG.md)

> [!CAUTION]
> Since `v0.6.0`, the cache directory includes the venv type in its folder name and stores the environment under a matching subdirectory (e.g. `~/.local/share/uvlink/cache/<project-name>-<hash>-.venv/.venv`). Delete caches created with older versions and rerun `uvlink link` to migrate.


## Requirements

- Python 3.12+
- macOS or Linux with symlink support

> [!WARNING]
> uvlink is currently only tested on Apple Silicon (M-series) machines running macOS Tahoe. Other operating systems or architectures have not been validated yet.



## Install

### Using `uv tool` (recommended)

```bash
$ uv tool install uvlink
```

This installs the CLI into your `~/.local/bin` (or platform equivalent) with isolated dependencies handled by [Astral's uv](https://docs.astral.sh/uv/).

### Using `pip`

```bash
$ pip install uvlink
```


## Quick Start

Navigate to any Python project (which may be created by `uv init` for instance) and run:

```bash
$ cd /path/to/your/project
$ uvlink link
```

This creates a `.venv` symlink in your project pointing to a cached environment under `~/.local/share/uvlink/cache/<project-name>-<hash>-.venv/.venv`. Now your cloud service ignores the heavy virtual environment files.

After linking, you can do for example `uv sync` to install dependencies into `.venv`, which is now a symlink to the cached environment.

Need a different directory name (for example to match a tooling convention)? Pass it as an optional argument `[VENV_TYPE]`, which defaults to `.venv`:

```bash
$ uvlink link [VENV_TYPE]
```

**List all linked projects:**

```bash
$ uvlink ls
```

Shows all projects having cached environments and whether their symlinks are still linked.

**Clean up unlinked caches:**

```bash
$ uvlink gc
```

Removes cached environments for projects that no longer have working symlinks, freeing up disk space.


## Demo
![](docs/fig/uvlink-demo@2x.gif)

## Advanced Usage

`uvlink` ships with a [Typer](https://typer.tiangolo.com/) CLI. Run `uvlink --help` for all options.

**Specify a project directory:**

```bash
$ uvlink --project-dir /path/to/project link
```

Works from any location without needing to `cd` into the project directory first.

**Swap the .venv folder name:**

```bash
$ uvlink --project-dir /path/to/project link [VENV_TYPE]
```

Custom `[VENV_TYPE]` are helpful when sharing a cache across tooling expectations (e.g., `.venv-prod`, `.venv-dev`).

**Custom Cache Location:**

```bash
$ uvlink --cache-root /path/to/cache link
$ uvlink --cache-root /path/to/cache ls
$ uvlink --cache-root /path/to/cache gc
```

Overrides the default cache directory (`~/.local/share/uvlink/cache`). This applies to all commands (`link`, `ls`, `gc`).



## Notes
uvlink stores environments under `~/.local/share/uvlink/cache/<project-name>-<hash>-<venv_type>/<venv_type>` and makes a symlink `./.venv` back into that. Each project receives a stable hash based on its absolute path, so repeated runs target the same cache location.



## Contributing

Issues and pull requests are welcome. Please keep docstrings and comments in the Google style already used throughout the codebase and run the included linters/formatters before submitting. A pre-commit configuration is provided that runs Ruff and Black; install it with `pre-commit install` to match formatting.