diff --git a/cargo-dist/src/config/mod.rs b/cargo-dist/src/config/mod.rs index 4d27e03db..44bba2b21 100644 --- a/cargo-dist/src/config/mod.rs +++ b/cargo-dist/src/config/mod.rs @@ -12,6 +12,7 @@ use cargo_dist_schema::{ use serde::{Deserialize, Serialize}; use crate::announce::TagSettings; +use crate::config::v1::DistWorkspaceConfig; use crate::SortedMap; use crate::{ errors::{DistError, DistResult}, @@ -929,6 +930,21 @@ impl std::fmt::Display for ProductionMode { } } +pub(crate) fn load_config(dist_manifest_path: &Utf8Path) -> DistResult { + let src = SourceFile::load_local(dist_manifest_path)?; + parse_config(src) +} + +pub(crate) fn parse_config(src: SourceFile) -> DistResult { + let config: DistWorkspaceConfig = src.deserialize_toml()?; + Ok(config) +} + +pub(crate) fn load_generic_v0_config(dist_manifest_path: &Utf8Path) -> DistResult { + let src = SourceFile::load_local(dist_manifest_path)?; + parse_generic_config(src) +} + pub(crate) fn parse_metadata_table_or_manifest( manifest_path: &Utf8Path, dist_manifest_path: Option<&Utf8Path>, @@ -937,8 +953,7 @@ pub(crate) fn parse_metadata_table_or_manifest( if let Some(dist_manifest_path) = dist_manifest_path { reject_metadata_table(manifest_path, dist_manifest_path, metadata_table)?; // Generic dist.toml - let src = SourceFile::load_local(dist_manifest_path)?; - parse_generic_config(src) + load_generic_v0_config(dist_manifest_path) } else { // Pre-parsed Rust metadata table parse_metadata_table(manifest_path, metadata_table) diff --git a/cargo-dist/src/config/v1/mod.rs b/cargo-dist/src/config/v1/mod.rs index bd10f1121..d73594abb 100644 --- a/cargo-dist/src/config/v1/mod.rs +++ b/cargo-dist/src/config/v1/mod.rs @@ -373,6 +373,78 @@ impl ApplyLayer for AppConfigInheritable { } } +/// The internal representation of the [package] table from dist[-workspace].toml. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct PackageTable { + /// The name of the package. + pub name: String, + /// The version of the package. Syntax must be a valid Cargo SemVer Version. + pub version: String, + /// A brief description of the package. + pub description: Option, + /// The authors of the package. + pub authors: Option>, + /// A URL to the repository hosting this package. + pub repository: Option, + /// A URL to the homepage of the package. + pub homepage: Option, + /// A URL to the documentation of the package. + pub documentation: Option, + /// A relative path to the changelog file for your package. + pub changelog: Option, + /// A relative path to the readme file for your package. + pub readme: Option, + /// The license(s) of your package, in SPDX format. + pub license: Option, + /// Relative paths to the license files for your package. + pub license_files: Option>, + /// Names of binaries (without the extension) your package is expected + /// to build and distribute. + pub binaries: Option>, + /// Names of c-style static libraries (without the extension) your + /// package is expected to build and distribute. + pub cstaticlibs: Option>, + /// Names of c-style dynamic libraries (without the extension) your + /// package is expected to build and distribute. + pub cdylibs: Option>, + /// A command to run in your package's root directory to build its + /// binaries, cstaticlibs, and cdylibs. + pub build_command: Option>, +} + +/// The internal representation of dist.toml. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct DistConfig { + /// The `[package]` table from dist.toml. + pub package: Option, + /// The `[dist]` table from dist.toml. + pub dist: TomlLayer, +} + +/// The internal representation of the [workspace] table from dist-workspace.toml. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct WorkspaceTable { + /// The various projects/workspaces/packages to be managed by dist. + pub members: Vec, +} + +/// The internal representation of dist-workspace.toml. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct DistWorkspaceConfig { + /// The `[workspace]` table. + #[serde(skip_serializing_if = "Option::is_none")] + pub workspace: Option, + /// The `[dist]` table + pub dist: TomlLayer, + /// The `[package]` table. + #[serde(skip_serializing_if = "Option::is_none")] + pub package: Option, +} + /// The "raw" input from a toml file containing config #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] diff --git a/cargo-dist/src/errors.rs b/cargo-dist/src/errors.rs index 2d8349030..0cb79a1be 100644 --- a/cargo-dist/src/errors.rs +++ b/cargo-dist/src/errors.rs @@ -74,6 +74,10 @@ pub enum DistError { #[error(transparent)] TripleError(#[from] cargo_dist_schema::target_lexicon::ParseError), + /// error when using axoasset::toml::to_string() or similar + #[error(transparent)] + AxoassetTomlSerErr(#[from] axoasset::toml::ser::Error), + /// A problem with a jinja template, which is always a dist bug #[error("Failed to render template")] #[diagnostic( diff --git a/cargo-dist/src/init.rs b/cargo-dist/src/init.rs index 8c754e78c..130b45f03 100644 --- a/cargo-dist/src/init.rs +++ b/cargo-dist/src/init.rs @@ -1,4 +1,4 @@ -use axoasset::{toml_edit, LocalAsset}; +use axoasset::{toml, toml_edit, LocalAsset}; use axoproject::{WorkspaceGraph, WorkspaceInfo, WorkspaceKind}; use camino::Utf8PathBuf; use cargo_dist_schema::TripleNameRef; @@ -199,11 +199,46 @@ fn do_migrate_from_dist_toml() -> DistResult<()> { Ok(()) } +fn do_migrate_from_v0() -> DistResult<()> { + let workspaces = config::get_project()?; + let root_workspace = workspaces.root_workspace(); + let manifest_path = &root_workspace.manifest_path; + + if config::load_config(manifest_path).is_ok() { + // We're already on a V1 config, no need to migrate! + return Ok(()); + } + + // Load in the root workspace toml to edit and write back + let Ok(dist_metadata) = config::load_generic_v0_config(manifest_path) else { + // We don't have a valid v0 _or_ v1 config. No migration can be done. + // It feels weird to return Ok(()) here, but I think it's right? + return Ok(()); + }; + + let dist = dist_metadata.to_toml_layer(true); + let workspace = Some(config::v1::WorkspaceTable { members: vec![] }); + let package = None; + + let config = config::v1::DistWorkspaceConfig { + dist, + workspace, + package, + }; + + let workspace_toml_text = toml::to_string(&config)?; + + // Write new config file. + axoasset::LocalAsset::write_new(&workspace_toml_text, manifest_path)?; + + Ok(()) +} + /// Run `dist migrate` pub fn do_migrate() -> DistResult<()> { do_migrate_from_rust_workspace()?; do_migrate_from_dist_toml()?; - //do_migrate_from_v0()?; + do_migrate_from_v0()?; Ok(()) }