From 157b269209d02ea51e166eb74da0bfdf0dcaed15 Mon Sep 17 00:00:00 2001 From: Peter Tripp Date: Tue, 1 Sep 2026 12:38:41 -0400 Subject: [PATCH] Add pending_migration_versions to validate v-api migrations --- v-model/src/migrations.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/v-model/src/migrations.rs b/v-model/src/migrations.rs index 491590a..e85d30d 100644 --- a/v-model/src/migrations.rs +++ b/v-model/src/migrations.rs @@ -2,10 +2,10 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -use std::collections::HashSet; +use std::{collections::HashSet, error::Error}; use diesel::{ - PgConnection, + Connection, PgConnection, migration::MigrationSource, pg::Pg, r2d2::{ConnectionManager, ManageConnection}, @@ -51,6 +51,32 @@ pub fn assert_unique_migration_versions() { } } +/// Returns the versions of enabled embedded migrations that have not been +/// applied to the database, without modifying it. +pub fn pending_migration_versions(url: &str) -> Result, Box> { + assert_unique_migration_versions(); + + let mut conn = PgConnection::establish(url)?; + let applied = conn + .applied_migrations()? + .into_iter() + .map(|version| version.to_string()) + .collect(); + let mut embedded = HashSet::new(); + for migration_set in all_migrations() { + let migrations = >::migrations(&migration_set)?; + embedded.extend( + migrations + .iter() + .map(|migration| migration.name().version().to_string()), + ); + } + let mut pending: Vec = embedded.difference(&applied).cloned().collect(); + pending.sort(); + + Ok(pending) +} + /// Runs all pending migrations for each enabled feature against the database /// at the provided connection string. Migration sets are applied in dependency /// order (core first, then feature-specific), naming each migration on stdout