mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00
Auto merge of #13626 - linyihai:pre-update, r=weihanglo
Allow precise update to prerelease. ### What does this PR try to resolve? This is a feature that attempts to support updates to pre-release versions via `cargo update --precise`. when `precise-pre-release` used, the prerelase version will be taking consider as compatible version. That said, we can update to any compatible pre-release version. The logic of checking the compatibility of pre-release versions is currently tentative and does not take many conditions into account, this part of the logic makes more sense when implemented in semver. Use `-Zunstable-options` instead of `-Zprecise-pre-release`. ### How should we test and review this PR? ### Additional information Part of https://github.com/rust-lang/cargo/issues/13290
This commit is contained in:
commit
6774b8503c
@ -402,6 +402,14 @@ impl Dependency {
|
|||||||
self.matches_id(sum.package_id())
|
self.matches_id(sum.package_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn matches_prerelease(&self, sum: &Summary) -> bool {
|
||||||
|
let id = sum.package_id();
|
||||||
|
self.inner.name == id.name()
|
||||||
|
&& (self.inner.only_match_name
|
||||||
|
|| (self.inner.req.matches_prerelease(id.version())
|
||||||
|
&& self.inner.source_id == id.source_id()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the package (`id`) can fulfill this dependency request.
|
/// Returns `true` if the package (`id`) can fulfill this dependency request.
|
||||||
pub fn matches_ignoring_source(&self, id: PackageId) -> bool {
|
pub fn matches_ignoring_source(&self, id: PackageId) -> bool {
|
||||||
self.package_name() == id.name() && self.version_req().matches(id.version())
|
self.package_name() == id.name() && self.version_req().matches(id.version())
|
||||||
|
@ -768,7 +768,6 @@ unstable_cli_options!(
|
|||||||
next_lockfile_bump: bool,
|
next_lockfile_bump: bool,
|
||||||
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
|
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
|
||||||
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
|
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
|
||||||
precise_pre_release: bool = ("Enable pre-release versions to be selected with `update --precise`"),
|
|
||||||
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
|
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
|
||||||
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
|
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
|
||||||
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
|
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
|
||||||
@ -1158,7 +1157,6 @@ impl CliUnstable {
|
|||||||
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
|
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
|
||||||
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
|
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
|
||||||
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
|
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
|
||||||
"precise-pre-release" => self.precise_pre_release = parse_empty(k, v)?,
|
|
||||||
"trim-paths" => self.trim_paths = parse_empty(k, v)?,
|
"trim-paths" => self.trim_paths = parse_empty(k, v)?,
|
||||||
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
|
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
|
||||||
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
|
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
|
||||||
|
@ -208,9 +208,9 @@ use crate::sources::source::QueryKind;
|
|||||||
use crate::sources::source::Source;
|
use crate::sources::source::Source;
|
||||||
use crate::sources::PathSource;
|
use crate::sources::PathSource;
|
||||||
use crate::util::cache_lock::CacheLockMode;
|
use crate::util::cache_lock::CacheLockMode;
|
||||||
use crate::util::hex;
|
|
||||||
use crate::util::interning::InternedString;
|
use crate::util::interning::InternedString;
|
||||||
use crate::util::network::PollExt;
|
use crate::util::network::PollExt;
|
||||||
|
use crate::util::{hex, VersionExt};
|
||||||
use crate::util::{restricted_names, CargoResult, Filesystem, GlobalContext, LimitErrorReader};
|
use crate::util::{restricted_names, CargoResult, Filesystem, GlobalContext, LimitErrorReader};
|
||||||
|
|
||||||
/// The `.cargo-ok` file is used to track if the source is already unpacked.
|
/// The `.cargo-ok` file is used to track if the source is already unpacked.
|
||||||
@ -752,7 +752,13 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
|||||||
if let Some((_, requested)) = self
|
if let Some((_, requested)) = self
|
||||||
.source_id
|
.source_id
|
||||||
.precise_registry_version(dep.package_name().as_str())
|
.precise_registry_version(dep.package_name().as_str())
|
||||||
.filter(|(c, _)| req.matches(c))
|
.filter(|(c, to)| {
|
||||||
|
if to.is_prerelease() && self.gctx.cli_unstable().unstable_options {
|
||||||
|
req.matches_prerelease(c)
|
||||||
|
} else {
|
||||||
|
req.matches(c)
|
||||||
|
}
|
||||||
|
})
|
||||||
{
|
{
|
||||||
req.precise_to(&requested);
|
req.precise_to(&requested);
|
||||||
}
|
}
|
||||||
@ -790,7 +796,13 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
|||||||
.index
|
.index
|
||||||
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
|
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
|
||||||
let matched = match kind {
|
let matched = match kind {
|
||||||
QueryKind::Exact => dep.matches(s.as_summary()),
|
QueryKind::Exact => {
|
||||||
|
if req.is_precise() && self.gctx.cli_unstable().unstable_options {
|
||||||
|
dep.matches_prerelease(s.as_summary())
|
||||||
|
} else {
|
||||||
|
dep.matches(s.as_summary())
|
||||||
|
}
|
||||||
|
}
|
||||||
QueryKind::Alternatives => true,
|
QueryKind::Alternatives => true,
|
||||||
QueryKind::Normalized => true,
|
QueryKind::Normalized => true,
|
||||||
};
|
};
|
||||||
|
@ -111,6 +111,19 @@ impl OptVersionReq {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Since Semver does not support prerelease versions,
|
||||||
|
/// the simplest implementation is taken here without comparing the prerelease section.
|
||||||
|
/// The logic here is temporary, we'll have to consider more boundary conditions later,
|
||||||
|
/// and we're not sure if this part of the functionality should be implemented in semver or cargo.
|
||||||
|
pub fn matches_prerelease(&self, version: &Version) -> bool {
|
||||||
|
if version.is_prerelease() {
|
||||||
|
let mut version = version.clone();
|
||||||
|
version.pre = semver::Prerelease::EMPTY;
|
||||||
|
return self.matches(&version);
|
||||||
|
}
|
||||||
|
self.matches(version)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn matches(&self, version: &Version) -> bool {
|
pub fn matches(&self, version: &Version) -> bool {
|
||||||
match self {
|
match self {
|
||||||
OptVersionReq::Any => true,
|
OptVersionReq::Any => true,
|
||||||
|
@ -46,6 +46,8 @@ revision (such as a SHA hash or tag).
|
|||||||
While not recommended, you can specify a yanked version of a package (nightly only).
|
While not recommended, you can specify a yanked version of a package (nightly only).
|
||||||
When possible, try other non-yanked SemVer-compatible versions or seek help
|
When possible, try other non-yanked SemVer-compatible versions or seek help
|
||||||
from the maintainers of the package.
|
from the maintainers of the package.
|
||||||
|
|
||||||
|
A compatible `pre-release` version can also be specified even when the version requirement in `Cargo.toml` doesn't contain any pre-release identifer (nightly only).
|
||||||
{{/option}}
|
{{/option}}
|
||||||
|
|
||||||
{{#option "`-w`" "`--workspace`" }}
|
{{#option "`-w`" "`--workspace`" }}
|
||||||
|
@ -40,6 +40,10 @@ OPTIONS
|
|||||||
SemVer-compatible versions or seek help from the maintainers of the
|
SemVer-compatible versions or seek help from the maintainers of the
|
||||||
package.
|
package.
|
||||||
|
|
||||||
|
A compatible pre-release version can also be specified even when the
|
||||||
|
version requirement in Cargo.toml doesn’t contain any pre-release
|
||||||
|
identifer (nightly only).
|
||||||
|
|
||||||
-w, --workspace
|
-w, --workspace
|
||||||
Attempt to update only packages defined in the workspace. Other
|
Attempt to update only packages defined in the workspace. Other
|
||||||
packages are updated only if they don’t already exist in the
|
packages are updated only if they don’t already exist in the
|
||||||
|
@ -42,7 +42,8 @@ the package to. If the package comes from a git repository, this can be a git
|
|||||||
revision (such as a SHA hash or tag).</p>
|
revision (such as a SHA hash or tag).</p>
|
||||||
<p>While not recommended, you can specify a yanked version of a package (nightly only).
|
<p>While not recommended, you can specify a yanked version of a package (nightly only).
|
||||||
When possible, try other non-yanked SemVer-compatible versions or seek help
|
When possible, try other non-yanked SemVer-compatible versions or seek help
|
||||||
from the maintainers of the package.</dd>
|
from the maintainers of the package.</p>
|
||||||
|
<p>A compatible <code>pre-release</code> version can also be specified even when the version requirement in <code>Cargo.toml</code> doesn’t contain any pre-release identifer (nightly only).</dd>
|
||||||
|
|
||||||
|
|
||||||
<dt class="option-term" id="option-cargo-update--w"><a class="option-anchor" href="#option-cargo-update--w"></a><code>-w</code></dt>
|
<dt class="option-term" id="option-cargo-update--w"><a class="option-anchor" href="#option-cargo-update--w"></a><code>-w</code></dt>
|
||||||
|
@ -347,7 +347,7 @@ Take for example this `Cargo.toml`.
|
|||||||
my-dependency = "0.1.1"
|
my-dependency = "0.1.1"
|
||||||
```
|
```
|
||||||
|
|
||||||
It's possible to update `my-dependancy` to a pre-release with `update -Zprecise-pre-release -p my-dependency --precise 0.1.2-pre.0`.
|
It's possible to update `my-dependancy` to a pre-release with `update -Zunstable-options my-dependency --precise 0.1.2-pre.0`.
|
||||||
This is because `0.1.2-pre.0` is considered compatible with `0.1.1`.
|
This is because `0.1.2-pre.0` is considered compatible with `0.1.1`.
|
||||||
It would not be possible to upgrade to `0.2.0-pre.0` from `0.1.1` in the same way.
|
It would not be possible to upgrade to `0.2.0-pre.0` from `0.1.1` in the same way.
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ revision (such as a SHA hash or tag).
|
|||||||
While not recommended, you can specify a yanked version of a package (nightly only).
|
While not recommended, you can specify a yanked version of a package (nightly only).
|
||||||
When possible, try other non\-yanked SemVer\-compatible versions or seek help
|
When possible, try other non\-yanked SemVer\-compatible versions or seek help
|
||||||
from the maintainers of the package.
|
from the maintainers of the package.
|
||||||
|
.sp
|
||||||
|
A compatible \fBpre\-release\fR version can also be specified even when the version requirement in \fBCargo.toml\fR doesn\[cq]t contain any pre\-release identifer (nightly only).
|
||||||
.RE
|
.RE
|
||||||
.sp
|
.sp
|
||||||
\fB\-w\fR,
|
\fB\-w\fR,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<svg width="1230px" height="740px" xmlns="http://www.w3.org/2000/svg">
|
<svg width="1230px" height="722px" xmlns="http://www.w3.org/2000/svg">
|
||||||
<style>
|
<style>
|
||||||
.fg { fill: #AAAAAA }
|
.fg { fill: #AAAAAA }
|
||||||
.bg { background: #000000 }
|
.bg { background: #000000 }
|
||||||
@ -69,35 +69,33 @@
|
|||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="460px"><tspan> </tspan><tspan class="fg-cyan bold">-Z panic-abort-tests </tspan><tspan> Enable support to run tests with -Cpanic=abort</tspan>
|
<tspan x="10px" y="460px"><tspan> </tspan><tspan class="fg-cyan bold">-Z panic-abort-tests </tspan><tspan> Enable support to run tests with -Cpanic=abort</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="478px"><tspan> </tspan><tspan class="fg-cyan bold">-Z precise-pre-release </tspan><tspan> Enable pre-release versions to be selected with `update --precise`</tspan>
|
<tspan x="10px" y="478px"><tspan> </tspan><tspan class="fg-cyan bold">-Z profile-rustflags </tspan><tspan> Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="496px"><tspan> </tspan><tspan class="fg-cyan bold">-Z profile-rustflags </tspan><tspan> Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
|
<tspan x="10px" y="496px"><tspan> </tspan><tspan class="fg-cyan bold">-Z public-dependency </tspan><tspan> Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="514px"><tspan> </tspan><tspan class="fg-cyan bold">-Z public-dependency </tspan><tspan> Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
|
<tspan x="10px" y="514px"><tspan> </tspan><tspan class="fg-cyan bold">-Z publish-timeout </tspan><tspan> Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="532px"><tspan> </tspan><tspan class="fg-cyan bold">-Z publish-timeout </tspan><tspan> Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
|
<tspan x="10px" y="532px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-map </tspan><tspan> Allow passing external documentation mappings to rustdoc</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="550px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-map </tspan><tspan> Allow passing external documentation mappings to rustdoc</tspan>
|
<tspan x="10px" y="550px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-scrape-examples</tspan><tspan> Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="568px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-scrape-examples</tspan><tspan> Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
|
<tspan x="10px" y="568px"><tspan> </tspan><tspan class="fg-cyan bold">-Z script </tspan><tspan> Enable support for single-file, `.rs` packages</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="586px"><tspan> </tspan><tspan class="fg-cyan bold">-Z script </tspan><tspan> Enable support for single-file, `.rs` packages</tspan>
|
<tspan x="10px" y="586px"><tspan> </tspan><tspan class="fg-cyan bold">-Z target-applies-to-host </tspan><tspan> Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="604px"><tspan> </tspan><tspan class="fg-cyan bold">-Z target-applies-to-host </tspan><tspan> Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
|
<tspan x="10px" y="604px"><tspan> </tspan><tspan class="fg-cyan bold">-Z trim-paths </tspan><tspan> Enable the `trim-paths` option in profiles</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="622px"><tspan> </tspan><tspan class="fg-cyan bold">-Z trim-paths </tspan><tspan> Enable the `trim-paths` option in profiles</tspan>
|
<tspan x="10px" y="622px"><tspan> </tspan><tspan class="fg-cyan bold">-Z unstable-options </tspan><tspan> Allow the usage of unstable options</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="640px"><tspan> </tspan><tspan class="fg-cyan bold">-Z unstable-options </tspan><tspan> Allow the usage of unstable options</tspan>
|
<tspan x="10px" y="640px">
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="658px">
|
<tspan x="10px" y="658px"><tspan>Run with `</tspan><tspan class="fg-cyan bold">cargo -Z</tspan><tspan> </tspan><tspan class="fg-cyan">[FLAG] [COMMAND]</tspan><tspan>`</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="676px"><tspan>Run with `</tspan><tspan class="fg-cyan bold">cargo -Z</tspan><tspan> </tspan><tspan class="fg-cyan">[FLAG] [COMMAND]</tspan><tspan>`</tspan>
|
<tspan x="10px" y="676px">
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="694px">
|
<tspan x="10px" y="694px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
||||||
</tspan>
|
</tspan>
|
||||||
<tspan x="10px" y="712px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
<tspan x="10px" y="712px">
|
||||||
</tspan>
|
|
||||||
<tspan x="10px" y="730px">
|
|
||||||
</tspan>
|
</tspan>
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.3 KiB |
@ -23,7 +23,7 @@ fn requires_nightly_cargo() {
|
|||||||
.file("src/lib.rs", "")
|
.file("src/lib.rs", "")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("update -p my-dependency --precise 0.1.2-pre.0")
|
p.cargo("update my-dependency --precise 0.1.2-pre.0")
|
||||||
.with_status(101)
|
.with_status(101)
|
||||||
// This error is suffering from #12579 but still demonstrates that updating to
|
// This error is suffering from #12579 but still demonstrates that updating to
|
||||||
// a pre-release does not work on stable
|
// a pre-release does not work on stable
|
||||||
@ -41,20 +41,77 @@ perhaps a crate was updated and forgotten to be re-vendored?"#,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn feature_exists() {
|
fn update_pre_release() {
|
||||||
|
cargo_test_support::registry::init();
|
||||||
|
|
||||||
|
for version in ["0.1.1", "0.1.2-pre.0"] {
|
||||||
|
cargo_test_support::registry::Package::new("my-dependency", version).publish();
|
||||||
|
}
|
||||||
|
|
||||||
let p = project()
|
let p = project()
|
||||||
.file(
|
.file(
|
||||||
"Cargo.toml",
|
"Cargo.toml",
|
||||||
r#"
|
r#"
|
||||||
[package]
|
[package]
|
||||||
name = "package"
|
name = "package"
|
||||||
|
[dependencies]
|
||||||
|
my-dependency = "0.1.1"
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.file("src/lib.rs", "")
|
.file("src/lib.rs", "")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("-Zprecise-pre-release update")
|
p.cargo("update my-dependency --precise 0.1.2-pre.0 -Zunstable-options")
|
||||||
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||||
.with_stderr("")
|
.with_stderr(
|
||||||
.run()
|
r#"[UPDATING] `dummy-registry` index
|
||||||
|
[UPDATING] my-dependency v0.1.1 -> v0.1.2-pre.0
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
let lockfile = p.read_lockfile();
|
||||||
|
assert!(lockfile.contains("\nname = \"my-dependency\"\nversion = \"0.1.2-pre.0\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn update_pre_release_differ() {
|
||||||
|
cargo_test_support::registry::init();
|
||||||
|
|
||||||
|
for version in ["0.1.2", "0.1.2-pre.0", "0.1.2-pre.1"] {
|
||||||
|
cargo_test_support::registry::Package::new("my-dependency", version).publish();
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "package"
|
||||||
|
[dependencies]
|
||||||
|
my-dependency = "0.1.2"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("update -p my-dependency --precise 0.1.2-pre.0 -Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||||
|
.with_stderr(
|
||||||
|
r#"[UPDATING] `dummy-registry` index
|
||||||
|
[DOWNGRADING] my-dependency v0.1.2 -> v0.1.2-pre.0
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
p.cargo("update -p my-dependency --precise 0.1.2-pre.1 -Zunstable-options")
|
||||||
|
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||||
|
.with_stderr(
|
||||||
|
r#"[UPDATING] `dummy-registry` index
|
||||||
|
[UPDATING] my-dependency v0.1.2-pre.0 -> v0.1.2-pre.1
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
let lockfile = p.read_lockfile();
|
||||||
|
assert!(lockfile.contains("\nname = \"my-dependency\"\nversion = \"0.1.2-pre.1\""));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user