Skip to content

Commit

Permalink
Add the ability to determine and track the config version.
Browse files Browse the repository at this point in the history
  • Loading branch information
duckinator committed Jan 14, 2025
1 parent 09df520 commit 8ff45a1
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cargo-dist/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use crate::{
METADATA_DIST,
};

mod version;
pub use version::get_version;

pub mod v0;
pub mod v0_to_v1;
pub mod v1;
Expand Down
2 changes: 2 additions & 0 deletions cargo-dist/src/config/v0_to_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ impl DistMetadata {

TomlLayer {
dist_version: cargo_dist_version,
// v0_to_v1 means we're using a v0 config, so just set that.
config_version: 0,
dist_url_override: cargo_dist_url_override,
dist,
allow_dirty,
Expand Down
6 changes: 6 additions & 0 deletions cargo-dist/src/config/v1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ impl ApplyLayer for WorkspaceConfigInheritable {
allow_dirty,
dist_version,
dist_url_override,
config_version: _,
// app-scope only
dist: _,
targets: _,
Expand Down Expand Up @@ -361,6 +362,7 @@ impl ApplyLayer for AppConfigInheritable {
allow_dirty: _,
dist_version: _,
dist_url_override: _,
config_version: _,
}: Self::Layer,
) {
self.artifacts.apply_val_layer(artifacts);
Expand Down Expand Up @@ -388,6 +390,10 @@ pub struct TomlLayer {
#[serde(skip_serializing_if = "Option::is_none")]
pub dist_version: Option<Version>,

/// The configuration file version.
#[serde(default = "crate::config::version::default")]
pub config_version: i64,

/// see [`CargoDistUrlOverride`]
#[serde(skip_serializing_if = "Option::is_none")]
pub dist_url_override: Option<CargoDistUrlOverride>,
Expand Down
68 changes: 68 additions & 0 deletions cargo-dist/src/config/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! For determining which configuration version we're using.
use axoasset::SourceFile;
use camino::Utf8PathBuf;
use serde::Deserialize;

use crate::{DistError, DistResult};

const MAX_VERSION: i64 = 1;

// Extremely minimal struct designed to differentiate between config versions.
// V0 does not have the `config-version` field, so will fail to parse.
// V1+ should have it, so will parse, and contain a `config_version` field.
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
struct FauxDistTable {
#[allow(dead_code)]
config_version: i64,
}

#[derive(Deserialize)]
struct FauxConfig {
#[allow(dead_code)]
dist: FauxDistTable,
}

/// Return the default versioni.
pub fn default() -> i64 {
1
}

/// Return the config version used for the root workspace.
pub fn get_version() -> DistResult<i64> {
let workspaces = super::get_project()?;
let root_workspace = workspaces.root_workspace();

get_version_for_manifest(root_workspace.manifest_path.to_owned())
}


/// Given a path to a dist manifest (e.g. `dist-workspace.toml`), returns
/// the config version being used.
pub fn get_version_for_manifest(dist_manifest_path: Utf8PathBuf) -> DistResult<i64> {
if dist_manifest_path.file_name() != Some("dist-workspace.toml") {
// If the manifest is in Cargo.toml or dist.toml, we're
// definitely using a v0 config.
return Ok(0);
}

let src = SourceFile::load_local(&dist_manifest_path)?;

let Ok(config) = src.deserialize_toml::<FauxConfig>() else {
// If we could load it, but can't parse it, it's likely v0.
return Ok(0);
};

let version = config.dist.config_version;

if version <= MAX_VERSION {
Ok(version)
} else {
Err(DistError::InvalidConfigVersion {
manifest_path: dist_manifest_path.into(),
config_version: version,
max_version: MAX_VERSION,
})
}
}
12 changes: 12 additions & 0 deletions cargo-dist/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,18 @@ pub enum DistError {
/// Version the project uses
your_version: semver::Version,
},

/// Project uses a version that doesn't exist yet.
#[error("{{manifest_path}} has dist.config-version set to invalid value: {{config_version}}")]
#[diagnostic(help("Valid options are 0 through {{max_version}}"))]
InvalidConfigVersion {
/// The path to the manifest file.
manifest_path: String,
/// The version specified in the manifest file.
config_version: i64,
/// The maximum valid version.
max_version: i64,
},
}

impl From<minijinja::Error> for DistError {
Expand Down
2 changes: 2 additions & 0 deletions cargo-dist/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use camino::Utf8PathBuf;
use dist_schema::TripleNameRef;
use semver::Version;
use serde::Deserialize;
use tracing::debug;

use crate::{
config::{
Expand Down Expand Up @@ -203,6 +204,7 @@ fn do_migrate_from_dist_toml() -> DistResult<()> {
pub fn do_migrate() -> DistResult<()> {
do_migrate_from_rust_workspace()?;
do_migrate_from_dist_toml()?;
debug!("dist.config-version = {}", config::get_version()?);
//do_migrate_from_v0()?;
Ok(())
}
Expand Down

0 comments on commit 8ff45a1

Please sign in to comment.