MeiliSearch/meilisearch-types/src/versioning.rs

79 lines
3.0 KiB
Rust
Raw Normal View History

2022-10-25 15:06:28 +02:00
use std::fs;
use std::io::{self, ErrorKind};
use std::path::Path;
/// The name of the file that contains the version of the database.
pub const VERSION_FILE_NAME: &str = "VERSION";
static VERSION_MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
static VERSION_MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");
static VERSION_PATCH: &str = env!("CARGO_PKG_VERSION_PATCH");
/// Persists the version of the current Meilisearch binary to a VERSION file
2024-09-05 10:08:06 +02:00
pub fn create_current_version_file(db_path: &Path) -> io::Result<()> {
create_version_file(db_path, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH)
}
pub fn create_version_file(
db_path: &Path,
major: &str,
minor: &str,
patch: &str,
) -> io::Result<()> {
2022-10-25 15:06:28 +02:00
let version_path = db_path.join(VERSION_FILE_NAME);
2024-09-05 10:08:06 +02:00
fs::write(version_path, format!("{}.{}.{}", major, minor, patch))
2022-10-25 15:06:28 +02:00
}
/// Ensures Meilisearch version is compatible with the database, returns an error versions mismatch.
pub fn check_version_file(db_path: &Path) -> anyhow::Result<()> {
2024-09-05 10:08:06 +02:00
let (major, minor, patch) = get_version(db_path)?;
if major != VERSION_MAJOR || minor != VERSION_MINOR {
return Err(VersionFileError::VersionMismatch { major, minor, patch }.into());
}
Ok(())
}
pub fn get_version(db_path: &Path) -> Result<(String, String, String), VersionFileError> {
2022-10-25 15:06:28 +02:00
let version_path = db_path.join(VERSION_FILE_NAME);
match fs::read_to_string(version_path) {
2024-09-05 10:08:06 +02:00
Ok(version) => parse_version(&version),
Err(error) => match error.kind() {
ErrorKind::NotFound => Err(VersionFileError::MissingVersionFile),
_ => Err(error.into()),
},
2022-10-25 15:06:28 +02:00
}
2024-09-05 10:08:06 +02:00
}
2022-10-25 15:06:28 +02:00
2024-09-05 10:08:06 +02:00
pub fn parse_version(version: &str) -> Result<(String, String, String), VersionFileError> {
let version_components = version.split('.').collect::<Vec<_>>();
let (major, minor, patch) = match &version_components[..] {
[major, minor, patch] => (major.to_string(), minor.to_string(), patch.to_string()),
_ => return Err(VersionFileError::MalformedVersionFile),
};
Ok((major, minor, patch))
2022-10-25 15:06:28 +02:00
}
#[derive(thiserror::Error, Debug)]
pub enum VersionFileError {
#[error(
"Meilisearch (v{}) failed to infer the version of the database.
To update Meilisearch please follow our guide on https://www.meilisearch.com/docs/learn/update_and_migration/updating.",
2022-10-25 15:06:28 +02:00
env!("CARGO_PKG_VERSION").to_string()
)]
MissingVersionFile,
#[error("Version file is corrupted and thus Meilisearch is unable to determine the version of the database.")]
MalformedVersionFile,
#[error(
"Your database version ({major}.{minor}.{patch}) is incompatible with your current engine version ({}).\n\
To migrate data between Meilisearch versions, please follow our guide on https://www.meilisearch.com/docs/learn/update_and_migration/updating.",
2022-10-25 15:06:28 +02:00
env!("CARGO_PKG_VERSION").to_string()
)]
VersionMismatch { major: String, minor: String, patch: String },
2024-09-05 10:08:06 +02:00
#[error(transparent)]
IoError(#[from] std::io::Error),
2022-10-25 15:06:28 +02:00
}