allow_dirty: options.flag_allow_dirty,
target: options.flag_target.as_ref().map(|t| &t[..]),
jobs: options.flag_jobs,
+ registry: None,
})?;
Ok(())
}
}
}
- pub fn to_registry_toml(&self) -> String {
+ pub fn to_registry_toml(&self) -> CargoResult<String> {
let manifest = self.manifest().original().prepare_for_publish();
- let toml = toml::to_string(&manifest).unwrap();
- format!("\
+ let toml = toml::to_string(&manifest)?;
+ Ok(format!("\
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO\n\
#\n\
# When uploading crates to the registry Cargo will automatically\n\
# will likely look very different (and much more reasonable)\n\
\n\
{}\
- ", toml)
+ ", toml))
}
}
pub verify: bool,
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
+ pub registry: Option<String>,
}
pub fn package(ws: &Workspace,
opts: &PackageOpts) -> CargoResult<Option<FileLock>> {
let pkg = ws.current()?;
let config = ws.config();
- if !pkg.manifest().features().activated().is_empty() {
+
+ // Allow packaging if a registry has been provided, or if there are no nightly
+ // features enabled.
+ if opts.registry.is_none() && !pkg.manifest().features().activated().is_empty() {
bail!("cannot package or publish crates which activate nightly-only \
cargo features")
}
})?;
let mut header = Header::new_ustar();
- let toml = pkg.to_registry_toml();
+ let toml = pkg.to_registry_toml()?;
header.set_path(&path)?;
header.set_entry_type(EntryType::file());
header.set_mode(0o644);
allow_dirty: opts.allow_dirty,
target: opts.target,
jobs: opts.jobs,
+ registry: opts.registry.clone(),
})?.unwrap();
// Upload said tarball to the specified destination
#[derive(Debug, Deserialize, Serialize)]
pub struct TomlManifest {
+ #[serde(rename = "cargo-features")]
+ cargo_features: Option<Vec<String>>,
package: Option<Box<TomlProject>>,
project: Option<Box<TomlProject>>,
profile: Option<TomlProfiles>,
patch: Option<BTreeMap<String, BTreeMap<String, TomlDependency>>>,
workspace: Option<TomlWorkspace>,
badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
- #[serde(rename = "cargo-features")]
- cargo_features: Option<Vec<String>>,
}
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
};
let profiles = build_profiles(&me.profile);
let publish = match project.publish {
- Some(VecStringOrBool::VecString(ref vecstring)) => Some(vecstring.clone()),
+ Some(VecStringOrBool::VecString(ref vecstring)) => {
+ features.require(Feature::alternative_registries()).chain_err(|| {
+ "the `publish` manifest key is unstable for anything other than a value of true or false"
+ })?;
+ Some(vecstring.clone())
+ },
Some(VecStringOrBool::Bool(false)) => Some(vec![]),
_ => None,
};
assert!(!publish::upload_path().join("api/v1/crates/new").exists());
}
+#[test]
+fn block_publish_feature_not_enabled() {
+ publish::setup();
+
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ license = "MIT"
+ description = "foo"
+ publish = [
+ "test"
+ ]
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .build();
+
+ assert_that(p.cargo("publish").masquerade_as_nightly_cargo()
+ .arg("--registry").arg("alternative").arg("-Zunstable-options"),
+ execs().with_status(101).with_stderr("\
+error: failed to parse manifest at `[..]`
+
+Caused by:
+ the `publish` manifest key is unstable for anything other than a value of true or false
+
+Caused by:
+ feature `alternative-registries` is required
+
+consider adding `cargo-features = [\"alternative-registries\"]` to the manifest
+"));
+}
+
#[test]
fn registry_not_in_publish_list() {
publish::setup();
let p = project("foo")
.file("Cargo.toml", r#"
+ cargo-features = ["alternative-registries"]
+
[project]
name = "foo"
version = "0.0.1"
let p = project("foo")
.file("Cargo.toml", r#"
+ cargo-features = ["alternative-registries"]
+
[project]
name = "foo"
version = "0.0.1"
let _ = repo(&paths::root().join("foo"))
.file("Cargo.toml", r#"
+ cargo-features = ["alternative-registries"]
+
[project]
name = "foo"
version = "0.0.1"
let p = project("foo")
.file("Cargo.toml", r#"
+ cargo-features = ["alternative-registries"]
+
[project]
name = "foo"
version = "0.0.1"