Merge pull request #1283 from gitbutlerapp/tests-suite

Tests suite
This commit is contained in:
Nikita Galaiko 2023-10-04 14:02:45 +02:00 committed by GitHub
commit 65b108ad1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1759 additions and 2045 deletions

View File

@ -11,6 +11,7 @@ pub struct App {
project: projects::Project,
gb_repository: gb_repository::Repository,
sessions_db: sessions::Database,
user: Option<users::User>,
}
impl App {
@ -19,9 +20,9 @@ impl App {
let local_data_dir = find_local_data_dir().context("could not find local data dir")?;
let storage = storage::Storage::from(&local_data_dir);
let users_storage = users::Storage::from(storage.clone());
let users_storage = users::Storage::from(&storage);
let projects_storage = projects::Storage::try_from(storage)?;
let projects_storage = projects::Storage::try_from(&storage)?;
let projects = projects_storage
.list_projects()
.context("failed to list projects")?;
@ -31,11 +32,12 @@ impl App {
.find(|p| p.path == path)
.context("failed to find project")?;
let user = users_storage.get().context("failed to get user")?;
let gb_repository = gb_repository::Repository::open(
&local_data_dir,
&project.id,
projects_storage,
users_storage,
user.as_ref(),
)
.context("failed to open repository")?;
@ -49,9 +51,14 @@ impl App {
project,
gb_repository,
sessions_db,
user,
})
}
pub fn user(&self) -> Option<&users::User> {
self.user.as_ref()
}
pub fn path(&self) -> &str {
&self.path
}

View File

@ -62,6 +62,7 @@ impl super::RunCommand for Commit {
&message,
None,
None,
app.user(),
)
.context("failed to commit")?;

View File

@ -11,7 +11,7 @@ impl super::RunCommand for Flush {
let app = App::new().context("Failed to create app")?;
println!("Flushing sessions");
app.gb_repository()
.flush()
.flush(app.user())
.context("failed to flush sessions")?;
Ok(())
}

View File

@ -39,6 +39,7 @@ impl super::RunCommand for Setup {
set_base_branch(
app.gb_repository(),
&app.project_repository(),
app.user(),
&items[index].branch().parse()?,
)
.context("failed to set target branch")?;

View File

@ -86,12 +86,16 @@ impl App {
Ok(())
}
fn gb_repository(&self, project_id: &str) -> Result<gb_repository::Repository> {
fn gb_repository(
&self,
project_id: &str,
user: Option<&users::User>,
) -> Result<gb_repository::Repository> {
gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.projects_storage.clone(),
self.users_storage.clone(),
user,
)
.context("failed to open repository")
}
@ -177,7 +181,7 @@ impl App {
self.local_data_dir.clone(),
id,
self.projects_storage.clone(),
self.users_storage.clone(),
self.users_storage.get()?.as_ref(),
) {
Ok(repo) => Ok(Some(repo)),
Err(gb_repository::Error::ProjectPathNotFound(_)) => Ok(None),
@ -237,8 +241,9 @@ impl App {
.get_by_project_id_id(project_id, session_id)
.context("failed to get session")?
.context("session not found")?;
let user = self.users_storage.get()?;
let gb_repo = self
.gb_repository(project_id)
.gb_repository(project_id, user.as_ref())
.context("failed to open repository")?;
let session_reader =
sessions::Reader::open(&gb_repo, &session).context("failed to open session reader")?;
@ -259,7 +264,8 @@ impl App {
pub fn fetch_from_target(&self, project_id: &str) -> Result<(), Error> {
let project = self.gb_project(project_id)?;
let project_repository = project_repository::Repository::open(&project)?;
let gb_repo = self.gb_repository(project_id)?;
let user = self.users_storage.get()?;
let gb_repo = self.gb_repository(project_id, user.as_ref())?;
let current_session = gb_repo.get_or_create_current_session()?;
let current_session_reader = sessions::Reader::open(&gb_repo, &current_session)?;
let target_reader = target::Reader::new(&current_session_reader);
@ -292,7 +298,8 @@ impl App {
}
pub fn upsert_bookmark(&self, bookmark: &bookmarks::Bookmark) -> Result<()> {
let gb_repository = self.gb_repository(&bookmark.project_id)?;
let user = self.users_storage.get()?;
let gb_repository = self.gb_repository(&bookmark.project_id, user.as_ref())?;
let writer = bookmarks::Writer::new(&gb_repository).context("failed to open writer")?;
writer.write(bookmark).context("failed to write bookmark")?;
@ -403,7 +410,8 @@ impl App {
&self,
project_id: &str,
) -> Result<Vec<virtual_branches::RemoteBranch>> {
let gb_repository = self.gb_repository(project_id)?;
let user = self.users_storage.get()?;
let gb_repository = self.gb_repository(project_id, user.as_ref())?;
let project = self.gb_project(project_id)?;
let project_repository = project_repository::Repository::open(&project)
.context("failed to open project repository")?;
@ -440,8 +448,9 @@ impl App {
}
pub fn git_gb_push(&self, project_id: &str) -> Result<()> {
let gb_repository = self.gb_repository(project_id)?;
gb_repository.push()
let user = self.users_storage.get()?;
let gb_repository = self.gb_repository(project_id, user.as_ref())?;
gb_repository.push(user.as_ref())
}
pub fn search(&self, query: &search::Query) -> Result<search::Results> {

View File

@ -22,7 +22,7 @@ impl<'reader> BookmarksReader<'reader> {
pub fn read(&self) -> Result<Vec<Bookmark>> {
match self
.session_reader
.read(&path::Path::new("session/bookmarks.jsonl").to_path_buf())
.read(path::Path::new("session/bookmarks.jsonl"))
{
Ok(reader::Content::UTF8(content)) => {
let iter = JsonLinesReader::new(content.as_bytes()).read_all::<Bookmark>();

View File

@ -45,7 +45,7 @@ impl<'reader> DeltasReader<'reader> {
let mut result = HashMap::new();
for file_path in files {
if let Some(paths) = paths.as_ref() {
if !paths.into_iter().any(|path| file_path.eq(path)) {
if !paths.iter().any(|path| file_path.eq(path)) {
continue;
}
}

View File

@ -65,26 +65,21 @@ impl<'writer> DeltasWriter<'writer> {
mod tests {
use std::vec;
use crate::{deltas, projects, sessions, test_utils, users};
use crate::{
deltas, sessions,
test_utils::{Case, Suite},
};
use super::*;
#[test]
fn write_no_vbranches() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let deltas_writer = DeltasWriter::new(&gb_repo);
let deltas_writer = DeltasWriter::new(&gb_repository);
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let path = "test.txt";

View File

@ -25,7 +25,6 @@ use crate::{
pub struct Repository {
pub project_id: String,
project_store: projects::Storage,
users_store: users::Storage,
pub git_repository: git::Repository,
lock_file: std::fs::File,
}
@ -47,7 +46,7 @@ impl Repository {
root: P,
project_id: &str,
project_store: projects::Storage,
users_store: users::Storage,
user: Option<&users::User>,
) -> Result<Self, Error> {
let project = project_store
.get_project(project_id)
@ -80,7 +79,6 @@ impl Repository {
project_id: project_id.to_string(),
git_repository,
project_store,
users_store,
lock_file: File::create(lock_path).context("failed to create lock file")?,
})
} else {
@ -101,7 +99,6 @@ impl Repository {
project_id: project_id.to_string(),
git_repository,
project_store,
users_store,
lock_file: File::create(lock_path).context("failed to create lock file")?,
};
@ -119,7 +116,11 @@ impl Repository {
drop(_lock);
gb_repository
.flush_session(&project_repository::Repository::open(&project)?, &session)
.flush_session(
&project_repository::Repository::open(&project)?,
&session,
user,
)
.context("failed to run initial flush")?;
Result::Ok(gb_repository)
@ -130,12 +131,7 @@ impl Repository {
&self.project_id
}
pub fn user(&self) -> Result<Option<users::User>> {
self.users_store.get()
}
fn remote(&self) -> Result<Option<(git::Remote, String)>> {
let user = self.users_store.get().context("failed to get user")?;
fn remote(&self, user: Option<&users::User>) -> Result<Option<(git::Remote, String)>> {
let project = self
.project_store
.get_project(&self.project_id)
@ -145,7 +141,7 @@ impl Repository {
// only push if logged in
let access_token = match user {
Some(user) => user.access_token,
Some(user) => user.access_token.clone(),
None => return Ok(None),
};
@ -168,8 +164,8 @@ impl Repository {
Ok(Some((remote, access_token)))
}
pub fn fetch(&self) -> Result<bool> {
let (mut remote, access_token) = match self.remote()? {
pub fn fetch(&self, user: Option<&users::User>) -> Result<bool> {
let (mut remote, access_token) = match self.remote(user)? {
Some((remote, access_token)) => (remote, access_token),
None => return Ok(false),
};
@ -216,8 +212,8 @@ impl Repository {
Ok(true)
}
pub fn push(&self) -> Result<()> {
let (mut remote, access_token) = match self.remote()? {
pub fn push(&self, user: Option<&users::User>) -> Result<()> {
let (mut remote, access_token) = match self.remote(user)? {
Some((remote, access_token)) => (remote, access_token),
None => return Ok(()),
};
@ -406,7 +402,7 @@ impl Repository {
}
}
pub fn flush(&self) -> Result<Option<sessions::Session>> {
pub fn flush(&self, user: Option<&users::User>) -> Result<Option<sessions::Session>> {
let current_session = self
.get_current_session()
.context("failed to get current session")?;
@ -427,6 +423,7 @@ impl Repository {
let current_session = self.flush_session(
&project_repository::Repository::open(&project)?,
&current_session,
user,
)?;
Ok(Some(current_session))
}
@ -435,6 +432,7 @@ impl Repository {
&self,
project_repository: &project_repository::Repository,
session: &sessions::Session,
user: Option<&users::User>,
) -> Result<sessions::Session> {
if session.hash.is_some() {
return Ok(session.clone());
@ -474,10 +472,8 @@ impl Repository {
let tree_id = tree_builder.write().context("failed to write tree")?;
let user = self.users_store.get().context("failed to get user")?;
let commit_oid =
write_gb_commit(tree_id, self, &user).context("failed to write gb commit")?;
write_gb_commit(tree_id, self, user).context("failed to write gb commit")?;
tracing::info!(
project_id = self.project_id,
@ -1062,7 +1058,7 @@ fn add_file_to_index(
fn write_gb_commit(
tree_id: git::Oid,
gb_repository: &Repository,
user: &Option<users::User>,
user: Option<&users::User>,
) -> Result<git::Oid> {
let comitter = git::Signature::now("gitbutler", "gitbutler@localhost")?;
let author = match user {

View File

@ -1,9 +1,13 @@
use std::{path, thread, time};
use std::{collections::HashMap, path, thread, time};
use crate::{deltas, gb_repository, projects, reader, sessions, test_utils, users};
use anyhow::Result;
use tempfile::tempdir;
use crate::{
deltas, projects, reader, sessions,
test_utils::{Case, Suite},
};
fn remote_repository() -> Result<git2::Repository> {
let path = tempdir()?.path().to_str().unwrap().to_string();
let repository = git2::Repository::init_bare(path)?;
@ -12,18 +16,10 @@ fn remote_repository() -> Result<git2::Repository> {
#[test]
fn test_get_current_session_writer_should_use_existing_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let current_session_1 = gb_repo.get_or_create_current_session()?;
let current_session_2 = gb_repo.get_or_create_current_session()?;
let current_session_1 = gb_repository.get_or_create_current_session()?;
let current_session_2 = gb_repository.get_or_create_current_session()?;
assert_eq!(current_session_1.id, current_session_2.id);
Ok(())
@ -31,19 +27,11 @@ fn test_get_current_session_writer_should_use_existing_session() -> Result<()> {
#[test]
fn test_must_not_return_init_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
assert!(gb_repo.get_current_session()?.is_none());
assert!(gb_repository.get_current_session()?.is_none());
let iter = gb_repo.get_sessions_iterator()?;
let iter = gb_repository.get_sessions_iterator()?;
assert_eq!(iter.count(), 0);
Ok(())
@ -51,89 +39,38 @@ fn test_must_not_return_init_session() -> Result<()> {
#[test]
fn test_must_not_flush_without_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
assert!(session.is_none());
let iter = gb_repo.get_sessions_iterator()?;
let iter = gb_repository.get_sessions_iterator()?;
assert_eq!(iter.count(), 0);
Ok(())
}
#[test]
fn test_init_on_non_empty_repository() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
fn test_non_empty_repository() -> Result<()> {
let Case { gb_repository, .. } = Suite::default()
.new_case_with_files(HashMap::from([(path::PathBuf::from("test.txt"), "test")]));
std::fs::write(repository.path().parent().unwrap().join("test.txt"), "test")?;
test_utils::commit_all(&repository);
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
Ok(())
}
#[test]
fn test_flush_on_existing_repository() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
std::fs::write(repository.path().parent().unwrap().join("test.txt"), "test")?;
test_utils::commit_all(&repository);
gb_repository::Repository::open(
gb_repo_path.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
gb_repo.get_or_create_current_session()?;
gb_repo.flush()?;
gb_repository.get_or_create_current_session()?;
gb_repository.flush(None)?;
Ok(())
}
#[test]
fn test_must_flush_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
gb_repo.get_or_create_current_session()?;
gb_repository.get_or_create_current_session()?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
assert!(session.is_some());
let iter = gb_repo.get_sessions_iterator()?;
let iter = gb_repository.get_sessions_iterator()?;
assert_eq!(iter.count(), 1);
Ok(())
@ -141,18 +78,10 @@ fn test_must_flush_current_session() -> Result<()> {
#[test]
fn test_list_deltas_from_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let current_session = gb_repo.get_or_create_current_session()?;
let writer = deltas::Writer::new(&gb_repo);
let current_session = gb_repository.get_or_create_current_session()?;
let writer = deltas::Writer::new(&gb_repository);
writer.write(
"test.txt",
&vec![deltas::Delta {
@ -161,7 +90,7 @@ fn test_list_deltas_from_current_session() -> Result<()> {
}],
)?;
let session_reader = sessions::Reader::open(&gb_repo, &current_session)?;
let session_reader = sessions::Reader::open(&gb_repository, &current_session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read(None)?;
@ -182,17 +111,9 @@ fn test_list_deltas_from_current_session() -> Result<()> {
#[test]
fn test_list_deltas_from_flushed_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
"test.txt",
&vec![deltas::Delta {
@ -200,9 +121,9 @@ fn test_list_deltas_from_flushed_session() -> Result<()> {
timestamp_ms: 0,
}],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let session_reader = sessions::Reader::open(&gb_repo, &session.unwrap())?;
let session_reader = sessions::Reader::open(&gb_repository, &session.unwrap())?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read(None)?;
@ -223,26 +144,13 @@ fn test_list_deltas_from_flushed_session() -> Result<()> {
#[test]
fn test_list_files_from_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
// files are there before the session is created
std::fs::write(
repository.path().parent().unwrap().join("test.txt"),
let Case { gb_repository, .. } = Suite::default().new_case_with_files(HashMap::from([(
path::PathBuf::from("test.txt"),
"Hello World",
)?;
)]));
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let session = gb_repo.get_or_create_current_session()?;
let reader = sessions::Reader::open(&gb_repo, &session)?;
let current = gb_repository.get_or_create_current_session()?;
let reader = sessions::Reader::open(&gb_repository, &current)?;
let files = reader.files(None)?;
assert_eq!(files.len(), 1);
@ -256,27 +164,14 @@ fn test_list_files_from_current_session() -> Result<()> {
#[test]
fn test_list_files_from_flushed_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_app_data);
// files are there before the session is created
std::fs::write(
repository.path().parent().unwrap().join("test.txt"),
let Case { gb_repository, .. } = Suite::default().new_case_with_files(HashMap::from([(
path::PathBuf::from("test.txt"),
"Hello World",
)?;
)]));
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
gb_repo.get_or_create_current_session()?;
let session = gb_repo.flush()?.unwrap();
let reader = sessions::Reader::open(&gb_repo, &session)?;
gb_repository.get_or_create_current_session()?;
let session = gb_repository.flush(None)?.unwrap();
let reader = sessions::Reader::open(&gb_repository, &session)?;
let files = reader.files(None)?;
assert_eq!(files.len(), 1);
@ -302,34 +197,23 @@ fn test_remote_syncronization() -> Result<()> {
sync: true,
};
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
let gb_repos_path = tempdir()?.path().to_str().unwrap().to_string();
let user_store = users::Storage::from(&local_app_data);
user_store.set(&users::User {
name: "test".to_string(),
email: "test@email.com".to_string(),
..Default::default()
})?;
let suite = Suite::default();
let user = suite.sign_in();
// create first local project, add files, deltas and flush a session
let repository_one = test_utils::test_repository();
let project_one = projects::Project::try_from(&repository_one)?;
project_store.add_project(&projects::Project {
api: Some(api_project.clone()),
..project_one.clone()
})?;
std::fs::write(
repository_one.path().parent().unwrap().join("test.txt"),
let case_one = suite.new_case_with_files(HashMap::from([(
path::PathBuf::from("test.txt"),
"Hello World",
)?;
let gb_repo_one = gb_repository::Repository::open(
gb_repos_path.clone(),
&project_one.id,
project_store.clone(),
user_store.clone(),
)?;
let writer = deltas::Writer::new(&gb_repo_one);
)]));
suite
.projects_storage
.update_project(&projects::UpdateRequest {
id: case_one.project.id.clone(),
api: Some(api_project.clone()),
..Default::default()
})?;
let writer = deltas::Writer::new(&case_one.gb_repository);
writer.write(
"test.txt",
&vec![deltas::Delta {
@ -337,28 +221,31 @@ fn test_remote_syncronization() -> Result<()> {
timestamp_ms: 0,
}],
)?;
let session_one = gb_repo_one.flush()?.unwrap();
gb_repo_one.push().unwrap();
let session_one = case_one.gb_repository.flush(Some(&user))?.unwrap();
case_one.gb_repository.push(Some(&user)).unwrap();
// create second local project, fetch it and make sure session is there
let repository_two = test_utils::test_repository();
let project_two = projects::Project::try_from(&repository_two)?;
project_store.add_project(&projects::Project {
api: Some(api_project),
..project_two.clone()
})?;
let gb_repo_two =
gb_repository::Repository::open(gb_repos_path, &project_two.id, project_store, user_store)?;
gb_repo_two.fetch()?;
let case_two = suite.new_case();
suite
.projects_storage
.update_project(&projects::UpdateRequest {
id: case_two.project.id.clone(),
api: Some(api_project.clone()),
..Default::default()
})?;
case_two.gb_repository.fetch(Some(&user))?;
// now it should have the session from the first local project synced
let sessions_two = gb_repo_two
let sessions_two = case_two
.gb_repository
.get_sessions_iterator()?
.map(|s| s.unwrap())
.collect::<Vec<_>>();
assert_eq!(sessions_two.len(), 1);
assert_eq!(sessions_two[0].id, session_one.id);
let session_reader = sessions::Reader::open(&gb_repo_two, &sessions_two[0])?;
let session_reader = sessions::Reader::open(&case_two.gb_repository, &sessions_two[0])?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read(None)?;
let files = session_reader.files(None)?;
@ -393,90 +280,64 @@ fn test_remote_sync_order() -> Result<()> {
sync: true,
};
let local_app_data = tempdir()?.path().to_path_buf();
let project_store = projects::Storage::from(&local_app_data);
let gb_repos_path = tempdir()?.path().to_str().unwrap().to_string();
let user_store = users::Storage::from(&local_app_data);
user_store.set(&users::User {
name: "test".to_string(),
email: "test@email.com".to_string(),
..Default::default()
})?;
let suite = Suite::default();
// create first project and repo
let repository_one = test_utils::test_repository();
let project_one = projects::Project::try_from(&repository_one)?;
project_store.add_project(&projects::Project {
api: Some(api_project.clone()),
..project_one.clone()
})?;
let gb_repo_one = gb_repository::Repository::open(
gb_repos_path.clone(),
&project_one.id,
project_store.clone(),
user_store.clone(),
)?;
let case_one = suite.new_case();
suite
.projects_storage
.update_project(&projects::UpdateRequest {
id: case_one.project.id.clone(),
api: Some(api_project.clone()),
..Default::default()
})?;
// create second project and repo
let repository_two = test_utils::test_repository();
let project_two = projects::Project::try_from(&repository_two)?;
project_store.add_project(&projects::Project {
api: Some(api_project),
..project_two.clone()
})?;
let gb_repo_two =
gb_repository::Repository::open(gb_repos_path, &project_two.id, project_store, user_store)?;
let case_two = suite.new_case();
suite
.projects_storage
.update_project(&projects::UpdateRequest {
id: case_two.project.id.clone(),
api: Some(api_project.clone()),
..Default::default()
})?;
let user = suite.sign_in();
// create session in the first project
gb_repo_one.get_or_create_current_session()?;
std::fs::write(
repository_one.path().parent().unwrap().join("test.txt"),
"Hello World",
)?;
let session_one_first = gb_repo_one.flush()?.unwrap();
gb_repo_one.push().unwrap();
case_one.gb_repository.get_or_create_current_session()?;
let session_one_first = case_one.gb_repository.flush(Some(&user))?.unwrap();
case_one.gb_repository.push(Some(&user)).unwrap();
thread::sleep(time::Duration::from_secs(1));
// create session in the second project
gb_repo_two.get_or_create_current_session()?;
std::fs::write(
repository_two.path().parent().unwrap().join("test2.txt"),
"Hello World",
)?;
let session_two_first = gb_repo_two.flush()?.unwrap();
gb_repo_two.push().unwrap();
case_two.gb_repository.get_or_create_current_session()?;
let session_two_first = case_two.gb_repository.flush(Some(&user))?.unwrap();
case_two.gb_repository.push(Some(&user)).unwrap();
thread::sleep(time::Duration::from_secs(1));
// create second session in the first project
gb_repo_one.get_or_create_current_session()?;
std::fs::write(
repository_one.path().parent().unwrap().join("test.txt"),
"Hello World again",
)?;
let session_one_second = gb_repo_one.flush()?.unwrap();
gb_repo_one.push().unwrap();
case_one.gb_repository.get_or_create_current_session()?;
let session_one_second = case_one.gb_repository.flush(Some(&user))?.unwrap();
case_one.gb_repository.push(Some(&user)).unwrap();
thread::sleep(time::Duration::from_secs(1));
// create second session in the second project
gb_repo_two.get_or_create_current_session()?;
std::fs::write(
repository_two.path().parent().unwrap().join("test2.txt"),
"Hello World again",
)?;
let session_two_second = gb_repo_two.flush()?.unwrap();
gb_repo_two.push().unwrap();
case_two.gb_repository.get_or_create_current_session()?;
let session_two_second = case_two.gb_repository.flush(Some(&user))?.unwrap();
case_two.gb_repository.push(Some(&user)).unwrap();
gb_repo_one.fetch()?;
let sessions_one = gb_repo_one
case_one.gb_repository.fetch(Some(&user))?;
let sessions_one = case_one
.gb_repository
.get_sessions_iterator()?
.map(|s| s.unwrap())
.collect::<Vec<_>>();
gb_repo_two.fetch()?;
let sessions_two = gb_repo_two
case_two.gb_repository.fetch(Some(&user))?;
let sessions_two = case_two
.gb_repository
.get_sessions_iterator()?
.map(|s| s.unwrap())
.collect::<Vec<_>>();

View File

@ -46,12 +46,10 @@ impl Config {
mod tests {
use crate::test_utils;
use super::*;
#[test]
pub fn test_set_str() {
let repo = test_utils::test_repository();
let mut config = Config::from(repo.config().unwrap());
let mut config = repo.config().unwrap();
config.set_str("test.key", "test.value").unwrap();
assert_eq!(
config.get_string("test.key").unwrap().unwrap(),
@ -62,7 +60,7 @@ mod tests {
#[test]
pub fn test_set_bool() {
let repo = test_utils::test_repository();
let mut config = Config::from(repo.config().unwrap());
let mut config = repo.config().unwrap();
config.set_bool("test.key", true).unwrap();
assert!(config.get_bool("test.key").unwrap().unwrap());
}
@ -70,14 +68,14 @@ mod tests {
#[test]
pub fn test_get_string_none() {
let repo = test_utils::test_repository();
let config = Config::from(repo.config().unwrap());
let config = repo.config().unwrap();
assert_eq!(config.get_string("test.key").unwrap(), None);
}
#[test]
pub fn test_get_bool_none() {
let repo = test_utils::test_repository();
let config = Config::from(repo.config().unwrap());
let config = repo.config().unwrap();
assert_eq!(config.get_bool("test.key").unwrap(), None);
}
}

View File

@ -21,23 +21,23 @@ pub enum Error {
SSHKey(#[from] ssh_key::Error),
}
impl From<storage::Storage> for Storage {
fn from(storage: storage::Storage) -> Self {
Self { storage }
impl From<&storage::Storage> for Storage {
fn from(storage: &storage::Storage) -> Self {
Self {
storage: storage.clone(),
}
}
}
impl From<&AppHandle> for Storage {
fn from(handle: &AppHandle) -> Self {
Self {
storage: handle.state::<storage::Storage>().inner().clone(),
}
Self::from(handle.state::<storage::Storage>().inner())
}
}
impl From<&path::PathBuf> for Storage {
fn from(path: &path::PathBuf) -> Self {
Self::from(storage::Storage::from(path))
Self::from(&storage::Storage::from(path))
}
}

View File

@ -6,24 +6,24 @@ use walkdir::WalkDir;
use crate::{git, keys, project_repository::activity, projects, reader, users};
pub struct Repository<'repository> {
pub struct Repository {
pub git_repository: git::Repository,
project: &'repository projects::Project,
project: projects::Project,
}
impl<'project> TryFrom<&'project projects::Project> for Repository<'project> {
impl TryFrom<&projects::Project> for Repository {
type Error = git::Error;
fn try_from(project: &'project projects::Project) -> std::result::Result<Self, Self::Error> {
fn try_from(project: &projects::Project) -> std::result::Result<Self, Self::Error> {
let git_repository = git::Repository::open(&project.path)?;
Ok(Self {
git_repository,
project,
project: project.clone(),
})
}
}
impl<'repository> Repository<'repository> {
impl Repository {
pub fn path(&self) -> &path::Path {
path::Path::new(&self.project.path)
}
@ -39,17 +39,13 @@ impl<'repository> Repository<'repository> {
super::signatures::signatures(self, user).context("failed to get signatures")
}
pub fn open(project: &'repository projects::Project) -> Result<Self> {
let git_repository = git::Repository::open(&project.path)
.with_context(|| format!("{}: failed to open git repository", project.path))?;
Ok(Self {
git_repository,
project,
})
pub fn open(project: &projects::Project) -> Result<Self> {
Self::try_from(project)
.with_context(|| format!("{}: failed to open git repository", project.path))
}
pub fn project(&self) -> &projects::Project {
self.project
&self.project
}
pub fn get_head(&self) -> Result<git::Reference, git::Error> {
@ -330,7 +326,7 @@ impl<'repository> Repository<'repository> {
// returns a remote and makes sure that the push url is an ssh url
// if url is already ssh, or not set at all, then it returns the remote as is.
fn get_remote(&'repository self, name: &str) -> Result<git::Remote<'repository>, Error> {
fn get_remote(&self, name: &str) -> Result<git::Remote, Error> {
let remote = self
.git_repository
.find_remote(name)

View File

@ -13,23 +13,23 @@ pub struct Storage {
storage: storage::Storage,
}
impl From<storage::Storage> for Storage {
fn from(storage: storage::Storage) -> Self {
Storage { storage }
impl From<&storage::Storage> for Storage {
fn from(storage: &storage::Storage) -> Self {
Storage {
storage: storage.clone(),
}
}
}
impl From<&path::PathBuf> for Storage {
fn from(value: &path::PathBuf) -> Self {
Self::from(storage::Storage::from(value))
Self::from(&storage::Storage::from(value))
}
}
impl From<&AppHandle> for Storage {
fn from(value: &AppHandle) -> Self {
Self {
storage: value.state::<storage::Storage>().inner().clone(),
}
Self::from(value.state::<storage::Storage>().inner())
}
}

View File

@ -2,23 +2,18 @@ use std::{path::Path, time};
use anyhow::Result;
use crate::{bookmarks, deltas, gb_repository, projects, test_utils, users};
use crate::{
bookmarks, deltas,
test_utils::{self, Case, Suite},
};
#[test]
fn test_sorted_by_timestamp() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![
@ -32,15 +27,15 @@ fn test_sorted_by_timestamp() -> Result<()> {
},
],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let searcher = super::Searcher::try_from(&index_path).unwrap();
let write_result = searcher.index_session(&gb_repo, &session.unwrap());
let write_result = searcher.index_session(&gb_repository, &session.unwrap());
assert!(write_result.is_ok());
let search_result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "hello".to_string(),
limit: 10,
offset: None,
@ -56,19 +51,11 @@ fn test_sorted_by_timestamp() -> Result<()> {
#[test]
fn search_by_bookmark_note() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![deltas::Delta {
@ -76,13 +63,13 @@ fn search_by_bookmark_note() -> Result<()> {
timestamp_ms: 123456,
}],
)?;
let session = gb_repo.flush()?.unwrap();
let session = gb_repository.flush(None)?.unwrap();
let searcher = super::Searcher::try_from(&index_path).unwrap();
// first we index bookmark
searcher.index_bookmark(&bookmarks::Bookmark {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
timestamp_ms: 123456,
created_timestamp_ms: 0,
updated_timestamp_ms: time::UNIX_EPOCH.elapsed()?.as_millis(),
@ -91,7 +78,7 @@ fn search_by_bookmark_note() -> Result<()> {
})?;
// and should not be able to find it before delta on the same timestamp is indexed
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "bookmark".to_string(),
limit: 10,
offset: None,
@ -99,11 +86,11 @@ fn search_by_bookmark_note() -> Result<()> {
assert_eq!(result.total, 0);
// then index session with deltas
searcher.index_session(&gb_repo, &session)?;
searcher.index_session(&gb_repository, &session)?;
// delta should be found by diff
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "hello".to_string(),
limit: 10,
offset: None,
@ -112,7 +99,7 @@ fn search_by_bookmark_note() -> Result<()> {
// and by note
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "bookmark".to_string(),
limit: 10,
offset: None,
@ -121,7 +108,7 @@ fn search_by_bookmark_note() -> Result<()> {
// then update the note
searcher.index_bookmark(&bookmarks::Bookmark {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
timestamp_ms: 123456,
created_timestamp_ms: 0,
updated_timestamp_ms: time::UNIX_EPOCH.elapsed()?.as_millis(),
@ -131,7 +118,7 @@ fn search_by_bookmark_note() -> Result<()> {
// should be able to find it by diff still
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "hello".to_string(),
limit: 10,
offset: None,
@ -140,7 +127,7 @@ fn search_by_bookmark_note() -> Result<()> {
// and by new note
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "updated bookmark".to_string(),
limit: 10,
offset: None,
@ -152,19 +139,11 @@ fn search_by_bookmark_note() -> Result<()> {
#[test]
fn search_by_full_match() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![deltas::Delta {
@ -172,16 +151,16 @@ fn search_by_full_match() -> Result<()> {
timestamp_ms: 0,
}],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let session = session.unwrap();
let searcher = super::Searcher::try_from(&index_path).unwrap();
let write_result = searcher.index_session(&gb_repo, &session);
let write_result = searcher.index_session(&gb_repository, &session);
assert!(write_result.is_ok());
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "hello world".to_string(),
limit: 10,
offset: None,
@ -193,19 +172,11 @@ fn search_by_full_match() -> Result<()> {
#[test]
fn search_by_diff() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![
@ -219,23 +190,23 @@ fn search_by_diff() -> Result<()> {
},
],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let session = session.unwrap();
let searcher = super::Searcher::try_from(&index_path).unwrap();
let write_result = searcher.index_session(&gb_repo, &session);
let write_result = searcher.index_session(&gb_repository, &session);
assert!(write_result.is_ok());
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "world".to_string(),
limit: 10,
offset: None,
})?;
assert_eq!(result.total, 1);
assert_eq!(result.page[0].session_id, session.id);
assert_eq!(result.page[0].project_id, gb_repo.get_project_id());
assert_eq!(result.page[0].project_id, gb_repository.get_project_id());
assert_eq!(result.page[0].file_path, "test.txt");
assert_eq!(result.page[0].index, 1);
@ -312,19 +283,11 @@ fn should_index_bookmark_once() -> Result<()> {
#[test]
fn test_delete_all() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![
@ -342,14 +305,14 @@ fn test_delete_all() -> Result<()> {
},
],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let searcher = super::Searcher::try_from(&index_path).unwrap();
searcher.index_session(&gb_repo, &session.unwrap())?;
searcher.index_session(&gb_repository, &session.unwrap())?;
searcher.delete_all_data()?;
let search_result_from = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "test.txt".to_string(),
limit: 10,
offset: None,
@ -361,19 +324,11 @@ fn test_delete_all() -> Result<()> {
#[test]
fn search_bookmark_by_phrase() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![deltas::Delta {
@ -381,14 +336,14 @@ fn search_bookmark_by_phrase() -> Result<()> {
timestamp_ms: 0,
}],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let session = session.unwrap();
let searcher = super::Searcher::try_from(&index_path).unwrap();
searcher.index_session(&gb_repo, &session)?;
searcher.index_session(&gb_repository, &session)?;
searcher.index_bookmark(&bookmarks::Bookmark {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
timestamp_ms: 0,
created_timestamp_ms: 0,
updated_timestamp_ms: time::UNIX_EPOCH.elapsed()?.as_millis(),
@ -397,7 +352,7 @@ fn search_bookmark_by_phrase() -> Result<()> {
})?;
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "bookmark note".to_string(),
limit: 10,
offset: None,
@ -405,7 +360,7 @@ fn search_bookmark_by_phrase() -> Result<()> {
assert_eq!(result.total, 0);
let result = searcher.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "text note".to_string(),
limit: 10,
offset: None,
@ -417,19 +372,11 @@ fn search_bookmark_by_phrase() -> Result<()> {
#[test]
fn search_by_filename() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let user_store = users::Storage::from(&local_data_dir);
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let index_path = test_utils::temp_dir();
let writer = deltas::Writer::new(&gb_repo);
let writer = deltas::Writer::new(&gb_repository);
writer.write(
Path::new("test.txt"),
&vec![
@ -443,16 +390,16 @@ fn search_by_filename() -> Result<()> {
},
],
)?;
let session = gb_repo.flush()?;
let session = gb_repository.flush(None)?;
let session = session.unwrap();
let searcher = super::Searcher::try_from(&index_path).unwrap();
searcher.index_session(&gb_repo, &session)?;
searcher.index_session(&gb_repository, &session)?;
let found_result = searcher
.search(&super::Query {
project_id: gb_repo.get_project_id().to_string(),
project_id: gb_repository.get_project_id().to_string(),
q: "test.txt".to_string(),
limit: 10,
offset: None,
@ -460,7 +407,7 @@ fn search_by_filename() -> Result<()> {
.page;
assert_eq!(found_result.len(), 2);
assert_eq!(found_result[0].session_id, session.id);
assert_eq!(found_result[0].project_id, gb_repo.get_project_id());
assert_eq!(found_result[0].project_id, gb_repository.get_project_id());
assert_eq!(found_result[0].file_path, "test.txt");
let not_found_result = searcher.search(&super::Query {

View File

@ -1,24 +1,15 @@
use anyhow::Result;
use crate::{
gb_repository,
projects::{self, Project},
sessions, test_utils, users,
sessions,
test_utils::{Case, Suite},
};
use super::Writer;
#[test]
fn test_should_not_write_session_with_hash() -> Result<()> {
let repository = test_utils::test_repository();
let project = Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = sessions::Session {
id: "session_id".to_string(),
@ -31,22 +22,14 @@ fn test_should_not_write_session_with_hash() -> Result<()> {
},
};
assert!(Writer::new(&gb_repo).write(&session).is_err());
assert!(Writer::new(&gb_repository).write(&session).is_err());
Ok(())
}
#[test]
fn test_should_write_full_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = sessions::Session {
id: "session_id".to_string(),
@ -59,26 +42,26 @@ fn test_should_write_full_session() -> Result<()> {
},
};
Writer::new(&gb_repo).write(&session)?;
Writer::new(&gb_repository).write(&session)?;
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/id"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/id"))?,
"session_id"
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/commit"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/commit"))?,
"commit"
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/branch"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/branch"))?,
"branch"
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/start"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/start"))?,
"0"
);
assert_ne!(
std::fs::read_to_string(gb_repo.session_path().join("meta/last"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/last"))?,
"1"
);
@ -87,15 +70,7 @@ fn test_should_write_full_session() -> Result<()> {
#[test]
fn test_should_write_partial_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = sessions::Session {
id: "session_id".to_string(),
@ -108,20 +83,20 @@ fn test_should_write_partial_session() -> Result<()> {
},
};
Writer::new(&gb_repo).write(&session)?;
Writer::new(&gb_repository).write(&session)?;
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/id"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/id"))?,
"session_id"
);
assert!(!gb_repo.session_path().join("meta/commit").exists());
assert!(!gb_repo.session_path().join("meta/branch").exists());
assert!(!gb_repository.session_path().join("meta/commit").exists());
assert!(!gb_repository.session_path().join("meta/branch").exists());
assert_eq!(
std::fs::read_to_string(gb_repo.session_path().join("meta/start"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/start"))?,
"0"
);
assert_ne!(
std::fs::read_to_string(gb_repo.session_path().join("meta/last"))?,
std::fs::read_to_string(gb_repository.session_path().join("meta/last"))?,
"1"
);

View File

@ -1,8 +1,91 @@
use std::{fs, path};
use std::{collections::HashMap, fs, path};
use tempfile::tempdir;
use crate::{database, git};
use crate::{database, gb_repository, git, keys, project_repository, projects, storage, users};
pub struct Suite {
pub local_app_data: path::PathBuf,
pub user_storage: users::Storage,
pub projects_storage: projects::Storage,
pub keys_storage: keys::Storage,
}
impl Default for Suite {
fn default() -> Self {
let local_app_data = temp_dir();
let storage = storage::Storage::from(&local_app_data);
let user_storage = users::Storage::from(&storage);
let projects_storage = projects::Storage::from(&storage);
let keys_storage = keys::Storage::from(&storage);
Self {
local_app_data,
user_storage,
projects_storage,
keys_storage,
}
}
}
impl Suite {
pub fn sign_in(&self) -> users::User {
let user = users::User {
name: "test".to_string(),
email: "test@email.com".to_string(),
..Default::default()
};
self.user_storage.set(&user).expect("failed to add user");
user
}
pub fn new_case_with_files(&self, fs: HashMap<path::PathBuf, &str>) -> Case {
let repository = test_repository();
for (path, contents) in fs {
if let Some(parent) = path.parent() {
fs::create_dir_all(repository.path().parent().unwrap().join(parent))
.expect("failed to create dir");
}
fs::write(
repository.path().parent().unwrap().join(&path),
contents.as_bytes(),
)
.expect("failed to write file");
}
commit_all(&repository);
self.case_from_repository(repository)
}
pub fn new_case(&self) -> Case {
self.new_case_with_files(HashMap::new())
}
fn case_from_repository(&self, repository: git::Repository) -> Case {
let project = projects::Project::try_from(&repository).expect("failed to create project");
self.projects_storage
.add_project(&project)
.expect("failed to add project");
let project_repository = project_repository::Repository::try_from(&project)
.expect("failed to create project repository");
let gb_repository = gb_repository::Repository::open(
&self.local_app_data,
&project.id,
self.projects_storage.clone(),
None,
)
.expect("failed to open gb repository");
Case {
project_repository,
project,
gb_repository,
}
}
}
pub struct Case {
pub project_repository: project_repository::Repository,
pub gb_repository: gb_repository::Repository,
pub project: projects::Project,
}
pub fn test_database() -> database::Database {
let path = temp_dir().join("test.db");

View File

@ -18,21 +18,23 @@ pub enum Error {
Storage(#[from] storage::Error),
}
impl From<storage::Storage> for Storage {
fn from(storage: storage::Storage) -> Self {
Self { storage }
}
}
impl From<&path::PathBuf> for Storage {
fn from(path: &path::PathBuf) -> Self {
Self::from(storage::Storage::from(path))
impl From<&storage::Storage> for Storage {
fn from(storage: &storage::Storage) -> Self {
Self {
storage: storage.clone(),
}
}
}
impl From<&AppHandle> for Storage {
fn from(value: &AppHandle) -> Self {
Self::from(value.state::<storage::Storage>().inner().clone())
Self::from(value.state::<storage::Storage>().inner())
}
}
impl From<&path::PathBuf> for Storage {
fn from(path: &path::PathBuf) -> Self {
Self::from(&storage::Storage::from(path))
}
}

View File

@ -8,7 +8,7 @@ use crate::{
gb_repository,
git::{self, diff},
project_repository::{self, LogUntil},
reader, sessions,
reader, sessions, users,
};
use super::{branch, delete_branch, iterator, target, RemoteCommit};
@ -42,6 +42,7 @@ pub fn get_base_branch_data(
pub fn set_base_branch(
gb_repository: &gb_repository::Repository,
project_repository: &project_repository::Repository,
user: Option<&users::User>,
target_branch: &git::RemoteBranchName,
) -> Result<super::BaseBranch> {
let repo = &project_repository.git_repository;
@ -109,6 +110,7 @@ pub fn set_base_branch(
project_repository,
&head_name,
Some(true),
user,
)?;
if branch.ownership.is_empty() && branch.head == target.sha {
delete_branch(gb_repository, project_repository, &branch.id)?;
@ -140,6 +142,7 @@ fn set_exclude_decoration(project_repository: &project_repository::Repository) -
pub fn update_base_branch(
gb_repository: &gb_repository::Repository,
project_repository: &project_repository::Repository,
user: Option<&users::User>,
) -> Result<()> {
let current_session = gb_repository
.get_or_create_current_session()
@ -223,8 +226,7 @@ pub fn update_base_branch(
};
let branch_tree = repo.find_tree(tree_oid)?;
let user = gb_repository.user()?;
let (author, committer) = project_repository.git_signatures(user.as_ref())?;
let (author, committer) = project_repository.git_signatures(user)?;
// check for conflicts with this tree
let mut merge_index = repo
@ -496,6 +498,7 @@ pub fn create_virtual_branch_from_branch(
project_repository: &project_repository::Repository,
upstream: &git::BranchName,
applied: Option<bool>,
user: Option<&users::User>,
) -> Result<branch::Branch> {
let current_session = gb_repository
.get_or_create_current_session()
@ -568,8 +571,7 @@ pub fn create_virtual_branch_from_branch(
if merge_index.has_conflicts() {
bail!("merge conflict");
} else {
let user = gb_repository.user()?;
let (author, committer) = project_repository.git_signatures(user.as_ref())?;
let (author, committer) = project_repository.git_signatures(user)?;
let new_head_tree_oid = merge_index
.write_tree_to(repo)
.context("failed to write merge tree")?;

View File

@ -36,7 +36,9 @@ mod tests {
use anyhow::Result;
use crate::{
gb_repository, projects, sessions, test_utils, users, virtual_branches::branch::Ownership,
sessions,
test_utils::{Case, Suite},
virtual_branches::branch::Ownership,
};
use super::{super::Writer, *};
@ -80,18 +82,10 @@ mod tests {
#[test]
fn test_read_not_found() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let reader = BranchReader::new(&session_reader);
let result = reader.read("not found");
@ -103,23 +97,15 @@ mod tests {
#[test]
fn test_read_override() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let writer = Writer::new(&gb_repo);
let writer = Writer::new(&gb_repository);
writer.write(&branch)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let reader = BranchReader::new(&session_reader);

View File

@ -106,7 +106,10 @@ impl<'writer> BranchWriter<'writer> {
mod tests {
use std::fs;
use crate::{projects, test_utils, users, virtual_branches::branch};
use crate::{
test_utils::{Case, Suite},
virtual_branches::branch,
};
use super::*;
@ -150,22 +153,14 @@ mod tests {
#[test]
fn test_write_branch() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let writer = BranchWriter::new(&gb_repo);
let writer = BranchWriter::new(&gb_repository);
writer.write(&branch)?;
let root = gb_repo.root().join("branches").join(&branch.id);
let root = gb_repository.root().join("branches").join(&branch.id);
assert_eq!(
fs::read_to_string(root.join("meta").join("name").to_str().unwrap())
@ -216,41 +211,25 @@ mod tests {
#[test]
fn test_should_create_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let writer = BranchWriter::new(&gb_repo);
let writer = BranchWriter::new(&gb_repository);
writer.write(&branch)?;
assert!(gb_repo.get_current_session()?.is_some());
assert!(gb_repository.get_current_session()?.is_some());
Ok(())
}
#[test]
fn test_should_update() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let writer = BranchWriter::new(&gb_repo);
let writer = BranchWriter::new(&gb_repository);
writer.write(&branch)?;
let updated_branch = Branch {
@ -265,7 +244,7 @@ mod tests {
writer.write(&updated_branch)?;
let root = gb_repo.root().join("branches").join(&branch.id);
let root = gb_repository.root().join("branches").join(&branch.id);
assert_eq!(
fs::read_to_string(root.join("meta").join("name").to_str().unwrap())

View File

@ -71,7 +71,7 @@ impl Controller {
ownership: Option<&Ownership>,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, user| {
let signing_key = if project_repository
.config()
.sign_commits()
@ -92,6 +92,7 @@ impl Controller {
message,
ownership,
signing_key.as_ref(),
user,
)?;
Ok(())
})
@ -113,7 +114,8 @@ impl Controller {
.as_ref()
.try_into()
.context("failed to open project repository")?;
let gb_repository = self.open_gb_repository(project_id)?;
let user = self.users_storage.get().context("failed to get user")?;
let gb_repository = self.open_gb_repository(project_id, user.as_ref())?;
super::is_remote_branch_mergeable(&gb_repository, &project_repository, branch_name)
.map_err(Error::Other)
}
@ -132,7 +134,8 @@ impl Controller {
.as_ref()
.try_into()
.context("failed to open project repository")?;
let gb_repository = self.open_gb_repository(project_id)?;
let user = self.users_storage.get().context("failed to get user")?;
let gb_repository = self.open_gb_repository(project_id, user.as_ref())?;
super::is_virtual_branch_mergeable(&gb_repository, &project_repository, branch_id)
.map_err(Error::Other)
}
@ -142,7 +145,7 @@ impl Controller {
project_id: &str,
) -> Result<Vec<super::VirtualBranch>, Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::list_virtual_branches(gb_repository, project_repository)
.map_err(Error::Other)
})
@ -156,7 +159,7 @@ impl Controller {
create: &super::branch::BranchCreateRequest,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
if conflicts::is_resolving(project_repository) {
return Err(Error::Conflicting);
}
@ -173,12 +176,13 @@ impl Controller {
branch: &git::BranchName,
) -> Result<String, Error> {
self.with_lock::<Result<String, Error>>(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, user| {
let branch = super::create_virtual_branch_from_branch(
gb_repository,
project_repository,
branch,
None,
user,
)
.map_err(Error::Other)?;
@ -202,6 +206,7 @@ impl Controller {
project_repository,
&branch.id,
signing_key.as_ref(),
user,
)
.map_err(Error::Other)?;
Ok(branch.id)
@ -223,7 +228,8 @@ impl Controller {
.as_ref()
.try_into()
.context("failed to open project repository")?;
let gb_repository = self.open_gb_repository(project_id)?;
let user = self.users_storage.get().context("failed to get user")?;
let gb_repository = self.open_gb_repository(project_id, user.as_ref())?;
let base_branch = super::get_base_branch_data(&gb_repository, &project_repository)?;
if let Some(branch) = base_branch {
Ok(Some(self.proxy_base_branch(branch).await))
@ -269,9 +275,16 @@ impl Controller {
.try_into()
.context("failed to open project repository")?;
let gb_repository = self.open_gb_repository(project_id)?;
let target = super::set_base_branch(&gb_repository, &project_repository, target_branch)
.map_err(Error::Other)?;
let user = self.users_storage.get().context("failed to get user")?;
let gb_repository = self.open_gb_repository(project_id, user.as_ref())?;
let target = super::set_base_branch(
&gb_repository,
&project_repository,
user.as_ref(),
target_branch,
)
.map_err(Error::Other)?;
let current_session = gb_repository.get_current_session()?;
if let Some(session) = current_session {
@ -291,7 +304,7 @@ impl Controller {
branch: &str,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, user| {
let signing_key = if project_repository
.config()
.sign_commits()
@ -310,6 +323,7 @@ impl Controller {
project_repository,
branch,
signing_key.as_ref(),
user,
)
.map_err(Error::Other)
})
@ -319,8 +333,9 @@ impl Controller {
pub async fn update_base_branch(&self, project_id: &str) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
super::update_base_branch(gb_repository, project_repository).map_err(Error::Other)
self.with_verify_branch(project_id, |gb_repository, project_repository, user| {
super::update_base_branch(gb_repository, project_repository, user)
.map_err(Error::Other)
})
})
.await
@ -332,7 +347,7 @@ impl Controller {
branch_update: super::branch::BranchUpdateRequest,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::update_branch(gb_repository, project_repository, branch_update)?;
Ok(())
})
@ -346,7 +361,7 @@ impl Controller {
branch_id: &str,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::delete_branch(gb_repository, project_repository, branch_id)?;
Ok(())
})
@ -360,7 +375,7 @@ impl Controller {
branch_id: &str,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, user| {
let signing_key = if project_repository
.config()
.sign_commits()
@ -379,6 +394,7 @@ impl Controller {
project_repository,
branch_id,
signing_key.as_ref(),
user,
)
.map_err(Error::Other)
})
@ -392,7 +408,7 @@ impl Controller {
ownership: &Ownership,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::unapply_ownership(gb_repository, project_repository, ownership)
.map_err(Error::Other)
})
@ -406,7 +422,7 @@ impl Controller {
branch_id: &str,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
super::unapply_branch(gb_repository, project_repository, branch_id)
.map_err(Error::Other)
})
@ -420,7 +436,7 @@ impl Controller {
branch_id: &str,
) -> Result<(), Error> {
self.with_lock(project_id, || {
self.with_verify_branch(project_id, |gb_repository, project_repository| {
self.with_verify_branch(project_id, |gb_repository, project_repository, _| {
let private_key = match &project_repository.project().preferred_key {
projects::AuthKey::Local {
private_key_path,
@ -455,6 +471,7 @@ impl Controller {
action: impl FnOnce(
&gb_repository::Repository,
&project_repository::Repository,
Option<&users::User>,
) -> Result<T, Error>,
) -> Result<T, Error> {
let project = self
@ -466,7 +483,8 @@ impl Controller {
.as_ref()
.try_into()
.context("failed to open project repository")?;
let gb_repository = self.open_gb_repository(project_id)?;
let user = self.users_storage.get().context("failed to get user")?;
let gb_repository = self.open_gb_repository(project_id, user.as_ref())?;
super::integration::verify_branch(&gb_repository, &project_repository).map_err(
|e| match e {
super::integration::VerifyError::DetachedHead => Error::DetachedHead,
@ -475,7 +493,7 @@ impl Controller {
e => Error::Other(anyhow::Error::from(e)),
},
)?;
action(&gb_repository, &project_repository)
action(&gb_repository, &project_repository, user.as_ref())
}
async fn with_lock<T>(&self, project_id: &str, action: impl FnOnce() -> T) -> T {
@ -487,12 +505,16 @@ impl Controller {
action()
}
fn open_gb_repository(&self, project_id: &str) -> Result<gb_repository::Repository, Error> {
fn open_gb_repository(
&self,
project_id: &str,
user: Option<&users::User>,
) -> Result<gb_repository::Repository, Error> {
gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.projects_storage.clone(),
self.users_storage.clone(),
user,
)
.context("failed to open repository")
.map_err(Error::Other)

View File

@ -55,7 +55,11 @@ impl<'iterator> Iterator for BranchIterator<'iterator> {
mod tests {
use anyhow::Result;
use crate::{gb_repository, projects, sessions, test_utils, users, virtual_branches::target};
use crate::{
sessions,
test_utils::{Case, Suite},
virtual_branches::target,
};
use super::*;
@ -114,18 +118,10 @@ mod tests {
#[test]
fn test_empty_iterator() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let iter = BranchIterator::new(&session_reader)?;
@ -136,20 +132,12 @@ mod tests {
#[test]
fn test_iterate_all() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let target_writer = target::Writer::new(&gb_repo);
let target_writer = target::Writer::new(&gb_repository);
target_writer.write_default(&test_target())?;
let branch_writer = branch::Writer::new(&gb_repo);
let branch_writer = branch::Writer::new(&gb_repository);
let branch_1 = test_branch();
branch_writer.write(&branch_1)?;
let branch_2 = test_branch();
@ -157,8 +145,8 @@ mod tests {
let branch_3 = test_branch();
branch_writer.write(&branch_3)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let mut iter = BranchIterator::new(&session_reader)?;
assert_eq!(iter.next().unwrap().unwrap(), branch_1);

View File

@ -42,7 +42,8 @@ mod tests {
use anyhow::Result;
use crate::{
gb_repository, projects, sessions, test_utils, users,
sessions,
test_utils::{Case, Suite},
virtual_branches::{branch, target::writer::TargetWriter},
};
@ -88,18 +89,10 @@ mod tests {
#[test]
fn test_read_not_found() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_repo_path = test_utils::temp_dir();
let user_store = users::Storage::from(&local_repo_path);
let project_store = projects::Storage::from(&local_repo_path);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let reader = TargetReader::new(&session_reader);
let result = reader.read("not found");
@ -111,17 +104,9 @@ mod tests {
#[test]
fn test_read_deprecated_format() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_data_path = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_path);
let project_store = projects::Storage::from(&local_data_path);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let writer = crate::writer::DirWriter::open(gb_repo.root());
let writer = crate::writer::DirWriter::open(gb_repository.root());
writer
.write_string("branches/target/name", "origin/master")
.unwrap();
@ -138,8 +123,8 @@ mod tests {
)
.unwrap();
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let reader = TargetReader::new(&session_reader);
let read = reader.read_default().unwrap();
@ -159,15 +144,7 @@ mod tests {
#[test]
fn test_read_override_target() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_app_data = test_utils::temp_dir();
let user_store = users::Storage::from(&local_app_data);
let project_store = projects::Storage::from(&local_app_data);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
@ -185,13 +162,13 @@ mod tests {
sha: "0123456789abcdef0123456789abcdef01234567".parse().unwrap(),
};
let branch_writer = branch::Writer::new(&gb_repo);
let branch_writer = branch::Writer::new(&gb_repository);
branch_writer.write(&branch)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let target_writer = TargetWriter::new(&gb_repo);
let target_writer = TargetWriter::new(&gb_repository);
let reader = TargetReader::new(&session_reader);
target_writer.write_default(&default_target)?;

View File

@ -85,7 +85,10 @@ impl<'writer> TargetWriter<'writer> {
mod tests {
use std::fs;
use crate::{projects, test_utils, users, virtual_branches::branch};
use crate::{
test_utils::{Case, Suite},
virtual_branches::branch,
};
use super::{super::Target, *};
@ -129,15 +132,7 @@ mod tests {
#[test]
fn test_write() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_repo_path = test_utils::temp_dir();
let user_store = users::Storage::from(&local_repo_path);
let project_store = projects::Storage::from(&local_repo_path);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let target = Target {
@ -146,13 +141,13 @@ mod tests {
sha: "0123456789abcdef0123456789abcdef01234567".parse().unwrap(),
};
let branch_writer = branch::Writer::new(&gb_repo);
let branch_writer = branch::Writer::new(&gb_repository);
branch_writer.write(&branch)?;
let target_writer = TargetWriter::new(&gb_repo);
let target_writer = TargetWriter::new(&gb_repository);
target_writer.write(&branch.id, &target)?;
let root = gb_repo.root().join("branches").join(&branch.id);
let root = gb_repository.root().join("branches").join(&branch.id);
assert_eq!(
fs::read_to_string(root.join("meta").join("name").to_str().unwrap())
@ -220,15 +215,7 @@ mod tests {
#[test]
fn test_should_update() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = test_utils::temp_dir();
let local_repo_path = test_utils::temp_dir();
let user_store = users::Storage::from(&local_repo_path);
let project_store = projects::Storage::from(&local_repo_path);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, &project.id, project_store, user_store)?;
let Case { gb_repository, .. } = Suite::default().new_case();
let branch = test_branch();
let target = Target {
@ -237,9 +224,9 @@ mod tests {
sha: "0123456789abcdef0123456789abcdef01234567".parse().unwrap(),
};
let branch_writer = branch::Writer::new(&gb_repo);
let branch_writer = branch::Writer::new(&gb_repository);
branch_writer.write(&branch)?;
let target_writer = TargetWriter::new(&gb_repo);
let target_writer = TargetWriter::new(&gb_repository);
target_writer.write(&branch.id, &target)?;
let updated_target = Target {
@ -252,7 +239,7 @@ mod tests {
target_writer.write(&branch.id, &updated_target)?;
let root = gb_repo.root().join("branches").join(&branch.id);
let root = gb_repository.root().join("branches").join(&branch.id);
assert_eq!(
fs::read_to_string(root.join("target").join("branch_name").to_str().unwrap())

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ use crate::{
git::{self, diff},
keys::{self, Key},
project_repository::{self, conflicts, LogUntil},
reader, sessions,
reader, sessions, users,
};
use super::{
@ -152,6 +152,7 @@ pub fn apply_branch(
project_repository: &project_repository::Repository,
branch_id: &str,
signing_key: Option<&keys::PrivateKey>,
user: Option<&users::User>,
) -> Result<()> {
if conflicts::is_resolving(project_repository) {
bail!("cannot apply a branch, project is in a conflicted state");
@ -233,8 +234,7 @@ pub fn apply_branch(
.context("failed to find head commit")?;
// commit our new upstream merge
let user = gb_repository.user()?;
let (author, committer) = project_repository.git_signatures(user.as_ref())?;
let (author, committer) = project_repository.git_signatures(user)?;
let message = "merge upstream";
// write the merge commit
let branch_tree_oid = merge_index.write_tree_to(repo)?;
@ -939,6 +939,7 @@ pub fn merge_virtual_branch_upstream(
project_repository: &project_repository::Repository,
branch_id: &str,
signing_key: Option<&keys::PrivateKey>,
user: Option<&users::User>,
) -> Result<()> {
if conflicts::is_conflicting(project_repository, None)? {
bail!("cannot merge upstream, project is in a conflicted state");
@ -1043,8 +1044,7 @@ pub fn merge_virtual_branch_upstream(
.write_tree_to(repo)
.context("failed to write tree")?;
let user = gb_repository.user()?;
let (author, committer) = project_repository.git_signatures(user.as_ref())?;
let (author, committer) = project_repository.git_signatures(user)?;
let message = "merged from upstream";
let head_commit = repo.find_commit(branch.head)?;
@ -1288,7 +1288,7 @@ pub fn virtual_hunks_by_filepath(
// list the virtual branches and their file statuses (statusi?)
pub fn get_status_by_branch(
gb_repository: &gb_repository::Repository,
project_repository: &project_repository::Repository<'_>,
project_repository: &project_repository::Repository,
) -> Result<Vec<(branch::Branch, Vec<VirtualBranchFile>)>> {
let current_session = gb_repository
.get_or_create_current_session()
@ -1345,7 +1345,7 @@ pub fn get_status_by_branch(
//
// ownerships are not taken into account here, as they are not relevant for non applied branches
fn get_non_applied_status(
project_repository: &project_repository::Repository<'_>,
project_repository: &project_repository::Repository,
default_target: &target::Target,
virtual_branches: Vec<branch::Branch>,
) -> Result<Vec<(branch::Branch, Vec<VirtualBranchFile>)>> {
@ -1416,7 +1416,7 @@ fn get_non_applied_status(
// ownerships are updated if nessessary
fn get_applied_status(
gb_repository: &gb_repository::Repository,
project_repository: &project_repository::Repository<'_>,
project_repository: &project_repository::Repository,
default_target: &target::Target,
mut virtual_branches: Vec<branch::Branch>,
) -> Result<Vec<(branch::Branch, Vec<VirtualBranchFile>)>> {
@ -1796,6 +1796,7 @@ pub fn commit(
message: &str,
ownership: Option<&branch::Ownership>,
signing_key: Option<&keys::PrivateKey>,
user: Option<&users::User>,
) -> Result<()> {
if conflicts::is_conflicting(project_repository, None)? {
bail!("cannot commit, project is in a conflicted state");
@ -1862,8 +1863,7 @@ pub fn commit(
.context(format!("failed to find tree {:?}", tree_oid))?;
// now write a commit, using a merge parent if it exists
let user = gb_repository.user()?;
let (author, committer) = project_repository.git_signatures(user.as_ref())?;
let (author, committer) = project_repository.git_signatures(user)?;
let extra_merge_parent =
conflicts::merge_parent(project_repository).context("failed to get merge parent")?;

View File

@ -66,11 +66,13 @@ impl HandlerInner {
Err(TryLockError::WouldBlock) => return Ok(vec![]),
};
let user = self.user_storage.get()?;
let gb_repo = gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.project_storage.clone(),
self.user_storage.clone(),
user.as_ref(),
)
.context("failed to open repository")?;
@ -96,7 +98,7 @@ impl HandlerInner {
.context("failed to get project")?
.ok_or_else(|| anyhow::anyhow!("project not found"))?;
let fetch_result = if let Err(error) = gb_repo.fetch() {
let fetch_result = if let Err(error) = gb_repo.fetch(user.as_ref()) {
tracing::error!(project_id, ?error, "failed to fetch gitbutler data");
projects::FetchResult::Error {
attempt: project

View File

@ -71,11 +71,13 @@ impl HandlerInner {
Err(TryLockError::WouldBlock) => return Ok(vec![]),
};
let user = self.user_storage.get()?;
let gb_repo = gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.project_storage.clone(),
self.user_storage.clone(),
user.as_ref(),
)
.context("failed to open repository")?;

View File

@ -42,16 +42,22 @@ impl Handler {
.context("failed to get project")?
.ok_or_else(|| anyhow!("project not found"))?;
let user = self.user_store.get()?;
let gb_repo = gb_repository::Repository::open(
&self.local_data_dir,
project_id,
self.project_store.clone(),
self.user_store.clone(),
user.as_ref(),
)
.context("failed to open repository")?;
let session = gb_repo
.flush_session(&project_repository::Repository::open(&project)?, session)
.flush_session(
&project_repository::Repository::open(&project)?,
session,
user.as_ref(),
)
.context("failed to flush session")?;
Ok(vec![

View File

@ -71,11 +71,13 @@ impl Handler {
}
pub fn reindex(&self, project_id: &str) -> Result<Vec<events::Event>> {
let user = self.user_store.get()?;
let gb_repository = gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.project_store.clone(),
self.user_store.clone(),
user.as_ref(),
)
.context("failed to open repository")?;
@ -92,11 +94,13 @@ impl Handler {
project_id: &str,
session: &sessions::Session,
) -> Result<Vec<events::Event>> {
let user = self.user_store.get()?;
let gb_repository = gb_repository::Repository::open(
self.local_data_dir.clone(),
project_id,
self.project_store.clone(),
self.user_store.clone(),
user.as_ref(),
)
.context("failed to open repository")?;

View File

@ -96,11 +96,13 @@ impl Handler {
let project_repository = project_repository::Repository::open(&project)
.with_context(|| "failed to open project repository for project")?;
let user = self.user_store.get().context("failed to get user")?;
let gb_repository = gb_repository::Repository::open(
&self.local_data_dir,
project_id,
self.project_store.clone(),
self.user_store.clone(),
user.as_ref(),
)
.context("failed to open gb repository")?;
@ -114,7 +116,7 @@ impl Handler {
.context("failed to get head")?;
if session.meta.branch != project_head.name().map(|s| s.to_string()) {
gb_repository
.flush_session(&project_repository, &session)
.flush_session(&project_repository, &session, user.as_ref())
.context("failed to flush session")?;
}
}
@ -191,8 +193,11 @@ impl Handler {
#[cfg(test)]
mod test {
use std::collections::HashMap;
use crate::{
deltas, gb_repository, project_repository, projects, sessions, test_utils, users,
deltas, sessions,
test_utils::{self, Case, Suite},
virtual_branches::{self, branch},
};
@ -253,31 +258,19 @@ mod test {
#[test]
fn test_register_existing_commited_file() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case_with_files(HashMap::from([(path::PathBuf::from("test.txt"), "test")]));
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
test_utils::commit_all(&repository);
std::fs::write(format!("{}/test.txt", project.path), "test2")?;
listener.handle("test.txt", &project.id)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
std::fs::write(project_repo.root().join(file_path), "test2")?;
listener.handle(file_path, &project.id)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1);
@ -287,7 +280,7 @@ mod test {
deltas::Operation::Insert((4, "2".to_string())),
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_wd_path().join(file_path))?,
std::fs::read_to_string(gb_repository.session_wd_path().join("test.txt"))?,
"test2"
);
@ -296,58 +289,40 @@ mod test {
#[test]
fn test_register_must_init_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
std::fs::write(format!("{}/test.txt", project.path), "test")?;
listener.handle("test.txt", &project.id)?;
listener.handle(file_path, &project.id)?;
assert!(gb_repo.get_current_session()?.is_some());
assert!(gb_repository.get_current_session()?.is_some());
Ok(())
}
#[test]
fn test_register_must_not_override_current_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
listener.handle(file_path, &project.id)?;
std::fs::write(format!("{}/test.txt", project.path), "test")?;
listener.handle("test.txt", &project.id)?;
let session1 = gb_repository.get_current_session()?.unwrap();
let session1 = gb_repo.get_current_session()?.unwrap();
std::fs::write(format!("{}/test.txt", project.path), "test2")?;
listener.handle("test.txt", &project.id)?;
let session2 = gb_repository.get_current_session()?.unwrap();
std::fs::write(project_repo.root().join(file_path), "test2")?;
listener.handle(file_path, &project.id)?;
let session2 = gb_repo.get_current_session()?.unwrap();
assert_eq!(session1.id, session2.id);
Ok(())
@ -355,28 +330,20 @@ mod test {
#[test]
fn test_register_new_file() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
std::fs::write(format!("{}/test.txt", project.path), "test")?;
listener.handle(file_path, &project.id)?;
listener.handle("test.txt", &project.id)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1);
@ -386,7 +353,7 @@ mod test {
deltas::Operation::Insert((0, "test".to_string())),
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_wd_path().join(file_path))?,
std::fs::read_to_string(gb_repository.session_wd_path().join("test.txt"))?,
"test"
);
@ -395,27 +362,19 @@ mod test {
#[test]
fn test_register_new_file_twice() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
listener.handle(file_path, &project.id)?;
std::fs::write(format!("{}/test.txt", project.path), "test")?;
listener.handle("test.txt", &project.id)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1);
@ -425,12 +384,12 @@ mod test {
deltas::Operation::Insert((0, "test".to_string())),
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_wd_path().join(file_path))?,
std::fs::read_to_string(gb_repository.session_wd_path().join("test.txt"))?,
"test"
);
std::fs::write(project_repo.root().join(file_path), "test2")?;
listener.handle(file_path, &project.id)?;
std::fs::write(format!("{}/test.txt", project.path), "test2")?;
listener.handle("test.txt", &project.id)?;
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 2);
@ -445,7 +404,7 @@ mod test {
deltas::Operation::Insert((4, "2".to_string())),
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_wd_path().join(file_path))?,
std::fs::read_to_string(gb_repository.session_wd_path().join("test.txt"))?,
"test2"
);
@ -454,27 +413,19 @@ mod test {
#[test]
fn test_register_file_deleted() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "test")?;
listener.handle(file_path, &project.id)?;
std::fs::write(format!("{}/test.txt", project.path), "test")?;
listener.handle("test.txt", &project.id)?;
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session)?;
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1);
@ -484,12 +435,12 @@ mod test {
deltas::Operation::Insert((0, "test".to_string())),
);
assert_eq!(
std::fs::read_to_string(gb_repo.session_wd_path().join(file_path))?,
std::fs::read_to_string(gb_repository.session_wd_path().join("test.txt"))?,
"test"
);
std::fs::remove_file(project_repo.root().join(file_path))?;
listener.handle(file_path, &project.id)?;
std::fs::remove_file(format!("{}/test.txt", project.path))?;
listener.handle("test.txt", &project.id)?;
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 2);
@ -506,19 +457,14 @@ mod test {
#[test]
fn test_flow_with_commits() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
project_repository,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let size = 10;
let relative_file_path = std::path::Path::new("one/two/test.txt");
@ -530,13 +476,13 @@ mod test {
i.to_string(),
)?;
test_utils::commit_all(&repository);
test_utils::commit_all(&project_repository.git_repository);
listener.handle(relative_file_path, &project.id)?;
assert!(gb_repo.flush()?.is_some());
assert!(gb_repository.flush(None)?.is_some());
}
// get all the created sessions
let mut sessions: Vec<sessions::Session> = gb_repo
let mut sessions: Vec<sessions::Session> = gb_repository
.get_sessions_iterator()?
.map(|s| s.unwrap())
.collect();
@ -559,7 +505,7 @@ mod test {
// collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![];
sessions_slice.iter().for_each(|session| {
let session_reader = sessions::Reader::open(&gb_repo, session).unwrap();
let session_reader = sessions::Reader::open(&gb_repository, session).unwrap();
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() {
@ -571,7 +517,8 @@ mod test {
}
});
let reader = sessions::Reader::open(&gb_repo, sessions_slice.first().unwrap()).unwrap();
let reader =
sessions::Reader::open(&gb_repository, sessions_slice.first().unwrap()).unwrap();
let files = reader.files(None).unwrap();
if i == 0 {
@ -597,19 +544,13 @@ mod test {
#[test]
fn test_flow_no_commits() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let size = 10;
let relative_file_path = std::path::Path::new("one/two/test.txt");
@ -622,11 +563,11 @@ mod test {
)?;
listener.handle(relative_file_path, &project.id)?;
assert!(gb_repo.flush()?.is_some());
assert!(gb_repository.flush(None)?.is_some());
}
// get all the created sessions
let mut sessions: Vec<sessions::Session> = gb_repo
let mut sessions: Vec<sessions::Session> = gb_repository
.get_sessions_iterator()?
.map(|s| s.unwrap())
.collect();
@ -649,7 +590,7 @@ mod test {
// collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![];
sessions_slice.iter().for_each(|session| {
let session_reader = sessions::Reader::open(&gb_repo, session).unwrap();
let session_reader = sessions::Reader::open(&gb_repository, session).unwrap();
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() {
@ -661,7 +602,8 @@ mod test {
}
});
let reader = sessions::Reader::open(&gb_repo, sessions_slice.first().unwrap()).unwrap();
let reader =
sessions::Reader::open(&gb_repository, sessions_slice.first().unwrap()).unwrap();
let files = reader.files(None).unwrap();
if i == 0 {
@ -687,19 +629,13 @@ mod test {
#[test]
fn test_flow_signle_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case();
let listener = Handler::from(&suite.local_app_data);
let size = 10;
let relative_file_path = std::path::Path::new("one/two/test.txt");
@ -716,8 +652,8 @@ mod test {
// collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![];
let session = gb_repo.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repo, &session).unwrap();
let session = gb_repository.get_current_session()?.unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session).unwrap();
let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() {
@ -728,7 +664,7 @@ mod test {
});
}
let reader = sessions::Reader::open(&gb_repo, &session).unwrap();
let reader = sessions::Reader::open(&gb_repository, &session).unwrap();
let files = reader.files(None).unwrap();
let base_file = files.get(&relative_file_path.to_path_buf());
@ -747,28 +683,19 @@ mod test {
#[test]
fn should_persist_branches_targets_state_between_sessions() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case_with_files(HashMap::from([(
path::PathBuf::from("test.txt"),
"hello world",
)]));
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "hello world")?;
test_utils::commit_all(&repository);
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let branch_writer = virtual_branches::branch::Writer::new(&gb_repo);
let target_writer = virtual_branches::target::Writer::new(&gb_repo);
let branch_writer = virtual_branches::branch::Writer::new(&gb_repository);
let target_writer = virtual_branches::target::Writer::new(&gb_repository);
let default_target = test_target();
target_writer.write_default(&default_target)?;
let vbranch0 = test_branch();
@ -778,17 +705,17 @@ mod test {
branch_writer.write(&vbranch1)?;
target_writer.write(&vbranch1.id, &vbranch1_target)?;
std::fs::write(project_repo.root().join(file_path), "hello world!").unwrap();
listener.handle(file_path, &project.id)?;
std::fs::write(format!("{}/test.txt", project.path), "hello world!").unwrap();
listener.handle("test.txt", &project.id)?;
let flushed_session = gb_repo.flush().unwrap();
let flushed_session = gb_repository.flush(None).unwrap();
// create a new session
let session = gb_repo.get_or_create_current_session().unwrap();
let session = gb_repository.get_or_create_current_session().unwrap();
assert_ne!(session.id, flushed_session.unwrap().id);
// ensure that the virtual branch is still there and selected
let session_reader = sessions::Reader::open(&gb_repo, &session).unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session).unwrap();
let branches = virtual_branches::Iterator::new(&session_reader)
.unwrap()
@ -810,28 +737,19 @@ mod test {
#[test]
fn should_restore_branches_targets_state_from_head_session() -> Result<()> {
let repository = test_utils::test_repository();
let project = projects::Project::try_from(&repository)?;
let project_repo = project_repository::Repository::open(&project)?;
let local_data_dir = test_utils::temp_dir();
let user_store = users::Storage::from(&local_data_dir);
let project_store = projects::Storage::from(&local_data_dir);
project_store.add_project(&project)?;
let suite = Suite::default();
let Case {
gb_repository,
project,
..
} = suite.new_case_with_files(HashMap::from([(
path::PathBuf::from("test.txt"),
"hello world",
)]));
let listener = Handler::from(&suite.local_app_data);
let file_path = std::path::Path::new("test.txt");
std::fs::write(project_repo.root().join(file_path), "hello world")?;
test_utils::commit_all(&repository);
let gb_repo = gb_repository::Repository::open(
local_data_dir.clone(),
&project.id,
project_store.clone(),
user_store.clone(),
)?;
let listener = Handler::from(&local_data_dir);
let branch_writer = virtual_branches::branch::Writer::new(&gb_repo);
let target_writer = virtual_branches::target::Writer::new(&gb_repo);
let branch_writer = virtual_branches::branch::Writer::new(&gb_repository);
let target_writer = virtual_branches::target::Writer::new(&gb_repository);
let default_target = test_target();
target_writer.write_default(&default_target)?;
let vbranch0 = test_branch();
@ -841,20 +759,20 @@ mod test {
branch_writer.write(&vbranch1)?;
target_writer.write(&vbranch1.id, &vbranch1_target)?;
std::fs::write(project_repo.root().join(file_path), "hello world!").unwrap();
listener.handle(file_path, &project.id).unwrap();
std::fs::write(format!("{}/test.txt", project.path), "hello world!").unwrap();
listener.handle("test.txt", &project.id).unwrap();
let flushed_session = gb_repo.flush().unwrap();
let flushed_session = gb_repository.flush(None).unwrap();
// hard delete branches state from disk
std::fs::remove_dir_all(gb_repo.root()).unwrap();
std::fs::remove_dir_all(gb_repository.root()).unwrap();
// create a new session
let session = gb_repo.get_or_create_current_session().unwrap();
let session = gb_repository.get_or_create_current_session().unwrap();
assert_ne!(session.id, flushed_session.unwrap().id);
// ensure that the virtual branch is still there and selected
let session_reader = sessions::Reader::open(&gb_repo, &session).unwrap();
let session_reader = sessions::Reader::open(&gb_repository, &session).unwrap();
let branches = virtual_branches::Iterator::new(&session_reader)
.unwrap()

View File

@ -77,15 +77,17 @@ impl HandlerInner {
Err(TryLockError::WouldBlock) => return Ok(vec![]),
};
let user = self.user_storage.get()?;
let gb_repo = gb_repository::Repository::open(
&self.local_data_dir,
project_id,
self.project_storage.clone(),
self.user_storage.clone(),
user.as_ref(),
)
.context("failed to open repository")?;
gb_repo.push().context("failed to push")?;
gb_repo.push(user.as_ref()).context("failed to push")?;
Ok(vec![])
}

View File

@ -34,11 +34,13 @@ impl TryFrom<&AppHandle> for Handler {
impl Handler {
pub fn handle(&self, project_id: &str, now: &time::SystemTime) -> Result<Vec<events::Event>> {
let user = self.user_store.get()?;
let gb_repo = gb_repository::Repository::open(
&self.local_data_dir,
project_id,
self.project_store.clone(),
self.user_store.clone(),
user.as_ref(),
)
.context("failed to open repository")?;