make sure session exists when writing deltas

This commit is contained in:
Nikita Galaiko 2023-02-21 14:32:52 +01:00
parent 1c8d4577f7
commit b6482b4347
No known key found for this signature in database
GPG Key ID: EBAB54E845BA519D
5 changed files with 82 additions and 16 deletions

View File

@ -27,7 +27,16 @@ pub fn read(project: &projects::Project, file_path: &Path) -> Result<Option<Vec<
Ok(Some(serde_json::from_str(&file_deltas)?))
}
pub fn write(project: &projects::Project, file_path: &Path, deltas: &Vec<Delta>) -> Result<()> {
pub fn write(
repo: &git2::Repository,
project: &projects::Project,
file_path: &Path,
deltas: &Vec<Delta>,
) -> Result<()> {
if sessions::Session::current(repo, project)?.is_none() {
sessions::Session::from_head(repo, project)?;
}
let delta_path = project.deltas_path().join(file_path);
let delta_dir = delta_path.parent().unwrap();
std::fs::create_dir_all(&delta_dir)?;

View File

@ -1,19 +1,30 @@
use crate::{deltas::operations::Operation, projects};
use crate::{deltas::operations::Operation, projects, sessions};
use anyhow::Result;
use std::path::Path;
use tempfile::tempdir;
fn test_project() -> Result<projects::Project> {
fn test_project() -> Result<(git2::Repository, projects::Project)> {
let path = tempdir()?.path().to_str().unwrap().to_string();
std::fs::create_dir_all(&path)?;
git2::Repository::init(&path)?;
let repo = git2::Repository::init(&path)?;
let mut index = repo.index()?;
let oid = index.write_tree()?;
let sig = git2::Signature::now("test", "test@email.com").unwrap();
let _commit = repo.commit(
Some("HEAD"),
&sig,
&sig,
"initial commit",
&repo.find_tree(oid)?,
&[],
)?;
let project = projects::Project::from_path(path)?;
Ok(project)
Ok((repo, project))
}
#[test]
fn test_read_none() {
let project = test_project().unwrap();
let (_repo, project) = test_project().unwrap();
let file_path = Path::new("test.txt");
let deltas = super::read(&project, file_path);
assert!(deltas.is_ok());
@ -22,7 +33,7 @@ fn test_read_none() {
#[test]
fn test_read_invalid() {
let project = test_project().unwrap();
let (_repo, project) = test_project().unwrap();
let file_path = Path::new("test.txt");
let full_file_path = project.deltas_path().join(file_path);
@ -35,17 +46,62 @@ fn test_read_invalid() {
#[test]
fn test_write_read() {
let project = test_project().unwrap();
let (repo, project) = test_project().unwrap();
let file_path = Path::new("test.txt");
let deltas = vec![super::Delta {
operations: vec![Operation::Insert((0, "Hello, world!".to_string()))],
timestamp_ms: 0,
}];
let write_result = super::write(&project, file_path, &deltas);
let write_result = super::write(&repo, &project, file_path, &deltas);
assert!(write_result.is_ok());
let read_result = super::read(&project, file_path);
assert!(read_result.is_ok());
assert_eq!(read_result.unwrap().unwrap(), deltas);
}
#[test]
fn test_write_must_create_session() {
let (repo, project) = test_project().unwrap();
let file_path = Path::new("test.txt");
let deltas = vec![super::Delta {
operations: vec![Operation::Insert((0, "Hello, world!".to_string()))],
timestamp_ms: 0,
}];
let write_result = super::write(&repo, &project, file_path, &deltas);
assert!(write_result.is_ok());
let current_session = sessions::Session::current(&repo, &project);
assert!(current_session.is_ok());
let current_session = current_session.unwrap();
assert!(current_session.is_some());
}
#[test]
fn test_write_must_not_override_session() {
let (repo, project) = test_project().unwrap();
let file_path = Path::new("test.txt");
let session_before_write = sessions::Session::from_head(&repo, &project);
assert!(session_before_write.is_ok());
let session_before_write = session_before_write.unwrap();
let deltas = vec![super::Delta {
operations: vec![Operation::Insert((0, "Hello, world!".to_string()))],
timestamp_ms: 0,
}];
let write_result = super::write(&repo, &project, file_path, &deltas);
assert!(write_result.is_ok());
let session_after_write = sessions::Session::current(&repo, &project);
assert!(session_after_write.is_ok());
let session_after_write = session_after_write.unwrap();
assert!(session_after_write.is_some());
let session_after_write = session_after_write.unwrap();
assert_eq!(session_before_write, session_after_write);
}

View File

@ -3,6 +3,7 @@ mod operations;
mod text_document;
pub use deltas::{list, read, write, Delta};
pub use operations::Operation;
pub use text_document::TextDocument;
#[cfg(test)]

View File

@ -46,7 +46,7 @@ fn test_current_none() {
}
#[test]
fn test_create_current() {
fn test_create_current_no_deltas() {
let (repo, project) = test_project().unwrap();
let current_session = super::sessions::Session::from_head(&repo, &project);
assert!(current_session.is_ok());

View File

@ -2,7 +2,7 @@ use crate::deltas::{read, write, Delta, TextDocument};
use crate::projects;
use crate::{events, sessions};
use anyhow::{Context, Result};
use git2::Repository;
use git2;
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
use std::fs;
use std::path::Path;
@ -37,7 +37,7 @@ impl<'a> DeltaWatchers<'a> {
.unwrap()
.insert(project.path.clone(), watcher);
let repo = Repository::open(project_path);
let repo = git2::Repository::open(project_path);
thread::spawn(move || {
if repo.is_err() {
log::error!("failed to open git repo: {:?}", repo.err());
@ -95,7 +95,7 @@ impl<'a> DeltaWatchers<'a> {
fn register_file_change<R: tauri::Runtime>(
window: &tauri::Window<R>,
project: &projects::Project,
repo: &Repository,
repo: &git2::Repository,
kind: &EventKind,
relative_file_path: &Path,
) -> Result<Option<(sessions::Session, Vec<Delta>)>, Box<dyn std::error::Error>> {
@ -162,7 +162,7 @@ fn register_file_change<R: tauri::Runtime>(
// if the file was modified, save the deltas
let deltas = text_doc.get_deltas();
write(project, relative_file_path, &deltas)?;
write(repo, project, relative_file_path, &deltas)?;
return Ok(Some((session, deltas)));
}
@ -172,7 +172,7 @@ fn register_file_change<R: tauri::Runtime>(
// returns None if file is not UTF-8
// TODO: handle binary files
fn get_latest_file_contents(
repo: &Repository,
repo: &git2::Repository,
project: &projects::Project,
relative_file_path: &Path,
) -> Result<Option<String>> {
@ -227,7 +227,7 @@ fn get_latest_file_contents(
fn write_beginning_meta_files<R: tauri::Runtime>(
window: &tauri::Window<R>,
project: &projects::Project,
repo: &Repository,
repo: &git2::Repository,
) -> Result<sessions::Session, Box<dyn std::error::Error>> {
match sessions::Session::current(repo, project)
.map_err(|e| format!("Error while getting current session: {}", e.to_string()))?