Merge pull request #2968 from gitbutlerapp/Virtual-branch-4

move from lib+bin to bin, refactor tests into crate
This commit is contained in:
Josh Junon 2024-03-01 16:58:38 +01:00 committed by GitHub
commit eb3d42edb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 307 additions and 360 deletions

View File

@ -1,2 +0,0 @@
[build]
rustflags = ["--cfg", "tokio_unstable"]

View File

@ -5,14 +5,6 @@ edition = "2021"
rust-version = "1.57"
authors = ["GitButler <gitbutler@gitbutler.com>"]
[lib]
name = "gblib"
path = "src/lib.rs"
[[bin]]
name = "gitbutler-app"
path = "src/bin.rs"
[build-dependencies]
tauri-build = { version = "1.5", features = [] }

View File

@ -148,13 +148,13 @@ impl App {
Ok(head.name().unwrap().to_string())
}
pub fn git_set_global_config(&self, key: &str, value: &str) -> Result<String> {
pub fn git_set_global_config(key: &str, value: &str) -> Result<String> {
let mut config = git2::Config::open_default()?;
config.set_str(key, value)?;
Ok(value.to_string())
}
pub fn git_get_global_config(&self, key: &str) -> Result<Option<String>> {
pub fn git_get_global_config(key: &str) -> Result<Option<String>> {
let config = git2::Config::open_default()?;
let value = config.get_string(key);
match value {

View File

@ -105,8 +105,7 @@ pub async fn git_set_global_config(
key: &str,
value: &str,
) -> Result<String, Error> {
let app = handle.state::<app::App>();
let result = app.git_set_global_config(key, value)?;
let result = app::App::git_set_global_config(key, value)?;
Ok(result)
}
@ -116,8 +115,7 @@ pub async fn git_get_global_config(
handle: tauri::AppHandle,
key: &str,
) -> Result<Option<String>, Error> {
let app = handle.state::<app::App>();
let result = app.git_get_global_config(key)?;
let result = app::App::git_get_global_config(key)?;
Ok(result)
}

View File

@ -74,13 +74,13 @@ impl Database {
#[cfg(test)]
mod tests {
use crate::test_utils;
use crate::tests;
use super::*;
#[test]
fn smoke() {
let data_dir = test_utils::temp_dir();
let data_dir = tests::temp_dir();
let db = Database::try_from(&data_dir).unwrap();
db.transaction(|tx| {
tx.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)", [])

View File

@ -138,13 +138,13 @@ fn insert_stmt<'conn>(
#[cfg(test)]
mod tests {
use crate::test_utils;
use crate::tests;
use super::*;
#[test]
fn insert_query() -> Result<()> {
let db = test_utils::test_database();
let db = tests::test_database();
let database = Database::new(db);
let project_id = ProjectId::generate();
@ -170,7 +170,7 @@ mod tests {
#[test]
fn insert_update() -> Result<()> {
let db = test_utils::test_database();
let db = tests::test_database();
let database = Database::new(db);
let project_id = ProjectId::generate();
@ -203,7 +203,7 @@ mod tests {
#[test]
fn aggregate_deltas_by_file() -> Result<()> {
let db = test_utils::test_database();
let db = tests::test_database();
let database = Database::new(db);
let project_id = ProjectId::generate();

View File

@ -77,7 +77,7 @@ mod tests {
use crate::{
deltas, sessions,
test_utils::{Case, Suite},
tests::{Case, Suite},
};
use super::*;

View File

@ -67,8 +67,8 @@ pub mod gb {
}
#[inline]
pub fn context(&self) -> Option<&Context> {
Some(&self.context)
pub fn context(&self) -> &Context {
&self.context
}
pub(crate) fn into_owned(self) -> (ErrorKind, Context) {
@ -175,10 +175,7 @@ pub mod gb {
let r = app_level_io();
assert!(r.is_err());
let e = r.unwrap_err();
assert_eq!(
e.context().unwrap().vars.get("foo"),
Some(&"bar".to_string())
);
assert_eq!(e.context().vars.get("foo"), Some(&"bar".to_string()));
assert!(e.source().is_none());
assert!(e.to_string().starts_with("io.other-error:"));
}

View File

@ -969,7 +969,7 @@ mod test {
use anyhow::Result;
use pretty_assertions::assert_eq;
use crate::test_utils::{Case, Suite};
use crate::tests::{Case, Suite};
#[test]
fn test_alternates_file_being_set() -> Result<()> {

View File

@ -8,7 +8,7 @@ use crate::{
projects::{self, ProjectId},
reader,
sessions::{self, SessionId},
test_utils::{Case, Suite},
tests::{Case, Suite},
};
fn test_remote_repository() -> Result<git2::Repository> {

View File

@ -50,11 +50,11 @@ impl Config {
#[cfg(test)]
mod tests {
use crate::test_utils;
use crate::tests;
#[test]
pub fn test_set_str() {
let repo = test_utils::test_repository();
let repo = tests::test_repository();
let mut config = repo.config().unwrap();
config.set_str("test.key", "test.value").unwrap();
assert_eq!(
@ -65,7 +65,7 @@ mod tests {
#[test]
pub fn test_set_bool() {
let repo = test_utils::test_repository();
let repo = tests::test_repository();
let mut config = repo.config().unwrap();
config.set_bool("test.key", true).unwrap();
assert!(config.get_bool("test.key").unwrap().unwrap());
@ -73,14 +73,14 @@ mod tests {
#[test]
pub fn test_get_string_none() {
let repo = test_utils::test_repository();
let repo = tests::test_repository();
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 repo = tests::test_repository();
let config = repo.config().unwrap();
assert_eq!(config.get_bool("test.key").unwrap(), None);
}

View File

@ -417,7 +417,7 @@ impl Helper {
mod tests {
use super::*;
use crate::test_utils::{self, test_repository};
use crate::tests::{self, test_repository};
#[derive(Default)]
struct TestCase<'a> {
@ -429,7 +429,7 @@ mod tests {
impl TestCase<'_> {
fn run(&self) -> Vec<(String, Vec<Credential>)> {
let local_app_data = test_utils::temp_dir();
let local_app_data = tests::temp_dir();
let users = users::Controller::try_from(&local_app_data).unwrap();
let user = users::User {

View File

@ -331,13 +331,13 @@ pub fn reverse_hunk(hunk: &Hunk) -> Option<Hunk> {
#[cfg(test)]
mod tests {
use crate::test_utils;
use crate::tests;
use super::*;
#[test]
fn diff_simple_text() {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(repository.workdir().unwrap().join("file"), "hello").unwrap();
let head_commit_id = repository.head().unwrap().peel_to_commit().unwrap().id();
@ -360,7 +360,7 @@ mod tests {
#[test]
fn diff_empty_file() {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(repository.workdir().unwrap().join("first"), "").unwrap();
let head_commit_id = repository.head().unwrap().peel_to_commit().unwrap().id();
@ -383,7 +383,7 @@ mod tests {
#[test]
fn diff_multiple_empty_files() {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(repository.workdir().unwrap().join("first"), "").unwrap();
std::fs::write(repository.workdir().unwrap().join("second"), "").unwrap();
@ -419,7 +419,7 @@ mod tests {
#[test]
fn diff_binary() {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(
repository.workdir().unwrap().join("image"),
[
@ -450,7 +450,7 @@ mod tests {
#[test]
fn diff_some_lines_are_binary() {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(
repository.workdir().unwrap().join("file"),
[

View File

@ -25,10 +25,6 @@ impl<'repo> Remote<'repo> {
.map_err(Into::into)
}
pub fn url_as_str(&self) -> Result<Option<&str>> {
Ok(self.inner.url())
}
pub fn push(
&mut self,
refspec: &[&str],

View File

@ -59,7 +59,7 @@ mod tests {
#[cfg(target_family = "unix")]
use std::os::unix::prelude::*;
use crate::test_utils::Suite;
use crate::tests::Suite;
use super::*;

View File

@ -4,7 +4,6 @@ use ssh_key::{HashAlg, LineEnding, SshSig};
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use ssh_key;
#[derive(Debug, Clone, Eq)]
pub struct PrivateKey(ssh_key::PrivateKey);

View File

@ -1,44 +0,0 @@
#![feature(error_generic_member_access)]
#![cfg_attr(target_os = "windows", feature(windows_by_handle))]
pub mod analytics;
pub mod app;
pub mod assets;
pub mod commands;
pub mod database;
pub mod dedup;
pub mod deltas;
pub mod error;
pub mod events;
pub mod fs;
pub mod gb_repository;
pub mod git;
pub mod github;
pub mod keys;
pub mod lock;
pub mod logs;
pub mod menu;
pub mod project_repository;
pub mod projects;
pub mod reader;
pub mod sentry;
pub mod sessions;
pub mod ssh;
pub mod storage;
pub mod types;
pub mod users;
pub mod virtual_branches;
pub mod watcher;
#[cfg(target_os = "windows")]
pub(crate) mod windows;
pub mod writer;
pub mod zip;
#[cfg(test)]
pub mod test_utils;
#[deprecated = "use `gitbutler-core` instead"]
pub mod id {
#[deprecated = "use `gitbutler-core` instead"]
pub use gitbutler_core::id::Id;
}

View File

@ -54,7 +54,7 @@ impl Inner {
mod tests {
use super::*;
use crate::test_utils::temp_dir;
use crate::tests::temp_dir;
#[tokio::test]
async fn test_lock_same_instance() {

View File

@ -1,12 +1,53 @@
#![feature(error_generic_member_access)]
#![cfg_attr(target_os = "windows", feature(windows_by_handle))]
pub(crate) mod analytics;
pub(crate) mod app;
pub(crate) mod assets;
pub(crate) mod commands;
pub(crate) mod database;
pub(crate) mod dedup;
pub(crate) mod deltas;
pub(crate) mod error;
pub(crate) mod events;
pub(crate) mod fs;
pub(crate) mod gb_repository;
pub(crate) mod git;
pub(crate) mod github;
pub(crate) mod keys;
pub(crate) mod lock;
pub(crate) mod logs;
pub(crate) mod menu;
pub(crate) mod project_repository;
pub(crate) mod projects;
pub(crate) mod reader;
pub(crate) mod sentry;
pub(crate) mod sessions;
pub(crate) mod ssh;
pub(crate) mod storage;
pub(crate) mod types;
pub(crate) mod users;
pub(crate) mod virtual_branches;
pub(crate) mod watcher;
#[cfg(target_os = "windows")]
pub(crate) mod windows;
pub(crate) mod writer;
pub(crate) mod zip;
#[cfg(test)]
pub(crate) mod tests;
#[deprecated = "use `gitbutler-core` instead"]
pub(crate) mod id {
#[deprecated = "use `gitbutler-core` instead"]
pub use gitbutler_core::id::Id;
}
use std::path::PathBuf;
use anyhow::Context;
use tauri::{generate_context, Manager, Wry};
use gblib::{
analytics, app, assets, commands, database, deltas, github, keys, logs, menu, projects, sentry,
sessions, storage, users, virtual_branches, watcher, zip,
};
use tauri_plugin_log::LogTarget;
use tauri_plugin_store::{with_store, JsonValue, StoreCollection};

View File

@ -447,11 +447,11 @@ mod tests {
use anyhow::Result;
use crate::test_utils;
use crate::tests;
#[test]
fn test_directory_reader_read_file() -> Result<()> {
let dir = test_utils::temp_dir();
let dir = tests::temp_dir();
let file_path = path::Path::new("test.txt");
std::fs::write(dir.join(file_path), "test")?;
@ -464,12 +464,12 @@ mod tests {
#[test]
fn test_commit_reader_read_file() -> Result<()> {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
let file_path = path::Path::new("test.txt");
std::fs::write(repository.path().parent().unwrap().join(file_path), "test")?;
let oid = test_utils::commit_all(&repository);
let oid = tests::commit_all(&repository);
std::fs::write(repository.path().parent().unwrap().join(file_path), "test2")?;
@ -481,7 +481,7 @@ mod tests {
#[test]
fn test_reader_list_files_should_return_relative() -> Result<()> {
let dir = test_utils::temp_dir();
let dir = tests::temp_dir();
std::fs::write(dir.join("test1.txt"), "test")?;
std::fs::create_dir_all(dir.join("dir"))?;
@ -497,7 +497,7 @@ mod tests {
#[test]
fn test_reader_list_files() -> Result<()> {
let dir = test_utils::temp_dir();
let dir = tests::temp_dir();
std::fs::write(dir.join("test.txt"), "test")?;
std::fs::create_dir_all(dir.join("dir"))?;
@ -514,7 +514,7 @@ mod tests {
#[test]
fn test_commit_reader_list_files_should_return_relative() -> Result<()> {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(
repository.path().parent().unwrap().join("test1.txt"),
@ -531,7 +531,7 @@ mod tests {
"test",
)?;
let oid = test_utils::commit_all(&repository);
let oid = tests::commit_all(&repository);
std::fs::remove_dir_all(repository.path().parent().unwrap().join("dir"))?;
@ -545,7 +545,7 @@ mod tests {
#[test]
fn test_commit_reader_list_files() -> Result<()> {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(repository.path().parent().unwrap().join("test.txt"), "test")?;
std::fs::create_dir_all(repository.path().parent().unwrap().join("dir"))?;
@ -559,7 +559,7 @@ mod tests {
"test",
)?;
let oid = test_utils::commit_all(&repository);
let oid = tests::commit_all(&repository);
std::fs::remove_dir_all(repository.path().parent().unwrap().join("dir"))?;
@ -574,7 +574,7 @@ mod tests {
#[test]
fn test_directory_reader_exists() -> Result<()> {
let dir = test_utils::temp_dir();
let dir = tests::temp_dir();
std::fs::write(dir.join("test.txt"), "test")?;
@ -587,11 +587,11 @@ mod tests {
#[test]
fn test_commit_reader_exists() -> Result<()> {
let repository = test_utils::test_repository();
let repository = tests::test_repository();
std::fs::write(repository.path().parent().unwrap().join("test.txt"), "test")?;
let oid = test_utils::commit_all(&repository);
let oid = tests::commit_all(&repository);
std::fs::remove_file(repository.path().parent().unwrap().join("test.txt"))?;

View File

@ -198,13 +198,13 @@ fn insert_stmt<'conn>(
#[cfg(test)]
mod tests {
use crate::test_utils;
use crate::tests;
use super::*;
#[test]
fn test_insert_query() -> Result<()> {
let db = test_utils::test_database();
let db = tests::test_database();
println!("0");
let database = Database::new(db);
println!("1");
@ -247,7 +247,7 @@ mod tests {
#[test]
fn test_update() -> Result<()> {
let db = test_utils::test_database();
let db = tests::test_database();
let database = Database::new(db);
let project_id = ProjectId::generate();

View File

@ -2,7 +2,7 @@ use anyhow::Result;
use crate::{
sessions::{self, session::SessionId},
test_utils::{Case, Suite},
tests::{Case, Suite},
};
use super::Writer;

View File

@ -1,3 +1,10 @@
pub(crate) mod common;
mod suite {
mod gb_repository;
mod projects;
mod virtual_branches;
}
use std::{collections::HashMap, fs, path};
use tempfile::tempdir;

View File

@ -1,5 +1,5 @@
#![allow(unused)]
use gblib::git;
use crate::git;
use std::{path, str::from_utf8};
pub fn temp_dir() -> std::path::PathBuf {

View File

@ -1,7 +1,7 @@
mod common;
use self::common::{paths, TestProject};
use gblib::{gb_repository, git, project_repository, projects};
use crate::{
gb_repository, git, project_repository, projects,
tests::common::{paths, TestProject},
};
use std::path;
mod init {

View File

@ -1,7 +1,7 @@
mod common;
use self::common::paths;
use gblib::projects::Controller;
use crate::{
projects::Controller,
tests::common::{self, paths},
};
pub fn new() -> Controller {
let data_dir = paths::data_dir();
@ -22,7 +22,7 @@ mod add {
}
mod error {
use gblib::projects::AddError;
use crate::projects::AddError;
use super::*;

View File

@ -5,20 +5,17 @@
clippy::dbg_macro
)]
mod common;
use std::{fs, path, str::FromStr};
use gblib::{
use crate::{
error::Error,
git, keys,
projects::{self, ProjectId},
tests::common::{paths, TestProject},
users,
virtual_branches::{branch, controller::ControllerError, errors, Controller},
};
use self::common::{paths, TestProject};
struct Test {
repository: TestProject,
project_id: ProjectId,
@ -49,7 +46,7 @@ impl Default for Test {
}
mod unapply_ownership {
use gblib::virtual_branches::branch::Ownership;
use crate::virtual_branches::branch::Ownership;
use super::*;
@ -365,7 +362,7 @@ mod references {
let branch1_id = controller
.create_virtual_branch(
&project_id,
&gblib::virtual_branches::branch::BranchCreateRequest {
&crate::virtual_branches::branch::BranchCreateRequest {
name: Some("name".to_string()),
..Default::default()
},
@ -376,7 +373,7 @@ mod references {
let branch2_id = controller
.create_virtual_branch(
&project_id,
&gblib::virtual_branches::branch::BranchCreateRequest {
&crate::virtual_branches::branch::BranchCreateRequest {
name: Some("name".to_string()),
..Default::default()
},
@ -3377,7 +3374,7 @@ mod update_base_branch {
}
mod reset_virtual_branch {
use gblib::virtual_branches::{controller::ControllerError, errors::ResetBranchError};
use crate::virtual_branches::{controller::ControllerError, errors::ResetBranchError};
use super::*;
@ -6255,7 +6252,7 @@ mod selected_for_changes {
}
mod move_commit_to_vbranch {
use gblib::virtual_branches::BranchId;
use crate::virtual_branches::BranchId;
use super::*;

View File

@ -555,7 +555,7 @@ pub fn target_to_base_branch(
.context("failed to get upstream commits")?
.iter()
.map(super::commit_to_remote_commit)
.collect::<Result<Vec<_>>>()?;
.collect::<Vec<_>>();
// get some recent commits
let recent_commits = project_repository
@ -563,7 +563,7 @@ pub fn target_to_base_branch(
.context("failed to get recent commits")?
.iter()
.map(super::commit_to_remote_commit)
.collect::<Result<Vec<_>>>()?;
.collect::<Vec<_>>();
let base = super::BaseBranch {
branch_name: format!("{}/{}", target.branch.remote(), target.branch.branch()),

View File

@ -142,15 +142,15 @@ impl Hunk {
self.timestamp_ms
}
pub fn contains(&self, line: &u32) -> bool {
self.start <= *line && self.end >= *line
pub fn contains(&self, line: u32) -> bool {
self.start <= line && self.end >= line
}
pub fn intersects(&self, another: &Hunk) -> bool {
self.contains(&another.start)
|| self.contains(&another.end)
|| another.contains(&self.start)
|| another.contains(&self.end)
self.contains(another.start)
|| self.contains(another.end)
|| another.contains(self.start)
|| another.contains(self.end)
}
}

View File

@ -27,7 +27,7 @@ mod tests {
use crate::{
sessions,
test_utils::{Case, Suite},
tests::{Case, Suite},
virtual_branches::branch::Ownership,
};

View File

@ -157,7 +157,7 @@ mod tests {
use once_cell::sync::Lazy;
use crate::{
test_utils::{Case, Suite},
tests::{Case, Suite},
virtual_branches::branch,
};

View File

@ -9,14 +9,14 @@ pub fn hunk_with_context(
context_lines: usize,
file_lines_before: &[&str],
change_type: diff::ChangeType,
) -> Result<diff::Hunk> {
) -> diff::Hunk {
let diff_lines = hunk_diff
.lines()
.map(std::string::ToString::to_string)
.collect::<Vec<_>>();
if diff_lines.is_empty() {
#[allow(clippy::cast_possible_truncation)]
return Ok(diff::Hunk {
return diff::Hunk {
diff: hunk_diff.to_owned(),
old_start: hunk_old_start_line as u32,
old_lines: 0,
@ -24,7 +24,7 @@ pub fn hunk_with_context(
new_lines: 0,
binary: is_binary,
change_type,
});
};
}
let new_file = hunk_old_start_line == 0;
@ -120,7 +120,8 @@ pub fn hunk_with_context(
binary: is_binary,
change_type,
};
Ok(hunk)
hunk
}
#[cfg(test)]
@ -140,8 +141,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
let expected = r#"@@ -5,7 +5,7 @@
[features]
@ -173,8 +173,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(
with_ctx.diff.replace("\n \n", "\n\n"),
r#"@@ -1,5 +1,5 @@
@ -206,8 +205,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(
with_ctx.diff.replace("\n \n", "\n\n"),
r#"@@ -1,4 +1,4 @@
@ -238,8 +236,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(
with_ctx.diff.replace("\n \n", "\n\n"),
r#"@@ -10,5 +10,5 @@
@ -274,8 +271,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(
with_ctx.diff.replace("\n \n", "\n\n"),
r#"@@ -5,7 +5,10 @@
@ -314,8 +310,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(
with_ctx.diff.replace("\n \n", "\n\n"),
r#"@@ -4,9 +4,7 @@
@ -348,8 +343,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(with_ctx.diff, "");
}
@ -379,8 +373,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(with_ctx.diff.replace("\n \n", "\n\n"), hunk_diff);
assert_eq!(with_ctx.old_start, 1);
assert_eq!(with_ctx.old_lines, 14);
@ -404,8 +397,7 @@ mod tests {
3,
&Vec::new(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(with_ctx.diff.replace("\n \n", "\n\n"), hunk_diff);
assert_eq!(with_ctx.old_start, 0);
assert_eq!(with_ctx.old_lines, 0);
@ -428,8 +420,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
let expected = r#"@@ -6,6 +6,9 @@
[features]
default = ["serde", "rusqlite"]
@ -463,8 +454,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
let expected = r#"@@ -6,6 +10,9 @@
[features]
default = ["serde", "rusqlite"]
@ -509,8 +499,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(with_ctx.diff.replace("\n \n", "\n\n"), expected);
assert_eq!(with_ctx.old_start, 4);
assert_eq!(with_ctx.old_lines, 9);
@ -544,8 +533,7 @@ mod tests {
3,
&file_lines(),
diff::ChangeType::Added,
)
.unwrap();
);
assert_eq!(with_ctx.diff.replace("\n \n", "\n\n"), expected);
assert_eq!(with_ctx.old_start, 4);
assert_eq!(with_ctx.old_lines, 9);
@ -567,8 +555,7 @@ mod tests {
3,
&file_lines_2(),
diff::ChangeType::Added,
)
.unwrap();
);
let expected = "@@ -8,8 +8,6 @@
.order(:created_at)
.page params[:page]
@ -599,8 +586,7 @@ mod tests {
3,
&file_lines_3(),
diff::ChangeType::Added,
)
.unwrap();
);
let expected = r#"@@ -1,4 +1,5 @@
alias(
name = "rdeps",

View File

@ -74,7 +74,7 @@ fn files_with_hunk_context(
.map(|hunk| {
if hunk.diff.is_empty() {
// noop on empty diff
Ok(hunk.clone())
hunk.clone()
} else {
context::hunk_with_context(
&hunk.diff,
@ -87,8 +87,7 @@ fn files_with_hunk_context(
)
}
})
.collect::<Result<Vec<diff::Hunk>>>()
.context("failed to add context to hunk")?;
.collect::<Vec<diff::Hunk>>();
}
Ok(files)
}

View File

@ -65,7 +65,7 @@ mod tests {
use crate::{
reader, sessions,
test_utils::{Case, Suite},
tests::{Case, Suite},
virtual_branches::target,
};

View File

@ -159,17 +159,17 @@ pub fn branch_to_remote_branch_data(
commits: ahead
.into_iter()
.map(|commit| commit_to_remote_commit(&commit))
.collect::<Result<Vec<_>>>()?,
.collect::<Vec<_>>(),
})
})
.transpose()
}
pub fn commit_to_remote_commit(commit: &git::Commit) -> Result<RemoteCommit> {
Ok(RemoteCommit {
pub fn commit_to_remote_commit(commit: &git::Commit) -> RemoteCommit {
RemoteCommit {
id: commit.id().to_string(),
description: commit.message().unwrap_or_default().to_string(),
created_at: commit.time().seconds().try_into().unwrap(),
author: commit.author().into(),
})
}
}

View File

@ -39,7 +39,7 @@ mod tests {
use crate::{
sessions,
test_utils::{Case, Suite},
tests::{Case, Suite},
virtual_branches::{branch, target::writer::TargetWriter},
};

View File

@ -100,7 +100,7 @@ mod tests {
use once_cell::sync::Lazy;
use crate::{
test_utils::{Case, Suite},
tests::{Case, Suite},
virtual_branches::branch,
};

View File

@ -13,7 +13,7 @@ use std::os::unix::{fs::symlink, prelude::*};
use crate::{
gb_repository, git, project_repository, reader, sessions,
test_utils::{self, empty_bare_repository, Case, Suite},
tests::{self, empty_bare_repository, Case, Suite},
virtual_branches::errors::CommitError,
};
@ -207,7 +207,7 @@ fn test_track_binary_files() -> Result<()> {
];
let mut file = fs::File::create(std::path::Path::new(&project.path).join("image.bin"))?;
file.write_all(&image_data)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
set_test_target(&gb_repository, &project_repository)?;
@ -954,7 +954,7 @@ fn test_merge_vbranch_upstream_clean_rebase() -> Result<()> {
std::path::Path::new(&project.path).join(file_path),
"line1\nline2\nline3\nline4\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let target_oid = project_repository
.git_repository
.head()
@ -967,7 +967,7 @@ fn test_merge_vbranch_upstream_clean_rebase() -> Result<()> {
"line1\nline2\nline3\nline4\nupstream\n",
)?;
// add a commit to the target branch it's pointing to so there is something "upstream"
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let last_push = project_repository
.git_repository
.head()
@ -981,7 +981,7 @@ fn test_merge_vbranch_upstream_clean_rebase() -> Result<()> {
"line1\nline2\nline3\nline4\nupstream\ncoworker work\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let coworker_work = project_repository
.git_repository
.head()
@ -1078,7 +1078,7 @@ fn test_merge_vbranch_upstream_conflict() -> Result<()> {
std::path::Path::new(&project.path).join(file_path),
"line1\nline2\nline3\nline4\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let target_oid = project_repository
.git_repository
.head()
@ -1091,7 +1091,7 @@ fn test_merge_vbranch_upstream_conflict() -> Result<()> {
"line1\nline2\nline3\nline4\nupstream\n",
)?;
// add a commit to the target branch it's pointing to so there is something "upstream"
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let last_push = project_repository
.git_repository
.head()
@ -1105,7 +1105,7 @@ fn test_merge_vbranch_upstream_conflict() -> Result<()> {
"line1\nline2\nline3\nline4\nupstream\ncoworker work\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let coworker_work = project_repository
.git_repository
.head()
@ -1284,7 +1284,7 @@ fn test_apply_unapply_branch() -> Result<()> {
std::path::Path::new(&project.path).join(file_path),
"line1\nline2\nline3\nline4\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
set_test_target(&gb_repository, &project_repository)?;
@ -1385,7 +1385,7 @@ fn test_apply_unapply_added_deleted_files() -> Result<()> {
std::path::Path::new(&project.path).join(file_path2),
"file2\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
set_test_target(&gb_repository, &project_repository)?;
@ -1471,7 +1471,7 @@ fn test_detect_mergeable_branch() -> Result<()> {
std::path::Path::new(&project.path).join(file_path),
"line1\nline2\nline3\nline4\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
set_test_target(&gb_repository, &project_repository)?;
@ -1532,7 +1532,7 @@ fn test_detect_mergeable_branch() -> Result<()> {
std::path::Path::new(&project.path).join(file_path),
"line1\nline2\nline3\nline4\nupstream\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let up_target = project_repository
.git_repository
.head()
@ -1556,7 +1556,7 @@ fn test_detect_mergeable_branch() -> Result<()> {
std::path::Path::new(&project.path).join(file_path3),
"file3\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let up_target = project_repository
.git_repository
.head()
@ -1682,7 +1682,7 @@ fn test_upstream_integrated_vbranch() -> Result<()> {
std::path::Path::new(&project.path).join("test.txt"),
"file1\nversion2\n",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
let upstream_commit = project_repository
.git_repository
@ -2388,12 +2388,12 @@ fn test_verify_branch_commits_to_integration() -> Result<()> {
// write two commits
let file_path2 = std::path::Path::new("test2.txt");
std::fs::write(std::path::Path::new(&project.path).join(file_path2), "file")?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
std::fs::write(
std::path::Path::new(&project.path).join(file_path2),
"update",
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
// verify puts commits onto the virtual branch
integration::verify_branch(&gb_repository, &project_repository).unwrap();

View File

@ -1007,7 +1007,7 @@ fn files_with_hunk_context(
.map(|hunk| {
if hunk.diff.is_empty() {
// noop on empty diff
Ok(hunk.clone())
hunk.clone()
} else {
let hunk_with_ctx = context::hunk_with_context(
&hunk.diff,
@ -1021,22 +1021,19 @@ fn files_with_hunk_context(
to_virtual_branch_hunk(hunk.clone(), hunk_with_ctx)
}
})
.collect::<Result<Vec<VirtualBranchHunk>>>()
.context("failed to add context to hunk")?;
.collect::<Vec<VirtualBranchHunk>>();
}
Ok(files)
}
fn to_virtual_branch_hunk(
mut hunk: VirtualBranchHunk,
diff_with_context: Result<diff::Hunk>,
) -> Result<VirtualBranchHunk> {
diff_with_context.map(|diff| {
hunk.diff = diff.diff;
hunk.start = diff.new_start;
hunk.end = diff.new_start + diff.new_lines;
hunk
})
diff_with_context: diff::Hunk,
) -> VirtualBranchHunk {
hunk.diff = diff_with_context.diff;
hunk.start = diff_with_context.new_start;
hunk.end = diff_with_context.new_start + diff_with_context.new_lines;
hunk
}
fn is_requires_force(

View File

@ -53,28 +53,26 @@ impl Watchers {
let project_id = project.id;
let project_path = project.path.clone();
task::Builder::new()
.name(&format!("{} watcher", project_id))
.spawn({
let watchers = Arc::clone(&self.watchers);
let watcher = watcher.clone();
async move {
watchers.lock().await.insert(project_id, watcher.clone());
match watcher.run(&project_path, &project_id).await {
Ok(()) => {
tracing::debug!(%project_id, "watcher stopped");
},
Err(RunError::PathNotFound(path)) => {
tracing::warn!(%project_id, path = %path.display(), "watcher stopped: project path not found");
watchers.lock().await.remove(&project_id);
}
Err(error) => {
tracing::error!(?error, %project_id, "watcher error");
watchers.lock().await.remove(&project_id);
}
task::spawn({
let watchers = Arc::clone(&self.watchers);
let watcher = watcher.clone();
async move {
watchers.lock().await.insert(project_id, watcher.clone());
match watcher.run(&project_path, &project_id).await {
Ok(()) => {
tracing::debug!(%project_id, "watcher stopped");
}
Err(RunError::PathNotFound(path)) => {
tracing::warn!(%project_id, path = %path.display(), "watcher stopped: project path not found");
watchers.lock().await.remove(&project_id);
}
Err(error) => {
tracing::error!(?error, %project_id, "watcher error");
watchers.lock().await.remove(&project_id);
}
}
})?;
}
});
Ok(())
}
@ -196,44 +194,42 @@ impl WatcherInner {
.context("failed to send event")?;
let handle_event = |event: &Event| -> Result<()> {
task::Builder::new()
.name(&format!("handle {}", event))
.spawn_blocking({
let project_id = project_id.to_string();
let handler = self.handler.clone();
let tx = proxy_tx.clone();
let event = event.clone();
move || {
futures::executor::block_on(async move {
match handler.handle(&event, time::SystemTime::now()).await {
Err(error) => tracing::error!(
project_id,
%event,
?error,
"failed to handle event",
),
Ok(events) => {
for e in events {
if let Err(error) = tx.send(e.clone()) {
tracing::error!(
project_id,
%event,
?error,
"failed to post event",
);
} else {
tracing::debug!(
project_id,
%event,
"sent response event",
);
}
task::spawn_blocking({
let project_id = project_id.to_string();
let handler = self.handler.clone();
let tx = proxy_tx.clone();
let event = event.clone();
move || {
futures::executor::block_on(async move {
match handler.handle(&event, time::SystemTime::now()).await {
Err(error) => tracing::error!(
project_id,
%event,
?error,
"failed to handle event",
),
Ok(events) => {
for e in events {
if let Err(error) = tx.send(e.clone()) {
tracing::error!(
project_id,
%event,
?error,
"failed to post event",
);
} else {
tracing::debug!(
project_id,
%event,
"sent response event",
);
}
}
}
});
}
})?;
}
});
}
});
Ok(())
};

View File

@ -55,24 +55,21 @@ impl Dispatcher {
let (tx, rx) = channel(1);
let project_id = *project_id;
task::Builder::new()
.name(&format!("{} dispatcher", project_id))
.spawn(async move {
loop {
select! {
() = self.cancellation_token.cancelled() => {
break;
}
Some(event) = file_change_rx.recv() => {
if let Err(error) = tx.send(event).await {
tracing::error!(%project_id, ?error,"failed to send file change");
}
task::spawn(async move {
loop {
select! {
() = self.cancellation_token.cancelled() => {
break;
}
Some(event) = file_change_rx.recv() => {
if let Err(error) = tx.send(event).await {
tracing::error!(%project_id, ?error,"failed to send file change");
}
}
}
tracing::debug!(%project_id, "dispatcher stopped");
})
.context("failed to spawn combined dispatcher task")?;
}
tracing::debug!(%project_id, "dispatcher stopped");
});
Ok(rx)
}

View File

@ -82,67 +82,70 @@ impl Dispatcher {
tracing::debug!(%project_id, "file watcher started");
let (tx, rx) = channel(1);
task::Builder::new()
.name(&format!("{} file watcher", project_id))
.spawn_blocking({
let path = path.to_path_buf();
let project_id = *project_id;
move || {
for result in notify_rx {
match result {
Err(errors) => {
tracing::error!(?errors, "file watcher error");
}
Ok(events) => {
let file_paths = events.into_iter().filter(|event| is_interesting_kind(event.kind)).flat_map(|event| event.paths.clone()).filter(|file| is_interesting_file(&repo, file));
for file_path in file_paths {
match file_path.strip_prefix(&path) {
Ok(relative_file_path) if relative_file_path.display().to_string().is_empty() => { /* noop */ }
Ok(relative_file_path) => {
let event = if relative_file_path.starts_with(".git") {
tracing::info!(
%project_id,
file_path = %relative_file_path.display(),
"git file change",
);
events::Event::GitFileChange(
project_id,
relative_file_path
.strip_prefix(".git")
.unwrap()
.to_path_buf(),
)
} else {
tracing::info!(
%project_id,
file_path = %relative_file_path.display(),
"project file change",
);
events::Event::ProjectFileChange(
project_id,
relative_file_path.to_path_buf(),
)
};
if let Err(error) = block_on(tx.send(event)) {
tracing::error!(
%project_id,
?error,
"failed to send file change event",
);
}
}
Err(error) => {
tracing::error!(%project_id, ?error, "failed to strip prefix");
task::spawn_blocking({
let path = path.to_path_buf();
let project_id = *project_id;
move || {
for result in notify_rx {
match result {
Err(errors) => {
tracing::error!(?errors, "file watcher error");
}
Ok(events) => {
let file_paths = events
.into_iter()
.filter(|event| is_interesting_kind(event.kind))
.flat_map(|event| event.paths.clone())
.filter(|file| is_interesting_file(&repo, file));
for file_path in file_paths {
match file_path.strip_prefix(&path) {
Ok(relative_file_path)
if relative_file_path.display().to_string().is_empty() =>
{ /* noop */ }
Ok(relative_file_path) => {
let event = if relative_file_path.starts_with(".git") {
tracing::info!(
%project_id,
file_path = %relative_file_path.display(),
"git file change",
);
events::Event::GitFileChange(
project_id,
relative_file_path
.strip_prefix(".git")
.unwrap()
.to_path_buf(),
)
} else {
tracing::info!(
%project_id,
file_path = %relative_file_path.display(),
"project file change",
);
events::Event::ProjectFileChange(
project_id,
relative_file_path.to_path_buf(),
)
};
if let Err(error) = block_on(tx.send(event)) {
tracing::error!(
%project_id,
?error,
"failed to send file change event",
);
}
}
Err(error) => {
tracing::error!(%project_id, ?error, "failed to strip prefix");
}
}
}
}
}
}
}
tracing::debug!(%project_id, "file watcher stopped");
}
}).context(format!("{}: failed to start file watcher thread", project_id))?;
tracing::debug!(%project_id, "file watcher stopped");
}
});
Ok(rx)
}

View File

@ -201,7 +201,7 @@ mod test {
use crate::{
deltas, sessions,
test_utils::{self, Case, Suite},
tests::{self, Case, Suite},
virtual_branches::{self, branch},
};
@ -613,7 +613,7 @@ mod test {
i.to_string(),
)?;
test_utils::commit_all(&project_repository.git_repository);
tests::commit_all(&project_repository.git_repository);
listener.handle(relative_file_path, &project.id)?;
assert!(gb_repository.flush(&project_repository, None)?.is_some());
}

View File

@ -167,7 +167,7 @@ mod test {
use pretty_assertions::assert_eq;
use crate::test_utils::{Case, Suite};
use crate::tests::{Case, Suite};
use super::super::test_remote_repository;
use super::*;

View File

@ -132,7 +132,7 @@ mod test {
use pretty_assertions::assert_eq;
use crate::{
test_utils::{Case, Suite},
tests::{Case, Suite},
watcher::handlers,
};

View File

@ -292,7 +292,7 @@ mod test {
use std::path::PathBuf;
use crate::project_repository::LogUntil;
use crate::test_utils::{Case, Suite};
use crate::tests::{Case, Suite};
use crate::virtual_branches::set_test_target;
use super::super::test_remote_repository;

View File

@ -67,18 +67,6 @@ impl DirWriter {
})?
}
pub fn write_usize(&self, path: &str, contents: &usize) -> Result<(), std::io::Error> {
self.write_string(path, &contents.to_string())
}
pub fn write_u128(&self, path: &str, contents: &u128) -> Result<(), std::io::Error> {
self.write_string(path, &contents.to_string())
}
pub fn write_bool(&self, path: &str, contents: &bool) -> Result<(), std::io::Error> {
self.write_string(path, &contents.to_string())
}
pub fn write_string(&self, path: &str, contents: &str) -> Result<(), std::io::Error> {
self.write(path, contents)
}