mirror of
https://github.com/rust-lang/cargo
synced 2024-08-27 19:29:21 +00:00
Auto merge of #13591 - epage:namespace, r=weihanglo
feat: Add 'open-namespaces' feature ### What does this PR try to resolve? This is a step towards #13576 ### How should we test and review this PR? ### Additional information
This commit is contained in:
commit
2fe739fcf1
|
@ -1215,7 +1215,7 @@ str_newtype!(PackageName);
|
||||||
impl<T: AsRef<str>> PackageName<T> {
|
impl<T: AsRef<str>> PackageName<T> {
|
||||||
/// Validated package name
|
/// Validated package name
|
||||||
pub fn new(name: T) -> Result<Self, NameValidationError> {
|
pub fn new(name: T) -> Result<Self, NameValidationError> {
|
||||||
restricted_names::validate_package_name(name.as_ref(), "package name")?;
|
restricted_names::validate_package_name(name.as_ref())?;
|
||||||
Ok(Self(name))
|
Ok(Self(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,7 +1237,7 @@ str_newtype!(RegistryName);
|
||||||
impl<T: AsRef<str>> RegistryName<T> {
|
impl<T: AsRef<str>> RegistryName<T> {
|
||||||
/// Validated registry name
|
/// Validated registry name
|
||||||
pub fn new(name: T) -> Result<Self, NameValidationError> {
|
pub fn new(name: T) -> Result<Self, NameValidationError> {
|
||||||
restricted_names::validate_package_name(name.as_ref(), "registry name")?;
|
restricted_names::validate_registry_name(name.as_ref())?;
|
||||||
Ok(Self(name))
|
Ok(Self(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,13 +33,18 @@ enum ErrorKind {
|
||||||
FeatureNameStartsWithDepColon(String),
|
FeatureNameStartsWithDepColon(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check the base requirements for a package name.
|
pub(crate) fn validate_package_name(name: &str) -> Result<()> {
|
||||||
///
|
for part in name.split("::") {
|
||||||
/// This can be used for other things than package names, to enforce some
|
validate_name(part, "package name")?;
|
||||||
/// level of sanity. Note that package names have other restrictions
|
}
|
||||||
/// elsewhere. `cargo new` has a few restrictions, such as checking for
|
Ok(())
|
||||||
/// reserved names. crates.io has even more restrictions.
|
}
|
||||||
pub(crate) fn validate_package_name(name: &str, what: &'static str) -> Result<()> {
|
|
||||||
|
pub(crate) fn validate_registry_name(name: &str) -> Result<()> {
|
||||||
|
validate_name(name, "registry name")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_name(name: &str, what: &'static str) -> Result<()> {
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
return Err(ErrorKind::Empty(what).into());
|
return Err(ErrorKind::Empty(what).into());
|
||||||
}
|
}
|
||||||
|
@ -84,6 +89,17 @@ pub(crate) fn validate_package_name(name: &str, what: &'static str) -> Result<()
|
||||||
|
|
||||||
/// Ensure a package name is [valid][validate_package_name]
|
/// Ensure a package name is [valid][validate_package_name]
|
||||||
pub(crate) fn sanitize_package_name(name: &str, placeholder: char) -> String {
|
pub(crate) fn sanitize_package_name(name: &str, placeholder: char) -> String {
|
||||||
|
let mut slug = String::new();
|
||||||
|
for part in name.split("::") {
|
||||||
|
if !slug.is_empty() {
|
||||||
|
slug.push_str("::");
|
||||||
|
}
|
||||||
|
slug.push_str(&sanitize_name(part, placeholder));
|
||||||
|
}
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn sanitize_name(name: &str, placeholder: char) -> String {
|
||||||
let mut slug = String::new();
|
let mut slug = String::new();
|
||||||
let mut chars = name.chars();
|
let mut chars = name.chars();
|
||||||
while let Some(ch) = chars.next() {
|
while let Some(ch) = chars.next() {
|
||||||
|
|
|
@ -504,6 +504,9 @@ features! {
|
||||||
|
|
||||||
/// Allow setting trim-paths in a profile to control the sanitisation of file paths in build outputs.
|
/// Allow setting trim-paths in a profile to control the sanitisation of file paths in build outputs.
|
||||||
(unstable, trim_paths, "", "reference/unstable.html#profile-trim-paths-option"),
|
(unstable, trim_paths, "", "reference/unstable.html#profile-trim-paths-option"),
|
||||||
|
|
||||||
|
/// Allow multiple packages to participate in the same API namespace
|
||||||
|
(unstable, open_namespaces, "", "reference/unstable.html#open-namespaces"),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Status and metadata for a single unstable feature.
|
/// Status and metadata for a single unstable feature.
|
||||||
|
|
|
@ -220,6 +220,16 @@ pub fn prepare_for_publish(
|
||||||
package_root: &Path,
|
package_root: &Path,
|
||||||
) -> CargoResult<manifest::TomlManifest> {
|
) -> CargoResult<manifest::TomlManifest> {
|
||||||
let gctx = ws.gctx();
|
let gctx = ws.gctx();
|
||||||
|
|
||||||
|
if me
|
||||||
|
.cargo_features
|
||||||
|
.iter()
|
||||||
|
.flat_map(|f| f.iter())
|
||||||
|
.any(|f| f == "open-namespaces")
|
||||||
|
{
|
||||||
|
anyhow::bail!("cannot publish with `open-namespaces`")
|
||||||
|
}
|
||||||
|
|
||||||
let mut package = me.package().unwrap().clone();
|
let mut package = me.package().unwrap().clone();
|
||||||
package.workspace = None;
|
package.workspace = None;
|
||||||
let current_resolver = package
|
let current_resolver = package
|
||||||
|
@ -580,6 +590,9 @@ pub fn to_real_manifest(
|
||||||
};
|
};
|
||||||
|
|
||||||
let package_name = package.name.trim();
|
let package_name = package.name.trim();
|
||||||
|
if package_name.contains(':') {
|
||||||
|
features.require(Feature::open_namespaces())?;
|
||||||
|
}
|
||||||
|
|
||||||
let resolved_path = package_root.join("Cargo.toml");
|
let resolved_path = package_root.join("Cargo.toml");
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ For the latest nightly, see the [nightly version] of this page.
|
||||||
* [host-config](#host-config) --- Allows setting `[target]`-like configuration settings for host build targets.
|
* [host-config](#host-config) --- Allows setting `[target]`-like configuration settings for host build targets.
|
||||||
* [target-applies-to-host](#target-applies-to-host) --- Alters whether certain flags will be passed to host build targets.
|
* [target-applies-to-host](#target-applies-to-host) --- Alters whether certain flags will be passed to host build targets.
|
||||||
* [gc](#gc) --- Global cache garbage collection.
|
* [gc](#gc) --- Global cache garbage collection.
|
||||||
|
* [open-namespaces](#open-namespaces) --- Allow multiple packages to participate in the same API namespace
|
||||||
* rustdoc
|
* rustdoc
|
||||||
* [rustdoc-map](#rustdoc-map) --- Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/).
|
* [rustdoc-map](#rustdoc-map) --- Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/).
|
||||||
* [scrape-examples](#scrape-examples) --- Shows examples within documentation.
|
* [scrape-examples](#scrape-examples) --- Shows examples within documentation.
|
||||||
|
@ -1518,6 +1519,20 @@ cargo clean gc --max-download-age=1week
|
||||||
cargo clean gc --max-git-size=0 --max-download-size=100MB
|
cargo clean gc --max-git-size=0 --max-download-size=100MB
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## open-namespaces
|
||||||
|
|
||||||
|
* Tracking Issue: [#13576](https://github.com/rust-lang/cargo/issues/13576)
|
||||||
|
|
||||||
|
Allow multiple packages to participate in the same API namespace
|
||||||
|
|
||||||
|
This can be enabled like so:
|
||||||
|
```toml
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
# Stabilized and removed features
|
# Stabilized and removed features
|
||||||
|
|
||||||
## Compile progress
|
## Compile progress
|
||||||
|
|
|
@ -467,18 +467,18 @@ fn cargo_compile_with_empty_package_name() {
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
fn cargo_compile_with_invalid_package_name() {
|
fn cargo_compile_with_invalid_package_name() {
|
||||||
let p = project()
|
let p = project()
|
||||||
.file("Cargo.toml", &basic_manifest("foo::bar", "0.0.0"))
|
.file("Cargo.toml", &basic_manifest("foo@bar", "0.0.0"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("build")
|
p.cargo("build")
|
||||||
.with_status(101)
|
.with_status(101)
|
||||||
.with_stderr(
|
.with_stderr(
|
||||||
"\
|
"\
|
||||||
[ERROR] invalid character `:` in package name: `foo::bar`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
|
[ERROR] invalid character `@` in package name: `foo@bar`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
|
||||||
--> Cargo.toml:3:16
|
--> Cargo.toml:3:16
|
||||||
|
|
|
|
||||||
3 | name = \"foo::bar\"
|
3 | name = \"foo@bar\"
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
|
|
@ -127,6 +127,7 @@ mod net_config;
|
||||||
mod new;
|
mod new;
|
||||||
mod offline;
|
mod offline;
|
||||||
mod old_cargos;
|
mod old_cargos;
|
||||||
|
mod open_namespaces;
|
||||||
mod out_dir;
|
mod out_dir;
|
||||||
mod owner;
|
mod owner;
|
||||||
mod package;
|
mod package;
|
||||||
|
|
358
tests/testsuite/open_namespaces.rs
Normal file
358
tests/testsuite/open_namespaces.rs
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
use cargo_test_support::project;
|
||||||
|
use cargo_test_support::registry::RegistryBuilder;
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn within_namespace_requires_feature() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
[package]
|
||||||
|
name = "foo::bar"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2015"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("read-manifest")
|
||||||
|
.masquerade_as_nightly_cargo(&["open-namespaces"])
|
||||||
|
.with_status(101)
|
||||||
|
.with_stderr(
|
||||||
|
r#"error: failed to parse manifest at `[CWD]/Cargo.toml`
|
||||||
|
|
||||||
|
Caused by:
|
||||||
|
feature `open-namespaces` is required
|
||||||
|
|
||||||
|
The package requires the Cargo feature called `open-namespaces`, but that feature is not stabilized in this version of Cargo ([..]).
|
||||||
|
Consider adding `cargo-features = ["open-namespaces"]` to the top of Cargo.toml (above the [package] table) to tell Cargo you are opting in to use this unstable feature.
|
||||||
|
See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#open-namespaces for more information about the status of this feature.
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn implicit_lib_within_namespace() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo::bar"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2015"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("read-manifest")
|
||||||
|
.masquerade_as_nightly_cargo(&["open-namespaces"])
|
||||||
|
.with_json(
|
||||||
|
r#"{
|
||||||
|
"authors": [],
|
||||||
|
"categories": [],
|
||||||
|
"default_run": null,
|
||||||
|
"dependencies": [],
|
||||||
|
"description": null,
|
||||||
|
"documentation": null,
|
||||||
|
"edition": "2015",
|
||||||
|
"features": {},
|
||||||
|
"homepage": null,
|
||||||
|
"id": "path+file://[..]#foo::bar@0.0.1",
|
||||||
|
"keywords": [],
|
||||||
|
"license": null,
|
||||||
|
"license_file": null,
|
||||||
|
"links": null,
|
||||||
|
"manifest_path": "[CWD]/Cargo.toml",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "foo::bar",
|
||||||
|
"publish": null,
|
||||||
|
"readme": null,
|
||||||
|
"repository": null,
|
||||||
|
"rust_version": null,
|
||||||
|
"source": null,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"crate_types": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"doc": true,
|
||||||
|
"doctest": true,
|
||||||
|
"edition": "2015",
|
||||||
|
"kind": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"name": "foo::bar",
|
||||||
|
"src_path": "[CWD]/src/lib.rs",
|
||||||
|
"test": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "0.0.1"
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.with_stderr("")
|
||||||
|
.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn implicit_bin_within_namespace() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo::bar"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2015"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/main.rs", "fn main() {}")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("read-manifest")
|
||||||
|
.masquerade_as_nightly_cargo(&["open-namespaces"])
|
||||||
|
.with_json(
|
||||||
|
r#"{
|
||||||
|
"authors": [],
|
||||||
|
"categories": [],
|
||||||
|
"default_run": null,
|
||||||
|
"dependencies": [],
|
||||||
|
"description": null,
|
||||||
|
"documentation": null,
|
||||||
|
"edition": "2015",
|
||||||
|
"features": {},
|
||||||
|
"homepage": null,
|
||||||
|
"id": "path+file://[..]#foo::bar@0.0.1",
|
||||||
|
"keywords": [],
|
||||||
|
"license": null,
|
||||||
|
"license_file": null,
|
||||||
|
"links": null,
|
||||||
|
"manifest_path": "[CWD]/Cargo.toml",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "foo::bar",
|
||||||
|
"publish": null,
|
||||||
|
"readme": null,
|
||||||
|
"repository": null,
|
||||||
|
"rust_version": null,
|
||||||
|
"source": null,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"crate_types": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"doc": true,
|
||||||
|
"doctest": false,
|
||||||
|
"edition": "2015",
|
||||||
|
"kind": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"name": "foo::bar",
|
||||||
|
"src_path": "[CWD]/src/main.rs",
|
||||||
|
"test": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "0.0.1"
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.with_stderr("")
|
||||||
|
.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
fn explicit_bin_within_namespace() {
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo::bar"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2015"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "foo-bar"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "")
|
||||||
|
.file("src/bin/foo-bar/main.rs", "fn main() {}")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("read-manifest")
|
||||||
|
.masquerade_as_nightly_cargo(&["open-namespaces"])
|
||||||
|
.with_json(
|
||||||
|
r#"{
|
||||||
|
"authors": [],
|
||||||
|
"categories": [],
|
||||||
|
"default_run": null,
|
||||||
|
"dependencies": [],
|
||||||
|
"description": null,
|
||||||
|
"documentation": null,
|
||||||
|
"edition": "2015",
|
||||||
|
"features": {},
|
||||||
|
"homepage": null,
|
||||||
|
"id": "path+file://[..]#foo::bar@0.0.1",
|
||||||
|
"keywords": [],
|
||||||
|
"license": null,
|
||||||
|
"license_file": null,
|
||||||
|
"links": null,
|
||||||
|
"manifest_path": "[CWD]/Cargo.toml",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "foo::bar",
|
||||||
|
"publish": null,
|
||||||
|
"readme": null,
|
||||||
|
"repository": null,
|
||||||
|
"rust_version": null,
|
||||||
|
"source": null,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"crate_types": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"doc": true,
|
||||||
|
"doctest": true,
|
||||||
|
"edition": "2015",
|
||||||
|
"kind": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"name": "foo::bar",
|
||||||
|
"src_path": "[CWD]/src/lib.rs",
|
||||||
|
"test": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"crate_types": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"doc": true,
|
||||||
|
"doctest": false,
|
||||||
|
"edition": "2015",
|
||||||
|
"kind": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"name": "foo-bar",
|
||||||
|
"src_path": "[CWD]/src/bin/foo-bar/main.rs",
|
||||||
|
"test": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "0.0.1"
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.with_stderr("")
|
||||||
|
.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn namespaced_script_name() {
|
||||||
|
let p = cargo_test_support::project()
|
||||||
|
.file(
|
||||||
|
"foo::bar.rs",
|
||||||
|
r#"---
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
package.edition = "2021"
|
||||||
|
---
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("read-manifest -Zscript --manifest-path foo::bar.rs")
|
||||||
|
.masquerade_as_nightly_cargo(&["script", "open-namespaces"])
|
||||||
|
.with_json(
|
||||||
|
r#"{
|
||||||
|
"authors": [],
|
||||||
|
"categories": [],
|
||||||
|
"default_run": null,
|
||||||
|
"dependencies": [],
|
||||||
|
"description": null,
|
||||||
|
"documentation": null,
|
||||||
|
"edition": "2021",
|
||||||
|
"features": {},
|
||||||
|
"homepage": null,
|
||||||
|
"id": "path+file://[..]#foo::bar@0.0.0",
|
||||||
|
"keywords": [],
|
||||||
|
"license": null,
|
||||||
|
"license_file": null,
|
||||||
|
"links": null,
|
||||||
|
"manifest_path": "[CWD]/foo::bar.rs",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "foo::bar",
|
||||||
|
"publish": [],
|
||||||
|
"readme": null,
|
||||||
|
"repository": null,
|
||||||
|
"rust_version": null,
|
||||||
|
"source": null,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"crate_types": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"doc": true,
|
||||||
|
"doctest": false,
|
||||||
|
"edition": "2021",
|
||||||
|
"kind": [
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"name": "foo::bar",
|
||||||
|
"src_path": "[..]/foo::bar.rs",
|
||||||
|
"test": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "0.0.0"
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.with_stderr("")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cargo_test]
|
||||||
|
#[cfg(unix)] // until we get proper packaging support
|
||||||
|
fn publish_namespaced() {
|
||||||
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
||||||
|
|
||||||
|
let p = project()
|
||||||
|
.file(
|
||||||
|
"Cargo.toml",
|
||||||
|
r#"
|
||||||
|
cargo-features = ["open-namespaces"]
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "foo::bar"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2015"
|
||||||
|
authors = []
|
||||||
|
license = "MIT"
|
||||||
|
description = "foo"
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.file("src/lib.rs", "fn main() {}")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
p.cargo("publish")
|
||||||
|
.masquerade_as_nightly_cargo(&["script", "open-namespaces"])
|
||||||
|
.replace_crates_io(registry.index_url())
|
||||||
|
.with_status(101)
|
||||||
|
.with_stderr(
|
||||||
|
"\
|
||||||
|
[UPDATING] crates.io index
|
||||||
|
[WARNING] manifest has no documentation, homepage or repository.
|
||||||
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
|
||||||
|
Packaging foo::bar v0.0.1 ([CWD])
|
||||||
|
[ERROR] failed to prepare local package for uploading
|
||||||
|
|
||||||
|
Caused by:
|
||||||
|
cannot publish with `open-namespaces`
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
Loading…
Reference in a new issue