mirror of https://github.com/sharkdp/bat
Add metadata information to cached assets
When saving/reading user-provided syntaxes or themes, `bat` will now maintain a `metadata.yaml` file which includes information about the `bat` version which was used to create the cached files. When loading cached files, we now print an error if they have been created with an incompatible version closes #882pull/933/head
parent
c8273369cc
commit
72618db179
@ -0,0 +1,82 @@
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use clap::crate_version;
|
||||
use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::errors::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
|
||||
pub struct AssetsMetadata {
|
||||
bat_version: Option<String>,
|
||||
creation_time: Option<SystemTime>,
|
||||
}
|
||||
|
||||
const FILENAME: &'static str = "metadata.yaml";
|
||||
|
||||
impl AssetsMetadata {
|
||||
pub(crate) fn new() -> AssetsMetadata {
|
||||
AssetsMetadata {
|
||||
bat_version: Some(crate_version!().into()),
|
||||
creation_time: Some(SystemTime::now()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn save_to_folder(&self, path: &Path) -> Result<()> {
|
||||
let file = File::create(path.join(FILENAME))?;
|
||||
serde_yaml::to_writer(file, self)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_load_from_folder(path: &Path) -> Result<Self> {
|
||||
let file = File::open(path.join(FILENAME))?;
|
||||
Ok(serde_yaml::from_reader(file)?)
|
||||
}
|
||||
|
||||
/// Load metadata about the stored cache file from the given folder.
|
||||
///
|
||||
/// There are several possibilities:
|
||||
/// - We find a metadata.yaml file and are able to parse it
|
||||
/// => return the contained information
|
||||
/// - We find a metadata.yaml file and but are not able to parse it
|
||||
/// => return a SerdeYamlError
|
||||
/// - We do not find a metadata.yaml file but a syntaxes.bin or themes.bin file
|
||||
/// => assume that these were created by an old version of bat and return
|
||||
/// AssetsMetadata::default() without version information
|
||||
/// - We do not find a metadata.yaml file and no cached assets
|
||||
/// => no user provided assets are available, return None
|
||||
pub fn load_from_folder(path: &Path) -> Result<Option<Self>> {
|
||||
match Self::try_load_from_folder(path) {
|
||||
Ok(metadata) => Ok(Some(metadata)),
|
||||
Err(e) => match e.kind() {
|
||||
ErrorKind::SerdeYamlError(_) => Err(e),
|
||||
_ => {
|
||||
if path.join("syntaxes.bin").exists() || path.join("themes.bin").exists() {
|
||||
Ok(Some(Self::default()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_compatible(&self) -> bool {
|
||||
let current_version =
|
||||
Version::parse(crate_version!()).expect("bat follows semantic versioning");
|
||||
let stored_version = self
|
||||
.bat_version
|
||||
.as_ref()
|
||||
.and_then(|ver| Version::parse(ver).ok());
|
||||
|
||||
if let Some(stored_version) = stored_version {
|
||||
current_version.major == stored_version.major
|
||||
&& current_version.minor == stored_version.minor
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue