Implement uv build (#6895)

## Summary

This PR exposes uv's PEP 517 implementation via a `uv build` frontend,
such that you can use `uv build` to build source and binary
distributions (i.e., wheels and sdists) from a given directory.

There are some TODOs that I'll tackle in separate PRs:

- [x] Support building a wheel from a source distribution (rather than
from source) (#6898)
- [x] Stream the build output (#6912)

Closes https://github.com/astral-sh/uv/issues/1510

Closes https://github.com/astral-sh/uv/issues/1663.
This commit is contained in:
Charlie Marsh 2024-09-04 11:23:46 -04:00 committed by GitHub
parent a3a1bfd5ec
commit df84d25a7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 1028 additions and 168 deletions

View file

@ -36,6 +36,8 @@ uv [OPTIONS] <COMMAND>
</dd>
<dt><a href="#uv-venv"><code>uv venv</code></a></dt><dd><p>Create a virtual environment</p>
</dd>
<dt><a href="#uv-build"><code>uv build</code></a></dt><dd><p>Build Python packages into source distributions and wheels</p>
</dd>
<dt><a href="#uv-cache"><code>uv cache</code></a></dt><dd><p>Manage uv&#8217;s cache</p>
</dd>
<dt><a href="#uv-version"><code>uv version</code></a></dt><dd><p>Display uv&#8217;s version</p>
@ -4766,7 +4768,7 @@ uv pip sync [OPTIONS] <SRC_FILE>...
</dd><dt><code>--python</code>, <code>-p</code> <i>python</i></dt><dd><p>The Python interpreter into which packages should be installed.</p>
<p>By default, syncing requires a virtual environment. An path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>By default, syncing requires a virtual environment. A path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>See <a href="#uv-python">uv python</a> for details on Python discovery and supported request formats.</p>
@ -5128,7 +5130,7 @@ uv pip install [OPTIONS] <PACKAGE|--requirement <REQUIREMENT>|--editable <EDITAB
</ul>
</dd><dt><code>--python</code>, <code>-p</code> <i>python</i></dt><dd><p>The Python interpreter into which packages should be installed.</p>
<p>By default, installation requires a virtual environment. An path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>By default, installation requires a virtual environment. A path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>See <a href="#uv-python">uv python</a> for details on Python discovery and supported request formats.</p>
@ -5364,7 +5366,7 @@ uv pip uninstall [OPTIONS] <PACKAGE|--requirement <REQUIREMENT>>
</dd><dt><code>--python</code>, <code>-p</code> <i>python</i></dt><dd><p>The Python interpreter from which packages should be uninstalled.</p>
<p>By default, uninstallation requires a virtual environment. An path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>By default, uninstallation requires a virtual environment. A path to an alternative Python can be provided, but it is only recommended in continuous integration (CI) environments and should be used with caution, as it can modify the system Python installation.</p>
<p>See <a href="#uv-python">uv python</a> for details on Python discovery and supported request formats.</p>
@ -6184,6 +6186,267 @@ uv venv [OPTIONS] [PATH]
</dd></dl>
## uv build
Build Python packages into source distributions and wheels.
By default, `uv build` will build a source distribution ("sdist") from the source directory, and a binary distribution ("wheel") from the source distribution.
`uv build --sdist` can be used to build only the source distribution, `uv build --wheel` can be used to build only the binary distribution, and `uv build --sdist --wheel` can be used to build both distributions from source.
<h3 class="cli-reference">Usage</h3>
```
uv build [OPTIONS] [SRC_DIR]
```
<h3 class="cli-reference">Arguments</h3>
<dl class="cli-reference"><dt><code>SRC_DIR</code></dt><dd><p>The directory from which distributions should be built.</p>
<p>Defaults to the current working directory.</p>
</dd></dl>
<h3 class="cli-reference">Options</h3>
<dl class="cli-reference"><dt><code>--allow-insecure-host</code> <i>allow-insecure-host</i></dt><dd><p>Allow insecure connections to a host.</p>
<p>Can be provided multiple times.</p>
<p>Expects to receive either a hostname (e.g., <code>localhost</code>), a host-port pair (e.g., <code>localhost:8080</code>), or a URL (e.g., <code>https://localhost</code>).</p>
<p>WARNING: Hosts included in this list will not be verified against the system&#8217;s certificate store. Only use <code>--allow-insecure-host</code> in a secure network with verified sources, as it bypasses SSL verification and could expose you to MITM attacks.</p>
<p>May also be set with the <code>UV_INSECURE_HOST</code> environment variable.</p>
</dd><dt><code>--cache-dir</code> <i>cache-dir</i></dt><dd><p>Path to the cache directory.</p>
<p>Defaults to <code>$HOME/Library/Caches/uv</code> on macOS, <code>$XDG_CACHE_HOME/uv</code> or <code>$HOME/.cache/uv</code> on Linux, and <code>%LOCALAPPDATA%\uv\cache</code> on Windows.</p>
<p>May also be set with the <code>UV_CACHE_DIR</code> environment variable.</p>
</dd><dt><code>--color</code> <i>color-choice</i></dt><dd><p>Control colors in output</p>
<p>[default: auto]</p>
<p>Possible values:</p>
<ul>
<li><code>auto</code>: Enables colored output only when the output is going to a terminal or TTY with support</li>
<li><code>always</code>: Enables colored output regardless of the detected environment</li>
<li><code>never</code>: Disables colored output</li>
</ul>
</dd><dt><code>--config-file</code> <i>config-file</i></dt><dd><p>The path to a <code>uv.toml</code> file to use for configuration.</p>
<p>While uv configuration can be included in a <code>pyproject.toml</code> file, it is not allowed in this context.</p>
<p>May also be set with the <code>UV_CONFIG_FILE</code> environment variable.</p>
</dd><dt><code>--config-setting</code>, <code>-C</code> <i>config-setting</i></dt><dd><p>Settings to pass to the PEP 517 build backend, specified as <code>KEY=VALUE</code> pairs</p>
</dd><dt><code>--exclude-newer</code> <i>exclude-newer</i></dt><dd><p>Limit candidate packages to those that were uploaded prior to the given date.</p>
<p>Accepts both RFC 3339 timestamps (e.g., <code>2006-12-02T02:07:43Z</code>) and local dates in the same format (e.g., <code>2006-12-02</code>) in your system&#8217;s configured time zone.</p>
<p>May also be set with the <code>UV_EXCLUDE_NEWER</code> environment variable.</p>
</dd><dt><code>--extra-index-url</code> <i>extra-index-url</i></dt><dd><p>Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--index-url</code> (which defaults to PyPI). When multiple <code>--extra-index-url</code> flags are provided, earlier values take priority.</p>
<p>May also be set with the <code>UV_EXTRA_INDEX_URL</code> environment variable.</p>
</dd><dt><code>--find-links</code>, <code>-f</code> <i>find-links</i></dt><dd><p>Locations to search for candidate distributions, in addition to those found in the registry indexes.</p>
<p>If a path, the target must be a directory that contains packages as wheel files (<code>.whl</code>) or source distributions (<code>.tar.gz</code> or <code>.zip</code>) at the top level.</p>
<p>If a URL, the page must contain a flat list of links to package files adhering to the formats described above.</p>
</dd><dt><code>--help</code>, <code>-h</code></dt><dd><p>Display the concise help for this command</p>
</dd><dt><code>--index-strategy</code> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-match</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attack can upload a malicious package under the same name to a secondary.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>first-index</code>: Only use results from the first index that returns a match for a given package name</li>
<li><code>unsafe-first-match</code>: Search for every package name across all indexes, exhausting the versions from the first index before moving on to the next</li>
<li><code>unsafe-best-match</code>: Search for every package name across all indexes, preferring the &quot;best&quot; version found. If a package version is in multiple indexes, only look at the entry for the first index</li>
</ul>
</dd><dt><code>--index-url</code>, <code>-i</code> <i>index-url</i></dt><dd><p>The URL of the Python package index (by default: &lt;https://pypi.org/simple&gt;).</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>The index given by this flag is given lower priority than all other indexes specified via the <code>--extra-index-url</code> flag.</p>
<p>May also be set with the <code>UV_INDEX_URL</code> environment variable.</p>
</dd><dt><code>--keyring-provider</code> <i>keyring-provider</i></dt><dd><p>Attempt to use <code>keyring</code> for authentication for index URLs.</p>
<p>At present, only <code>--keyring-provider subprocess</code> is supported, which configures uv to use the <code>keyring</code> CLI to handle authentication.</p>
<p>Defaults to <code>disabled</code>.</p>
<p>May also be set with the <code>UV_KEYRING_PROVIDER</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>disabled</code>: Do not use keyring for credential lookup</li>
<li><code>subprocess</code>: Use the <code>keyring</code> command for credential lookup</li>
</ul>
</dd><dt><code>--link-mode</code> <i>link-mode</i></dt><dd><p>The method to use when installing packages from the global cache.</p>
<p>This option is only used when building source distributions.</p>
<p>Defaults to <code>clone</code> (also known as Copy-on-Write) on macOS, and <code>hardlink</code> on Linux and Windows.</p>
<p>May also be set with the <code>UV_LINK_MODE</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>clone</code>: Clone (i.e., copy-on-write) packages from the wheel into the <code>site-packages</code> directory</li>
<li><code>copy</code>: Copy packages from the wheel into the <code>site-packages</code> directory</li>
<li><code>hardlink</code>: Hard link packages from the wheel into the <code>site-packages</code> directory</li>
<li><code>symlink</code>: Symbolically link packages from the wheel into the <code>site-packages</code> directory</li>
</ul>
</dd><dt><code>--native-tls</code></dt><dd><p>Whether to load TLS certificates from the platform&#8217;s native certificate store.</p>
<p>By default, uv loads certificates from the bundled <code>webpki-roots</code> crate. The <code>webpki-roots</code> are a reliable set of trust roots from Mozilla, and including them in uv improves portability and performance (especially on macOS).</p>
<p>However, in some cases, you may want to use the platform&#8217;s native certificate store, especially if you&#8217;re relying on a corporate trust root (e.g., for a mandatory proxy) that&#8217;s included in your system&#8217;s certificate store.</p>
<p>May also be set with the <code>UV_NATIVE_TLS</code> environment variable.</p>
</dd><dt><code>--no-binary</code></dt><dd><p>Don&#8217;t install pre-built wheels.</p>
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
</dd><dt><code>--no-build-isolation</code></dt><dd><p>Disable isolation when building source distributions.</p>
<p>Assumes that build dependencies specified by PEP 518 are already installed.</p>
<p>May also be set with the <code>UV_NO_BUILD_ISOLATION</code> environment variable.</p>
</dd><dt><code>--no-build-isolation-package</code> <i>no-build-isolation-package</i></dt><dd><p>Disable isolation when building source distributions for a specific package.</p>
<p>Assumes that the packages&#8217; build dependencies specified by PEP 518 are already installed.</p>
</dd><dt><code>--no-build-package</code> <i>no-build-package</i></dt><dd><p>Don&#8217;t build source distributions for a specific package</p>
</dd><dt><code>--no-cache</code>, <code>-n</code></dt><dd><p>Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation</p>
<p>May also be set with the <code>UV_NO_CACHE</code> environment variable.</p>
</dd><dt><code>--no-config</code></dt><dd><p>Avoid discovering configuration files (<code>pyproject.toml</code>, <code>uv.toml</code>).</p>
<p>Normally, configuration files are discovered in the current directory, parent directories, or user configuration directories.</p>
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p>
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
<p>For example, spinners or progress bars.</p>
</dd><dt><code>--no-python-downloads</code></dt><dd><p>Disable automatic downloads of Python.</p>
</dd><dt><code>--no-sources</code></dt><dd><p>Ignore the <code>tool.uv.sources</code> table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources</p>
</dd><dt><code>--offline</code></dt><dd><p>Disable network access.</p>
<p>When disabled, uv will only use locally cached data and locally available files.</p>
</dd><dt><code>--out-dir</code>, <code>-o</code> <i>out-dir</i></dt><dd><p>The output directory to which distributions should be written.</p>
<p>Defaults to the <code>dist</code> subdirectory within the source directory.</p>
</dd><dt><code>--prerelease</code> <i>prerelease</i></dt><dd><p>The strategy to use when considering pre-release versions.</p>
<p>By default, uv will accept pre-releases for packages that <em>only</em> publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (<code>if-necessary-or-explicit</code>).</p>
<p>May also be set with the <code>UV_PRERELEASE</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>disallow</code>: Disallow all pre-release versions</li>
<li><code>allow</code>: Allow all pre-release versions</li>
<li><code>if-necessary</code>: Allow pre-release versions if all versions of a package are pre-release</li>
<li><code>explicit</code>: Allow pre-release versions for first-party packages with explicit pre-release markers in their version requirements</li>
<li><code>if-necessary-or-explicit</code>: Allow pre-release versions if all versions of a package are pre-release, or if the package has an explicit pre-release marker in its version requirements</li>
</ul>
</dd><dt><code>--python</code>, <code>-p</code> <i>python</i></dt><dd><p>The Python interpreter to use for the build environment.</p>
<p>By default, builds are executed in isolated virtual environments. The discovered interpreter will be used to create those environments, and will be symlinked or copied in depending on the platform.</p>
<p>See <a href="#uv-python">uv python</a> to view supported request formats.</p>
<p>May also be set with the <code>UV_PYTHON</code> environment variable.</p>
</dd><dt><code>--python-preference</code> <i>python-preference</i></dt><dd><p>Whether to prefer uv-managed or system Python installations.</p>
<p>By default, uv prefers using Python versions it manages. However, it will use system Python installations if a uv-managed Python is not installed. This option allows prioritizing or ignoring system Python installations.</p>
<p>May also be set with the <code>UV_PYTHON_PREFERENCE</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>only-managed</code>: Only use managed Python installations; never use system Python installations</li>
<li><code>managed</code>: Prefer managed Python installations over system Python installations</li>
<li><code>system</code>: Prefer system Python installations over managed Python installations</li>
<li><code>only-system</code>: Only use system Python installations; never use managed Python installations</li>
</ul>
</dd><dt><code>--quiet</code>, <code>-q</code></dt><dd><p>Do not print any output</p>
</dd><dt><code>--refresh</code></dt><dd><p>Refresh all cached data</p>
</dd><dt><code>--refresh-package</code> <i>refresh-package</i></dt><dd><p>Refresh cached data for a specific package</p>
</dd><dt><code>--resolution</code> <i>resolution</i></dt><dd><p>The strategy to use when selecting between the different compatible versions for a given package requirement.</p>
<p>By default, uv will use the latest compatible version of each package (<code>highest</code>).</p>
<p>May also be set with the <code>UV_RESOLUTION</code> environment variable.</p>
<p>Possible values:</p>
<ul>
<li><code>highest</code>: Resolve the highest compatible version of each package</li>
<li><code>lowest</code>: Resolve the lowest compatible version of each package</li>
<li><code>lowest-direct</code>: Resolve the lowest compatible version of any direct dependencies, and the highest compatible version of any transitive dependencies</li>
</ul>
</dd><dt><code>--sdist</code></dt><dd><p>Build a source distribution (&quot;sdist&quot;) from the given directory</p>
</dd><dt><code>--upgrade</code>, <code>-U</code></dt><dd><p>Allow package upgrades, ignoring pinned versions in any existing output file. Implies <code>--refresh</code></p>
</dd><dt><code>--upgrade-package</code>, <code>-P</code> <i>upgrade-package</i></dt><dd><p>Allow upgrades for a specific package, ignoring pinned versions in any existing output file. Implies <code>--refresh-package</code></p>
</dd><dt><code>--verbose</code>, <code>-v</code></dt><dd><p>Use verbose output.</p>
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (&lt;https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives&gt;)</p>
</dd><dt><code>--version</code>, <code>-V</code></dt><dd><p>Display the uv version</p>
</dd><dt><code>--wheel</code></dt><dd><p>Build a binary distribution (&quot;wheel&quot;) from the given directory</p>
</dd></dl>
## uv cache
Manage uv's cache