Skip to content

Commit

Permalink
Auto merge of #13591 - epage:namespace, r=weihanglo
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Mar 15, 2024
2 parents 36108cb + 9ea3f26 commit 2fe739f
Show file tree
Hide file tree
Showing 8 changed files with 419 additions and 13 deletions.
4 changes: 2 additions & 2 deletions crates/cargo-util-schemas/src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ str_newtype!(PackageName);
impl<T: AsRef<str>> PackageName<T> {
/// Validated package name
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))
}
}
Expand All @@ -1237,7 +1237,7 @@ str_newtype!(RegistryName);
impl<T: AsRef<str>> RegistryName<T> {
/// Validated registry name
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))
}
}
Expand Down
30 changes: 23 additions & 7 deletions crates/cargo-util-schemas/src/restricted_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ enum ErrorKind {
FeatureNameStartsWithDepColon(String),
}

/// Check the base requirements for a package name.
///
/// This can be used for other things than package names, to enforce some
/// level of sanity. Note that package names have other restrictions
/// elsewhere. `cargo new` has a few restrictions, such as checking for
/// reserved names. crates.io has even more restrictions.
pub(crate) fn validate_package_name(name: &str, what: &'static str) -> Result<()> {
pub(crate) fn validate_package_name(name: &str) -> Result<()> {
for part in name.split("::") {
validate_name(part, "package name")?;
}
Ok(())
}

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() {
return Err(ErrorKind::Empty(what).into());
}
Expand Down Expand Up @@ -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]
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 chars = name.chars();
while let Some(ch) = chars.next() {
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ features! {

/// 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"),

/// 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.
Expand Down
13 changes: 13 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,16 @@ pub fn prepare_for_publish(
package_root: &Path,
) -> CargoResult<manifest::TomlManifest> {
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();
package.workspace = None;
let current_resolver = package
Expand Down Expand Up @@ -580,6 +590,9 @@ pub fn to_real_manifest(
};

let package_name = package.name.trim();
if package_name.contains(':') {
features.require(Feature::open_namespaces())?;
}

let resolved_path = package_root.join("Cargo.toml");

Expand Down
15 changes: 15 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* [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.
* [open-namespaces](#open-namespaces) --- Allow multiple packages to participate in the same API namespace
* rustdoc
* [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.
Expand Down Expand Up @@ -1518,6 +1519,20 @@ cargo clean gc --max-download-age=1week
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

## Compile progress
Expand Down
8 changes: 4 additions & 4 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,18 +467,18 @@ fn cargo_compile_with_empty_package_name() {
#[cargo_test]
fn cargo_compile_with_invalid_package_name() {
let p = project()
.file("Cargo.toml", &basic_manifest("foo::bar", "0.0.0"))
.file("Cargo.toml", &basic_manifest("foo@bar", "0.0.0"))
.build();

p.cargo("build")
.with_status(101)
.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
|
3 | name = \"foo::bar\"
| ^^^^^^^^^^
3 | name = \"foo@bar\"
| ^^^^^^^^^
|
",
)
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ mod net_config;
mod new;
mod offline;
mod old_cargos;
mod open_namespaces;
mod out_dir;
mod owner;
mod package;
Expand Down
Loading

0 comments on commit 2fe739f

Please sign in to comment.