extract create current session to store

This commit is contained in:
Nikita Galaiko 2023-03-21 07:59:56 +01:00
parent 9dfe98cef2
commit 06371e4c36
No known key found for this signature in database
GPG Key ID: EBAB54E845BA519D
10 changed files with 229 additions and 228 deletions

View File

@ -1,12 +1,11 @@
use crate::{deltas, projects, sessions};
use anyhow::{anyhow, Context, Result};
use std::{collections::HashMap, path::Path};
use std::{collections::HashMap, path::Path, time};
use super::{current, persistent};
pub struct Store {
project: projects::Project,
git_repository: git2::Repository,
persistent: persistent::Store,
current: current::Store,
@ -18,7 +17,6 @@ impl Clone for Store {
fn clone(&self) -> Self {
Self {
project: self.project.clone(),
git_repository: git2::Repository::open(&self.project.path).unwrap(),
current: self.current.clone(),
persistent: self.persistent.clone(),
sessions_store: self.sessions_store.clone(),
@ -27,14 +25,9 @@ impl Clone for Store {
}
impl Store {
pub fn new(
git_repository: git2::Repository,
project: projects::Project,
sessions_store: sessions::Store,
) -> Result<Self> {
pub fn new(project: projects::Project, sessions_store: sessions::Store) -> Result<Self> {
Ok(Self {
project: project.clone(),
git_repository,
current: current::Store::new(project.clone()),
persistent: persistent::Store::new(project)?,
sessions_store,
@ -52,13 +45,23 @@ impl Store {
) -> Result<sessions::Session> {
// make sure we always have a session before writing deltas
let session = match self.sessions_store.get_current()? {
Some(mut session) => {
session
.touch(&self.project)
.with_context(|| format!("failed to touch session {}", session.id))?;
Ok(session)
Some(session) => {
let updated_session = sessions::Session {
meta: sessions::Meta {
last_timestamp_ms: time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_millis(),
..session.meta
},
..session
};
self.sessions_store
.update(&updated_session)
.with_context(|| format!("failed to touch session {}", updated_session.id))?;
Ok(updated_session)
}
None => sessions::Session::from_head(&self.git_repository, &self.project),
None => self.sessions_store.create_current(),
}?;
self.current.write(file_path, deltas)?;

View File

@ -26,7 +26,7 @@ fn test_project() -> Result<(git2::Repository, projects::Project)> {
fn test_read_none() {
let (repo, project) = test_project().unwrap();
let sessions_store = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let store = super::Store::new(repo, project, sessions_store).unwrap();
let store = super::Store::new(project, sessions_store).unwrap();
let file_path = Path::new("test.txt");
let deltas = store.read(file_path);
assert!(deltas.is_ok());
@ -37,7 +37,7 @@ fn test_read_none() {
fn test_read_invalid() {
let (repo, project) = test_project().unwrap();
let sessions_store = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let store = super::Store::new(repo, project.clone(), sessions_store).unwrap();
let store = super::Store::new(project.clone(), sessions_store).unwrap();
let file_path = Path::new("test.txt");
let full_file_path = project.deltas_path().join(file_path);
@ -52,7 +52,7 @@ fn test_read_invalid() {
fn test_write_read() {
let (repo, project) = test_project().unwrap();
let sessions_store = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let store = super::Store::new(repo, project, sessions_store).unwrap();
let store = super::Store::new(project, sessions_store).unwrap();
let file_path = Path::new("test.txt");
let deltas = vec![Delta {
@ -71,7 +71,7 @@ fn test_write_read() {
fn test_write_must_create_session() {
let (repo, project) = test_project().unwrap();
let sessions_store = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone(), sessions_store.clone()).unwrap();
let store = super::Store::new(project.clone(), sessions_store.clone()).unwrap();
let file_path = Path::new("test.txt");
let deltas = vec![Delta {
@ -96,10 +96,10 @@ fn clone_repo(repo: &git2::Repository) -> git2::Repository {
fn test_write_must_not_override_session() {
let (repo, project) = test_project().unwrap();
let sessions_store = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone(), sessions_store.clone()).unwrap();
let store = super::Store::new(project.clone(), sessions_store.clone()).unwrap();
let file_path = Path::new("test.txt");
let session_before_write = sessions::Session::from_head(&repo, &project);
let session_before_write = sessions_store.create_current();
assert!(session_before_write.is_ok());
let session_before_write = session_before_write.unwrap();

View File

@ -549,9 +549,12 @@ fn main() {
let app_handle = app.handle();
tauri::async_runtime::spawn_blocking(move || {
let start = std::time::Instant::now();
log::info!("initializing app");
if let Err(e) = init(app_handle) {
log::error!("failed to app: {:#}", e);
}
log::info!("app initialized in {:?}", start.elapsed());
});
Ok(())
@ -666,12 +669,16 @@ fn init(app_handle: tauri::AppHandle) -> Result<()> {
.watchers
.lock()
.unwrap()
.watch(tx.clone(), &project, &repo.deltas_storage, &repo.sessions_storage)
.watch(
tx.clone(),
&project,
&repo.deltas_storage,
&repo.sessions_storage,
)
.with_context(|| format!("{}: failed to watch project", project.id))?;
let git_repository = repo.git_repository;
if let Err(err) = app_state.deltas_searcher.lock().unwrap().reindex_project(
&git_repository,
&repo.git_repository,
&repo.project,
&repo.deltas_storage,
&repo.sessions_storage,

View File

@ -33,11 +33,7 @@ impl Repository {
Ok(Repository {
project: project.clone(),
git_repository,
deltas_storage: deltas::Store::new(
git2::Repository::open(&project.path)?,
project,
sessions_storage.clone(),
)?,
deltas_storage: deltas::Store::new(project, sessions_storage.clone())?,
sessions_storage,
})
}
@ -355,7 +351,7 @@ impl Repository {
// if the reference doesn't exist, we create it by creating a flushing a new session
let mut current_session = match self.sessions_storage.get_current()? {
Some(session) => session,
None => sessions::Session::from_head(&self.git_repository, &self.project)?,
None => self.sessions_storage.create_current()?,
};
current_session
.flush(&self.git_repository, user, &self.project)
@ -380,7 +376,7 @@ fn init(
// if the reference doesn't exist, we create it by creating a flushing a new session
let mut current_session = match sessions_storage.get_current()? {
Some(session) => session,
None => sessions::Session::from_head(git_repository, project)?,
None => sessions_storage.create_current()?,
};
current_session
.flush(git_repository, user, project)

View File

@ -36,9 +36,8 @@ fn test_filter_by_timestamp() {
let index_path = tempdir().unwrap().path().to_str().unwrap().to_string();
let sessions_storage = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let deltas_storage =
deltas::Store::new(clone_repo(&repo), project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions::Session::from_head(&repo, &project).unwrap();
let deltas_storage = deltas::Store::new(project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions_storage.create_current().unwrap();
deltas_storage
.write(
Path::new("test.txt"),
@ -62,12 +61,8 @@ fn test_filter_by_timestamp() {
let mut searcher = super::Deltas::at(index_path.into()).unwrap();
let write_result = searcher.index_session(
&project,
&session,
&deltas_storage,
&sessions_storage,
);
let write_result =
searcher.index_session(&project, &session, &deltas_storage, &sessions_storage);
assert!(write_result.is_ok());
let search_result_from = searcher.search(&super::SearchQuery {
@ -113,9 +108,8 @@ fn test_sorted_by_timestamp() {
let index_path = tempdir().unwrap().path().to_str().unwrap().to_string();
let sessions_storage = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let deltas_storage =
deltas::Store::new(clone_repo(&repo), project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions::Session::from_head(&repo, &project).unwrap();
let deltas_storage = deltas::Store::new(project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions_storage.create_current().unwrap();
deltas_storage
.write(
Path::new("test.txt"),
@ -135,12 +129,8 @@ fn test_sorted_by_timestamp() {
let mut searcher = super::Deltas::at(index_path.into()).unwrap();
let write_result = searcher.index_session(
&project,
&session,
&deltas_storage,
&sessions_storage,
);
let write_result =
searcher.index_session(&project, &session, &deltas_storage, &sessions_storage);
assert!(write_result.is_ok());
let search_result = searcher.search(&super::SearchQuery {
@ -164,9 +154,8 @@ fn test_simple() {
let index_path = tempdir().unwrap().path().to_str().unwrap().to_string();
let sessions_storage = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let deltas_storage =
deltas::Store::new(clone_repo(&repo), project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions::Session::from_head(&repo, &project).unwrap();
let deltas_storage = deltas::Store::new(project.clone(), sessions_storage.clone()).unwrap();
let mut session = sessions_storage.create_current().unwrap();
deltas_storage
.write(
Path::new("test.txt"),
@ -186,12 +175,8 @@ fn test_simple() {
let mut searcher = super::Deltas::at(index_path.into()).unwrap();
let write_result = searcher.index_session(
&project,
&session,
&deltas_storage,
&sessions_storage,
);
let write_result =
searcher.index_session(&project, &session, &deltas_storage, &sessions_storage);
assert!(write_result.is_ok());
let search_result1 = searcher.search(&super::SearchQuery {

View File

@ -10,9 +10,7 @@ use std::{
io::{BufReader, Read},
os::unix::prelude::MetadataExt,
path::Path,
time,
};
use uuid::Uuid;
#[derive(Debug, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
@ -38,46 +36,6 @@ pub struct Session {
}
impl Session {
pub fn from_head(repo: &git2::Repository, project: &projects::Project) -> Result<Self> {
let now_ts = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_millis();
let activity = match std::fs::read_to_string(repo.path().join("logs/HEAD")) {
Ok(reflog) => reflog
.lines()
.filter_map(|line| activity::parse_reflog_line(line).ok())
.filter(|activity| activity.timestamp_ms >= now_ts)
.collect::<Vec<activity::Activity>>(),
Err(_) => Vec::new(),
};
let meta = match repo.head() {
Ok(head) => Meta {
start_timestamp_ms: now_ts,
last_timestamp_ms: now_ts,
branch: Some(head.name().unwrap().to_string()),
commit: Some(head.peel_to_commit().unwrap().id().to_string()),
},
Err(_) => Meta {
start_timestamp_ms: now_ts,
last_timestamp_ms: now_ts,
branch: None,
commit: None,
},
};
let session = Session {
id: Uuid::new_v4().to_string(),
hash: None,
meta,
activity,
};
create(project, &session).with_context(|| "failed to create current session from head")?;
Ok(session)
}
pub fn from_commit(repo: &git2::Repository, commit: &git2::Commit) -> Result<Self> {
let tree = commit.tree().with_context(|| {
format!("failed to get tree from commit {}", commit.id().to_string())
@ -159,10 +117,6 @@ impl Session {
})
}
pub fn touch(&mut self, project: &projects::Project) -> Result<()> {
update(project, self)
}
pub fn flush(
&mut self,
repo: &git2::Repository,
@ -173,106 +127,6 @@ impl Session {
}
}
fn write(session_path: &Path, session: &Session) -> Result<()> {
if session.hash.is_some() {
return Err(anyhow!("cannot write session that is not current"));
}
let meta_path = session_path.join("meta");
std::fs::create_dir_all(meta_path.clone()).with_context(|| {
format!(
"failed to create session meta directory {}",
meta_path.display()
)
})?;
let id_path = meta_path.join("id");
std::fs::write(id_path.clone(), session.id.clone())
.with_context(|| format!("failed to write session id to {}", id_path.display()))?;
let start_path = meta_path.join("start");
std::fs::write(
start_path.clone(),
session.meta.start_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session start timestamp to {}",
start_path.display()
)
})?;
let last_path = meta_path.join("last");
std::fs::write(
last_path.clone(),
session.meta.last_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session last timestamp to {}",
last_path.display()
)
})?;
if let Some(branch) = session.meta.branch.clone() {
let branch_path = meta_path.join("branch");
std::fs::write(branch_path.clone(), branch).with_context(|| {
format!(
"failed to write session branch to {}",
branch_path.display()
)
})?;
}
if let Some(commit) = session.meta.commit.clone() {
let commit_path = meta_path.join("commit");
std::fs::write(commit_path.clone(), commit).with_context(|| {
format!(
"failed to write session commit to {}",
commit_path.display()
)
})?;
}
Ok(())
}
fn update(project: &projects::Project, session: &mut Session) -> Result<()> {
session.meta.last_timestamp_ms = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_millis();
let session_path = project.session_path();
log::debug!("{}: updating current session", project.id);
if session_path.exists() {
write(&session_path, session)
} else {
Err(anyhow!("\"{}\" does not exist", session_path.display()))
}
}
fn create(project: &projects::Project, session: &Session) -> Result<()> {
let session_path = project.session_path();
log::debug!("{}: Creating current session", session_path.display());
let meta_path = session_path.join("meta");
if meta_path.exists() {
Err(anyhow!("session already exists"))
} else {
write(&session_path, session)
}
}
fn delete(project: &projects::Project) -> Result<()> {
let session_path = project.session_path();
log::debug!("{}: deleting current session", project.id);
if session_path.exists() {
std::fs::remove_dir_all(session_path)?;
}
Ok(())
}
pub fn id_from_commit(repo: &git2::Repository, commit: &git2::Commit) -> Result<String> {
let tree = commit.tree().unwrap();
let session_id_path = Path::new("session/meta/id");
@ -308,10 +162,6 @@ fn flush(
));
}
session
.touch(project)
.with_context(|| format!("failed to touch session"))?;
let wd_tree = build_wd_tree(&repo, &project)
.with_context(|| "failed to build wd tree for project".to_string())?;
@ -377,6 +227,15 @@ fn flush(
Ok(())
}
fn delete(project: &projects::Project) -> Result<()> {
let session_path = project.session_path();
log::debug!("{}: deleting current session", project.id);
if session_path.exists() {
std::fs::remove_dir_all(session_path)?;
}
Ok(())
}
// try to push the new gb history head to the remote
// TODO: if we see it is not a FF, pull down the remote, determine order, rewrite the commit line, and push again
fn push_to_remote(

View File

@ -53,29 +53,32 @@ fn test_current_none() {
#[test]
fn test_create_current_fails_when_meta_path_exists() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(repo, project.clone()).unwrap();
let meta_path = project.session_path().join("meta");
std::fs::create_dir_all(&meta_path).unwrap();
let current_session = super::sessions::Session::from_head(&repo, &project);
let current_session = store.create_current();
assert!(current_session.is_err());
}
#[test]
fn test_create_current_when_session_dir_exists() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(repo, project.clone()).unwrap();
let session_dir = project.session_path();
std::fs::create_dir_all(&session_dir).unwrap();
let current_session = super::sessions::Session::from_head(&repo, &project);
let current_session = store.create_current();
assert!(current_session.is_ok());
}
#[test]
fn test_create_current_empty() {
let (repo, project) = test_project_empty().unwrap();
let current_session = super::sessions::Session::from_head(&repo, &project);
let store = super::Store::new(repo, project).unwrap();
let current_session = store.create_current();
assert!(current_session.is_ok());
assert!(current_session.as_ref().unwrap().id.len() > 0);
assert_eq!(current_session.as_ref().unwrap().hash, None);
@ -92,7 +95,8 @@ fn test_create_current_empty() {
#[test]
fn test_create_current() {
let (repo, project) = test_project().unwrap();
let current_session = super::sessions::Session::from_head(&repo, &project);
let store = super::Store::new(clone_repo(&repo), project).unwrap();
let current_session = store.create_current();
assert!(current_session.is_ok());
assert!(current_session.as_ref().unwrap().id.len() > 0);
assert_eq!(current_session.as_ref().unwrap().hash, None);
@ -136,7 +140,7 @@ fn test_create_current() {
fn test_get_current() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone()).unwrap();
let created_session = super::sessions::Session::from_head(&repo, &project);
let created_session = store.create_current();
assert!(created_session.is_ok());
let created_session = created_session.unwrap();
@ -152,7 +156,7 @@ fn test_get_current() {
fn test_flush() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone()).unwrap();
let created_session = super::sessions::Session::from_head(&repo, &project);
let created_session = store.create_current();
assert!(created_session.is_ok());
let mut created_session = created_session.unwrap();
@ -183,7 +187,7 @@ fn test_flush() {
fn test_flush_with_user() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone()).unwrap();
let created_session = super::sessions::Session::from_head(&repo, &project);
let created_session = store.create_current();
assert!(created_session.is_ok());
let mut created_session = created_session.unwrap();
@ -213,7 +217,8 @@ fn test_flush_with_user() {
#[test]
fn test_get_persistent() {
let (repo, project) = test_project().unwrap();
let created_session = super::sessions::Session::from_head(&repo, &project);
let store = super::Store::new(clone_repo(&repo), project.clone()).unwrap();
let created_session = store.create_current();
assert!(created_session.is_ok());
let mut created_session = created_session.unwrap();
@ -237,19 +242,19 @@ fn clone_repo(repo: &git2::Repository) -> git2::Repository {
fn test_list() {
let (repo, project) = test_project().unwrap();
let store = super::Store::new(clone_repo(&repo), project.clone()).unwrap();
let first = super::sessions::Session::from_head(&repo, &project);
let first = store.create_current();
assert!(first.is_ok());
let mut first = first.unwrap();
first.flush(&repo, &None, &project).unwrap();
assert!(first.hash.is_some());
let second = super::sessions::Session::from_head(&repo, &project);
let second = store.create_current();
assert!(second.is_ok());
let mut second = second.unwrap();
second.flush(&repo, &None, &project).unwrap();
assert!(second.hash.is_some());
let current_session = super::sessions::Session::from_head(&repo, &project);
let current_session = store.create_current();
assert!(current_session.is_ok());
let current = current_session.unwrap();
@ -272,7 +277,7 @@ fn test_list_files_from_first_presistent_session() {
std::fs::write(file_path.clone(), "zero").unwrap();
let first = super::sessions::Session::from_head(&repo, &project);
let first = store.create_current();
assert!(first.is_ok());
let mut first = first.unwrap();
first.flush(&repo, &None, &project).unwrap();
@ -296,7 +301,7 @@ fn test_list_files_from_second_current_session() {
let file_path = Path::new(&project.path).join("test.txt");
std::fs::write(file_path.clone(), "zero").unwrap();
let first = super::sessions::Session::from_head(&repo, &project);
let first = store.create_current();
assert!(first.is_ok());
let mut first = first.unwrap();
first.flush(&repo, &None, &project).unwrap();
@ -306,7 +311,7 @@ fn test_list_files_from_second_current_session() {
std::fs::write(file_path.clone(), "one").unwrap();
let second = super::sessions::Session::from_head(&repo, &project);
let second = store.create_current();
assert!(second.is_ok());
let second = second.unwrap();
@ -325,7 +330,7 @@ fn test_list_files_from_second_presistent_session() {
let file_path = Path::new(&project.path).join("test.txt");
std::fs::write(file_path.clone(), "zero").unwrap();
let first = super::sessions::Session::from_head(&repo, &project);
let first = store.create_current();
assert!(first.is_ok());
let mut first = first.unwrap();
first.flush(&repo, &None, &project).unwrap();
@ -335,7 +340,7 @@ fn test_list_files_from_second_presistent_session() {
std::fs::write(file_path.clone(), "one").unwrap();
let second = super::sessions::Session::from_head(&repo, &project);
let second = store.create_current();
assert!(second.is_ok());
let mut second = second.unwrap();
second.flush(&repo, &None, &project).unwrap();
@ -365,7 +370,7 @@ fn test_flush_ensure_wd_structure() {
std::fs::write(file2_path.clone(), "zero").unwrap();
// flush first session
let first = super::sessions::Session::from_head(&repo, &project);
let first = store.create_current();
assert!(first.is_ok());
let mut first = first.unwrap();
first.flush(&repo, &None, &project).unwrap();
@ -387,7 +392,7 @@ fn test_flush_ensure_wd_structure() {
.unwrap();
// flush second session
let second = super::sessions::Session::from_head(&repo, &project);
let second = store.create_current();
assert!(second.is_ok());
let mut second = second.unwrap();
second.flush(&repo, &None, &project).unwrap();

View File

@ -1,5 +1,8 @@
use std::time;
use crate::{projects, sessions};
use anyhow::{Context, Result};
use uuid::Uuid;
pub struct Store {
project: projects::Project,
@ -23,6 +26,137 @@ impl Store {
})
}
pub fn create(&self) -> Result<sessions::Session> {
let now_ts = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_millis();
let activity = match std::fs::read_to_string(self.git_repository.path().join("logs/HEAD")) {
Ok(reflog) => reflog
.lines()
.filter_map(|line| sessions::activity::parse_reflog_line(line).ok())
.filter(|activity| activity.timestamp_ms >= now_ts)
.collect::<Vec<sessions::activity::Activity>>(),
Err(_) => Vec::new(),
};
let meta = match self.git_repository.head() {
Ok(head) => sessions::Meta {
start_timestamp_ms: now_ts,
last_timestamp_ms: now_ts,
branch: Some(head.name().unwrap().to_string()),
commit: Some(head.peel_to_commit().unwrap().id().to_string()),
},
Err(_) => sessions::Meta {
start_timestamp_ms: now_ts,
last_timestamp_ms: now_ts,
branch: None,
commit: None,
},
};
let session = sessions::Session {
id: Uuid::new_v4().to_string(),
hash: None,
meta,
activity,
};
let session_path = self.project.session_path();
log::debug!("{}: Creating current session", session_path.display());
let meta_path = session_path.join("meta");
if meta_path.exists() {
return Err(anyhow::anyhow!("session already exists"));
}
self.write(&session)?;
Ok(session)
}
pub fn update(&self, session: &sessions::Session) -> Result<()> {
if session.hash.is_some() {
return Err(anyhow::anyhow!("cannot update session that is not current"));
}
let session_path = self.project.session_path();
log::debug!("{}: updating current session", self.project.id);
if session_path.exists() {
self.write(session)
} else {
Err(anyhow::anyhow!(
"\"{}\" does not exist",
session_path.display()
))
}
}
fn write(&self, session: &sessions::Session) -> Result<()> {
let session_path = self.project.session_path();
if session.hash.is_some() {
return Err(anyhow::anyhow!("cannot write session that is not current"));
}
let meta_path = session_path.join("meta");
std::fs::create_dir_all(meta_path.clone()).with_context(|| {
format!(
"failed to create session meta directory {}",
meta_path.display()
)
})?;
let id_path = meta_path.join("id");
std::fs::write(id_path.clone(), session.id.clone())
.with_context(|| format!("failed to write session id to {}", id_path.display()))?;
let start_path = meta_path.join("start");
std::fs::write(
start_path.clone(),
session.meta.start_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session start timestamp to {}",
start_path.display()
)
})?;
let last_path = meta_path.join("last");
std::fs::write(
last_path.clone(),
session.meta.last_timestamp_ms.to_string(),
)
.with_context(|| {
format!(
"failed to write session last timestamp to {}",
last_path.display()
)
})?;
if let Some(branch) = session.meta.branch.clone() {
let branch_path = meta_path.join("branch");
std::fs::write(branch_path.clone(), branch).with_context(|| {
format!(
"failed to write session branch to {}",
branch_path.display()
)
})?;
}
if let Some(commit) = session.meta.commit.clone() {
let commit_path = meta_path.join("commit");
std::fs::write(commit_path.clone(), commit).with_context(|| {
format!(
"failed to write session commit to {}",
commit_path.display()
)
})?;
}
Ok(())
}
pub fn get(&self) -> Result<Option<sessions::Session>> {
let session_path = self.project.session_path();
let meta_path = session_path.join("meta");

View File

@ -25,6 +25,18 @@ impl Store {
})
}
pub fn create_current(&self) -> Result<sessions::Session> {
self.current.create()
}
pub fn update(&self, session: &sessions::Session) -> Result<()> {
if session.hash.is_some() {
Err(anyhow::anyhow!("cannot update session that is not current"))
} else {
self.current.update(session)
}
}
pub fn list_files(
&self,
session_id: &str,

View File

@ -36,7 +36,7 @@ fn test_register_file_change_must_create_session() {
let sessions_storage = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let deltas_storage =
deltas::Store::new(clone_repo(&repo), project.clone(), sessions_storage).unwrap();
deltas::Store::new(project.clone(), sessions_storage).unwrap();
let result =
super::delta::register_file_change(&project, &repo, &deltas_storage, &relative_file_path);
println!("{:?}", result);
@ -57,7 +57,7 @@ fn test_register_file_change_must_not_change_session() {
let sessions_storage = sessions::Store::new(clone_repo(&repo), project.clone()).unwrap();
let deltas_storage =
deltas::Store::new(clone_repo(&repo), project.clone(), sessions_storage).unwrap();
deltas::Store::new(project.clone(), sessions_storage).unwrap();
let result =
super::delta::register_file_change(&project, &repo, &deltas_storage, &relative_file_path);
assert!(result.is_ok());