Skip to content

Commit

Permalink
Better missing self update feature (#8337)
Browse files Browse the repository at this point in the history
  • Loading branch information
konstin authored Oct 18, 2024
1 parent d53d580 commit e26eed1
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 18 deletions.
4 changes: 0 additions & 4 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,6 @@ pub enum Commands {
Cache(CacheNamespace),
/// Manage the uv executable.
#[command(name = "self")]
#[cfg(feature = "self-update")]
Self_(SelfNamespace),
/// Clear the cache, removing all entries or those linked to specific packages.
#[command(hide = true)]
Expand Down Expand Up @@ -449,21 +448,18 @@ pub struct HelpArgs {
}

#[derive(Args)]
#[cfg(feature = "self-update")]
pub struct SelfNamespace {
#[command(subcommand)]
pub command: SelfCommand,
}

#[derive(Subcommand)]
#[cfg(feature = "self-update")]
pub enum SelfCommand {
/// Update uv.
Update(SelfUpdateArgs),
}

#[derive(Args, Debug)]
#[cfg(feature = "self-update")]
pub struct SelfUpdateArgs {
/// Update to the specified version. If not provided, uv will update to the latest version.
pub target_version: Option<String>,
Expand Down
7 changes: 7 additions & 0 deletions crates/uv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,13 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
token,
}),
}) => commands::self_update(target_version, token, printer).await,
#[cfg(not(feature = "self-update"))]
Commands::Self_(_) => {
anyhow::bail!(
"uv was installed through an external package manager, and self-update \
is not available. Please use your package manager to update uv."
);
}
Commands::Version { output_format } => {
commands::version(output_format, &mut stdout())?;
Ok(ExitStatus::Success)
Expand Down
35 changes: 21 additions & 14 deletions crates/uv/tests/it/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn help() {
let context = TestContext::new_with_versions(&[]);

// The `uv help` command should show the long help message
uv_snapshot!(context.filters(), context.help(), @r#"
uv_snapshot!(context.filters(), context.help(), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -29,6 +29,7 @@ fn help() {
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uvcutable
version Display uv's version
generate-shell-completion Generate shell completion
help Display documentation for a command
Expand Down Expand Up @@ -67,14 +68,14 @@ fn help() {
----- stderr -----
"#);
"###);
}

#[test]
fn help_flag() {
let context = TestContext::new_with_versions(&[]);

uv_snapshot!(context.filters(), context.command().arg("--help"), @r#"
uv_snapshot!(context.filters(), context.command().arg("--help"), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -98,6 +99,7 @@ fn help_flag() {
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uvcutable
version Display uv's version
help Display documentation for a command
Expand Down Expand Up @@ -134,14 +136,14 @@ fn help_flag() {
Use `uv help` for more details.
----- stderr -----
"#);
"###);
}

#[test]
fn help_short_flag() {
let context = TestContext::new_with_versions(&[]);

uv_snapshot!(context.filters(), context.command().arg("-h"), @r#"
uv_snapshot!(context.filters(), context.command().arg("-h"), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -165,6 +167,7 @@ fn help_short_flag() {
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uvcutable
version Display uv's version
help Display documentation for a command
Expand Down Expand Up @@ -201,7 +204,7 @@ fn help_short_flag() {
Use `uv help` for more details.
----- stderr -----
"#);
"###);
}

#[test]
Expand Down Expand Up @@ -672,7 +675,7 @@ fn help_flag_subsubcommand() {
fn help_unknown_subcommand() {
let context = TestContext::new_with_versions(&[]);

uv_snapshot!(context.filters(), context.help().arg("foobar"), @r#"
uv_snapshot!(context.filters(), context.help().arg("foobar"), @r###"
success: false
exit_code: 2
----- stdout -----
Expand All @@ -694,11 +697,12 @@ fn help_unknown_subcommand() {
build
publish
cache
self
version
generate-shell-completion
"#);
"###);

uv_snapshot!(context.filters(), context.help().arg("foo").arg("bar"), @r#"
uv_snapshot!(context.filters(), context.help().arg("foo").arg("bar"), @r###"
success: false
exit_code: 2
----- stdout -----
Expand All @@ -720,9 +724,10 @@ fn help_unknown_subcommand() {
build
publish
cache
self
version
generate-shell-completion
"#);
"###);
}

#[test]
Expand All @@ -749,7 +754,7 @@ fn help_unknown_subsubcommand() {
fn help_with_global_option() {
let context = TestContext::new_with_versions(&[]);

uv_snapshot!(context.filters(), context.help().arg("--no-cache"), @r#"
uv_snapshot!(context.filters(), context.help().arg("--no-cache"), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -773,6 +778,7 @@ fn help_with_global_option() {
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uvcutable
version Display uv's version
generate-shell-completion Generate shell completion
help Display documentation for a command
Expand Down Expand Up @@ -811,7 +817,7 @@ fn help_with_global_option() {
----- stderr -----
"#);
"###);
}

#[test]
Expand Down Expand Up @@ -853,7 +859,7 @@ fn help_with_no_pager() {

// We can't really test whether the --no-pager option works with a snapshot test.
// It's still nice to have a test for the option to confirm the option exists.
uv_snapshot!(context.filters(), context.help().arg("--no-pager"), @r#"
uv_snapshot!(context.filters(), context.help().arg("--no-pager"), @r###"
success: true
exit_code: 0
----- stdout -----
Expand All @@ -877,6 +883,7 @@ fn help_with_no_pager() {
build Build Python packages into source distributions and wheels
publish Upload distributions to an index
cache Manage uv's cache
self Manage the uvcutable
version Display uv's version
generate-shell-completion Generate shell completion
help Display documentation for a command
Expand Down Expand Up @@ -915,5 +922,5 @@ fn help_with_no_pager() {
----- stderr -----
"#);
"###);
}
130 changes: 130 additions & 0 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ uv [OPTIONS] <COMMAND>
</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-self"><code>uv self</code></a></dt><dd><p>Manage the uv executable</p>
</dd>
<dt><a href="#uv-version"><code>uv version</code></a></dt><dd><p>Display uv&#8217;s version</p>
</dd>
<dt><a href="#uv-help"><code>uv help</code></a></dt><dd><p>Display documentation for a command</p>
Expand Down Expand Up @@ -7868,6 +7870,134 @@ uv cache dir [OPTIONS]

</dd></dl>

## uv self

Manage the uv executable

<h3 class="cli-reference">Usage</h3>

```
uv self [OPTIONS] <COMMAND>
```

<h3 class="cli-reference">Commands</h3>

<dl class="cli-reference"><dt><a href="#uv-self-update"><code>uv self update</code></a></dt><dd><p>Update uv</p>
</dd>
</dl>

### uv self update

Update uv

<h3 class="cli-reference">Usage</h3>

```
uv self update [OPTIONS] [TARGET_VERSION]
```

<h3 class="cli-reference">Arguments</h3>

<dl class="cli-reference"><dt><code>TARGET_VERSION</code></dt><dd><p>Update to the specified version. If not provided, uv will update to the latest version</p>

</dd></dl>

<h3 class="cli-reference">Options</h3>

<dl class="cli-reference"><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>--directory</code> <i>directory</i></dt><dd><p>Change to the given directory prior to running the command.</p>

<p>Relative paths are resolved with the given directory as the base.</p>

<p>See <code>--project</code> to only change the project root directory.</p>

</dd><dt><code>--help</code>, <code>-h</code></dt><dd><p>Display the concise help for this command</p>

</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-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-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>--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>--project</code> <i>project</i></dt><dd><p>Run the command within the given project directory.</p>

<p>All <code>pyproject.toml</code>, <code>uv.toml</code>, and <code>.python-version</code> files will be discovered by walking up the directory tree from the project root, as will the project&#8217;s virtual environment (<code>.venv</code>).</p>

<p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p>

<p>See <code>--directory</code> to change the working directory entirely.</p>

<p>This setting has no effect when used in the <code>uv pip</code> interface.</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>--token</code> <i>token</i></dt><dd><p>A GitHub token for authentication. A token is not required but can be used to reduce the chance of encountering rate limits</p>

<p>May also be set with the <code>UV_GITHUB_TOKEN</code> environment variable.</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></dl>

## uv version

Display uv's version
Expand Down

0 comments on commit e26eed1

Please sign in to comment.