diff --git a/cargo-dist/src/config.rs b/cargo-dist/src/config.rs index cfe52b5f5..d3fa2b364 100644 --- a/cargo-dist/src/config.rs +++ b/cargo-dist/src/config.rs @@ -243,11 +243,6 @@ pub struct DistMetadata { #[serde(rename = "publish-jobs")] pub publish_jobs: Option>, - /// User-supplied extra publish jobs to run in CI - #[serde(skip_serializing_if = "Option::is_none")] - #[serde(rename = "user-publish-jobs")] - pub user_publish_jobs: Option>, - /// Whether to publish prereleases to package managers /// /// (defaults to false) @@ -294,7 +289,6 @@ impl DistMetadata { default_features: _, all_features: _, publish_jobs: _, - user_publish_jobs: _, publish_prereleases: _, create_release: _, pr_run_mode: _, @@ -336,7 +330,6 @@ impl DistMetadata { default_features, all_features, publish_jobs, - user_publish_jobs, publish_prereleases, create_release, pr_run_mode: _, @@ -417,9 +410,6 @@ impl DistMetadata { if publish_jobs.is_none() { *publish_jobs = workspace_config.publish_jobs.clone(); } - if user_publish_jobs.is_none() { - *user_publish_jobs = workspace_config.user_publish_jobs.clone(); - } // This was historically implemented as extend, but I'm not convinced the // inconsistency is worth the inconvenience... @@ -520,19 +510,48 @@ impl std::fmt::Display for InstallerStyle { } /// The publish jobs we should run -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Clone, Debug, Serialize, PartialEq, Eq)] pub enum PublishStyle { /// Publish a Homebrew formula to a tap repository #[serde(rename = "homebrew")] Homebrew, + /// User-supplied value + User(String), +} + +impl std::str::FromStr for PublishStyle { + type Err = DistError; + fn from_str(s: &str) -> DistResult { + if s.starts_with('@') { + Ok(Self::User(s.strip_prefix('@').unwrap().to_owned())) + } else if s == "homebrew" { + Ok(Self::Homebrew) + } else { + Err(DistError::UnrecognizedStyle { + style: s.to_owned(), + }) + } + } +} + +impl<'de> serde::Deserialize<'de> for PublishStyle { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + let path = String::deserialize(deserializer)?; + path.parse().map_err(|e| D::Error::custom(format!("{e}"))) + } } impl std::fmt::Display for PublishStyle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let string = match self { - PublishStyle::Homebrew => "homebrew", - }; - string.fmt(f) + match self { + PublishStyle::Homebrew => write!(f, "homebrew"), + PublishStyle::User(s) => write!(f, "@{s}"), + } } } diff --git a/cargo-dist/src/errors.rs b/cargo-dist/src/errors.rs index 394f740ba..058e8c57d 100644 --- a/cargo-dist/src/errors.rs +++ b/cargo-dist/src/errors.rs @@ -229,6 +229,13 @@ pub enum DistError { /// The missing keys keys: &'static [&'static str], }, + /// unrecognized style + #[error("{style} is not a recognized value")] + #[diagnostic(help("Styles that do not come with cargo-dist should be prefixed with an @"))] + UnrecognizedStyle { + /// Name of the msi + style: String, + }, } impl From for DistError { diff --git a/cargo-dist/src/init.rs b/cargo-dist/src/init.rs index d0b7e9f91..d8b41ed28 100644 --- a/cargo-dist/src/init.rs +++ b/cargo-dist/src/init.rs @@ -221,7 +221,6 @@ fn get_new_dist_metadata( default_features: None, all_features: None, publish_jobs: None, - user_publish_jobs: None, publish_prereleases: None, create_release: None, pr_run_mode: None, @@ -681,7 +680,6 @@ fn apply_dist_to_metadata(metadata: &mut toml_edit::Item, meta: &DistMetadata) { all_features, default_features, publish_jobs, - user_publish_jobs, publish_prereleases, create_release, pr_run_mode, @@ -842,13 +840,6 @@ fn apply_dist_to_metadata(metadata: &mut toml_edit::Item, meta: &DistMetadata) { publish_jobs.as_ref(), ); - apply_string_list( - table, - "user-publish-jobs", - "# User-defined publish jobs to run in CI\n", - user_publish_jobs.as_ref(), - ); - apply_optional_value( table, "publish-prereleases", diff --git a/cargo-dist/src/tasks.rs b/cargo-dist/src/tasks.rs index 3addb46be..f19d70abe 100644 --- a/cargo-dist/src/tasks.rs +++ b/cargo-dist/src/tasks.rs @@ -650,8 +650,6 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { install_path: _, // Only the final value merged into a package_config matters publish_jobs: _, - // Only the final value merged into a package_config matters - user_publish_jobs: _, publish_prereleases, features, default_features: no_default_features, @@ -705,11 +703,27 @@ impl<'pkg_graph> DistGraphBuilder<'pkg_graph> { }; let templates = Templates::new()?; - let publish_jobs = workspace_metadata.publish_jobs.clone().unwrap_or(vec![]); - let user_publish_jobs = workspace_metadata - .user_publish_jobs + let publish_jobs: Vec; + let user_publish_jobs: Vec; + (publish_jobs, user_publish_jobs) = workspace_metadata + .publish_jobs .clone() - .unwrap_or(vec![]); + .unwrap_or(vec![]) + .into_iter() + .partition(|s| !matches!(s, PublishStyle::User(_))); + let user_publish_jobs = user_publish_jobs + .into_iter() + // Remove the @ suffix for later; we only have user jobs at this + // point so we no longer need to distinguish + .map(|s| { + let string = s.to_string(); + if let Some(stripped) = string.strip_prefix('@') { + stripped.to_owned() + } else { + string + } + }) + .collect(); let publish_prereleases = publish_prereleases.unwrap_or(false); let allow_dirty = if allow_all_dirty {