1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::{path::Path, fs::{read_to_string, self}, io::ErrorKind};
use anyhow::{Context, anyhow};
use log::info;
use serde::{Serialize, Deserialize};
use toml_edit::{Document, value, array, Table};
use crate::salmo_contex::SalmoContext;
use super::migrations::Migration;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CommittedFile {
pub commits: Vec<Commit>
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Commit {
pub id: String,
pub hash: String
}
impl CommittedFile {
pub fn load(dir: &Path) -> anyhow::Result<Self> {
let file = match read_to_string(dir.join("committed.toml")) {
Ok(s) => s,
Err(e) => match e.kind() {
ErrorKind::NotFound => {
info!("No committed file. Assuming no commits, this is fine.");
return Ok(CommittedFile { commits: Vec::new() })
},
_ => return Err(e.into()),
},
};
toml_edit::easy::from_str(&file).context("parsing committed.toml")
}
pub fn add_commit(ctx: &SalmoContext, migration_id: &str) -> anyhow::Result<Commit> {
let dir = ctx.config.migrations_directory.join("committed.toml");
let file = read_to_string(&dir).or_else(|e| match e.kind() {
ErrorKind::NotFound => Ok("".to_string()),
_ => Err(e)
})?;
let mut doc = file.parse::<Document>()?;
doc.entry("version").or_insert(value("1"));
let commits = doc.entry("commits")
.or_insert(array())
.as_array_of_tables_mut()
.ok_or_else(|| anyhow!("corrupt committed.toml: the [commits] value must be an array of tables"))?;
let migrations = ctx.migrations()?;
let m = migrations.db.get(migration_id).ok_or_else(|| anyhow!("migration with id `{}` does not exist!", migration_id))?;
let hash = m.migrate_hash()?;
let mut commit_table = Table::new();
commit_table.insert("id", value(migration_id));
commit_table.insert("hash", value(&hash));
commits.push(commit_table);
fs::write(dir, doc.to_string())?;
Ok(Commit { id: migration_id.to_string(), hash })
}
pub fn contains_migration(&self, m: &Migration) -> bool {
self.commits.iter().any(|c| c.id == m.id )
}
}