mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-28 13:26:16 +03:00
refactor sessions mod
This commit is contained in:
parent
0562bcae5d
commit
137f73848f
@ -82,7 +82,7 @@ fn init(
|
||||
Some(session) => session,
|
||||
None => sessions::Session::from_head(git_repository, project)?,
|
||||
};
|
||||
sessions::flush_session(git_repository, user, project, &mut current_session)?;
|
||||
current_session.flush(git_repository, user, project)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error).with_context(|| {
|
||||
|
30
src-tauri/src/sessions/activity.rs
Normal file
30
src-tauri/src/sessions/activity.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Activity {
|
||||
#[serde(rename = "type")]
|
||||
pub activity_type: String,
|
||||
pub timestamp: u64,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
pub fn parse_reflog_line(line: &str) -> Result<Activity> {
|
||||
match line.split("\t").collect::<Vec<&str>>()[..] {
|
||||
[meta, message] => {
|
||||
let meta_parts = meta.split_whitespace().collect::<Vec<&str>>();
|
||||
let timestamp = meta_parts[meta_parts.len() - 2].parse::<u64>()?;
|
||||
|
||||
match message.split(": ").collect::<Vec<&str>>()[..] {
|
||||
[entry_type, msg] => Ok(Activity {
|
||||
activity_type: entry_type.to_string(),
|
||||
message: msg.to_string(),
|
||||
timestamp,
|
||||
}),
|
||||
_ => Err(anyhow!("failed to parse reflog line: {}", line)),
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow!("failed to parse reflog line: {}", line)),
|
||||
}
|
||||
}
|
49
src-tauri/src/sessions/activity_tests.rs
Normal file
49
src-tauri/src/sessions/activity_tests.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use super::activity::{parse_reflog_line, Activity};
|
||||
|
||||
#[test]
|
||||
fn test_parse_reflog_line() {
|
||||
let test_cases = vec![
|
||||
(
|
||||
"9ea641990993cb60c7d89c41606f6b457adb9681 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676275740 +0100 commit: try sturdy mac dev certificate",
|
||||
Activity{ activity_type: "commit".to_string(), timestamp: 1676275740, message: "try sturdy mac dev certificate".to_string() }
|
||||
),
|
||||
(
|
||||
"999bc2f0194ea001f71ba65b5422a742b5e66d9f bb98b5411d597fdede63053c190260a38d459ecb Nikita Galaiko <nikita@galaiko.rocks> 1675428111 +0100 checkout: moving from production-build to master",
|
||||
Activity{ activity_type: "checkout".to_string(), timestamp: 1675428111, message: "moving from production-build to master".to_string() },
|
||||
),
|
||||
(
|
||||
"0000000000000000000000000000000000000000 9aa96f488fbdb8f7b15151d9d2e47690d3b21b46 Nikita Galaiko <nikita@galaiko.rocks> 1675176957 +0100 commit (initial): simple tauri example",
|
||||
Activity{ activity_type: "commit (initial)".to_string(), timestamp: 1675176957, message: "simple tauri example".to_string() },
|
||||
),
|
||||
(
|
||||
"d083bb9213fc5e0bb6d07c2c6c1eae5be483be25 dc870a80fddb843583baa36cb637c5c820b1e863 Nikita Galaiko <nikita@galaiko.rocks> 1675425613 +0100 commit (amend): build app with github actions",
|
||||
Activity{ activity_type: "commit (amend)".to_string(), timestamp: 1675425613, message: "build app with github actions".to_string() },
|
||||
),
|
||||
(
|
||||
"2843be38a72ac8418c7e5c5630cba3c4803916d1 fbb7a9356484b948bde4c7ee9fdeb6439edff8c0 Nikita Galaiko <nikita@galaiko.rocks> 1676274883 +0100 pull: Fast-forward",
|
||||
Activity{ activity_type: "pull".to_string(), timestamp: 1676274883, message: "Fast-forward".to_string() },
|
||||
),
|
||||
(
|
||||
"3f2657e0d1eae57f58d7734aae10310a861de8e8 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676277401 +0100 reset: moving to HEAD",
|
||||
Activity{ activity_type: "reset".to_string() , timestamp: 1676277401, message: "moving to HEAD".to_string() },
|
||||
),
|
||||
(
|
||||
"9a831ba2fa07aa6a399bbb498e8effd913cec2e0 add94e65594e4c240b0f6b03973a3be3ff594306 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (start): checkout add94e65594e4c240b0f6b03973a3be3ff594306",
|
||||
Activity{ activity_type: "pull --rebase (start)".to_string(), timestamp: 1676039997, message: "checkout add94e65594e4c240b0f6b03973a3be3ff594306".to_string() },
|
||||
),
|
||||
(
|
||||
"add94e65594e4c240b0f6b03973a3be3ff594306 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (pick): make app run in background",
|
||||
Activity{ activity_type: "pull --rebase (pick)".to_string(), timestamp: 1676039997, message: "make app run in background".to_string() },
|
||||
),
|
||||
(
|
||||
"bcc93167c068649868aa3df4999ba154468a62b5 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (finish): returning to refs/heads/master",
|
||||
Activity{ activity_type: "pull --rebase (finish)".to_string(), timestamp: 1676039997, message: "returning to refs/heads/master".to_string() },
|
||||
)
|
||||
];
|
||||
|
||||
for (line, expected) in test_cases {
|
||||
let actual = parse_reflog_line(line);
|
||||
assert!(actual.is_ok());
|
||||
assert_eq!(actual.unwrap(), expected);
|
||||
}
|
||||
}
|
7
src-tauri/src/sessions/mod.rs
Normal file
7
src-tauri/src/sessions/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
mod activity;
|
||||
mod sessions;
|
||||
|
||||
pub use sessions::{get, list, list_files, Session};
|
||||
|
||||
#[cfg(test)]
|
||||
mod activity_tests;
|
@ -1,3 +1,4 @@
|
||||
use super::activity;
|
||||
use crate::{fs, projects, users};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use filetime::FileTime;
|
||||
@ -33,35 +34,7 @@ pub struct Session {
|
||||
// if hash is not set, the session is not saved aka current
|
||||
pub hash: Option<String>,
|
||||
pub meta: Meta,
|
||||
pub activity: Vec<Activity>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Activity {
|
||||
#[serde(rename = "type")]
|
||||
pub activity_type: String,
|
||||
pub timestamp: u64,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
fn parse_reflog_line(line: &str) -> Result<Activity> {
|
||||
match line.split("\t").collect::<Vec<&str>>()[..] {
|
||||
[meta, message] => {
|
||||
let meta_parts = meta.split_whitespace().collect::<Vec<&str>>();
|
||||
let timestamp = meta_parts[meta_parts.len() - 2].parse::<u64>()?;
|
||||
|
||||
match message.split(": ").collect::<Vec<&str>>()[..] {
|
||||
[entry_type, msg] => Ok(Activity {
|
||||
activity_type: entry_type.to_string(),
|
||||
message: msg.to_string(),
|
||||
timestamp,
|
||||
}),
|
||||
_ => Err(anyhow!("failed to parse reflog line: {}", line)),
|
||||
}
|
||||
}
|
||||
_ => Err(anyhow!("failed to parse reflog line: {}", line)),
|
||||
}
|
||||
pub activity: Vec<activity::Activity>,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
@ -110,9 +83,9 @@ impl Session {
|
||||
})?;
|
||||
let activity = reflog
|
||||
.lines()
|
||||
.filter_map(|line| parse_reflog_line(line).ok())
|
||||
.filter_map(|line| activity::parse_reflog_line(line).ok())
|
||||
.filter(|activity| activity.timestamp >= start_ts)
|
||||
.collect::<Vec<Activity>>();
|
||||
.collect::<Vec<activity::Activity>>();
|
||||
|
||||
let id_path = meta_path.join("id");
|
||||
let id = std::fs::read_to_string(id_path.clone())
|
||||
@ -149,7 +122,7 @@ impl Session {
|
||||
},
|
||||
activity: vec![],
|
||||
};
|
||||
create_session(project, &session)?;
|
||||
create(project, &session)?;
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
@ -175,9 +148,9 @@ impl Session {
|
||||
})?;
|
||||
let activity = reflog
|
||||
.lines()
|
||||
.filter_map(|line| parse_reflog_line(line).ok())
|
||||
.filter_map(|line| activity::parse_reflog_line(line).ok())
|
||||
.filter(|activity| activity.timestamp >= start_ts)
|
||||
.collect::<Vec<Activity>>();
|
||||
.collect::<Vec<activity::Activity>>();
|
||||
|
||||
Ok(Session {
|
||||
id: read_as_string(repo, &tree, Path::new("session/meta/id")).with_context(|| {
|
||||
@ -215,9 +188,22 @@ impl Session {
|
||||
activity,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&self, project: &projects::Project) -> Result<()> {
|
||||
update(project, self)
|
||||
}
|
||||
|
||||
pub fn flush(
|
||||
&mut self,
|
||||
repo: &git2::Repository,
|
||||
user: &Option<users::User>,
|
||||
project: &projects::Project,
|
||||
) -> Result<()> {
|
||||
flush(repo, user, project, self)
|
||||
}
|
||||
}
|
||||
|
||||
fn write_session(session_path: &Path, session: &Session) -> Result<()> {
|
||||
fn write(session_path: &Path, session: &Session) -> Result<()> {
|
||||
if session.hash.is_some() {
|
||||
return Err(anyhow!("cannot write session that is not current"));
|
||||
}
|
||||
@ -270,27 +256,27 @@ fn write_session(session_path: &Path, session: &Session) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_session(project: &projects::Project, session: &Session) -> Result<()> {
|
||||
fn update(project: &projects::Project, session: &Session) -> Result<()> {
|
||||
let session_path = project.session_path();
|
||||
log::debug!("{}: Updating current session", session_path.display());
|
||||
if session_path.exists() {
|
||||
write_session(&session_path, session)
|
||||
write(&session_path, session)
|
||||
} else {
|
||||
Err(anyhow!("session does not exist"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_session(project: &projects::Project, session: &Session) -> Result<()> {
|
||||
fn create(project: &projects::Project, session: &Session) -> Result<()> {
|
||||
let session_path = project.session_path();
|
||||
log::debug!("{}: Creating current session", session_path.display());
|
||||
if session_path.exists() {
|
||||
Err(anyhow!("session already exists"))
|
||||
} else {
|
||||
write_session(&session_path, session)
|
||||
write(&session_path, session)
|
||||
}
|
||||
}
|
||||
|
||||
fn delete_session(project: &projects::Project) -> Result<()> {
|
||||
fn delete(project: &projects::Project) -> Result<()> {
|
||||
let session_path = project.session_path();
|
||||
log::debug!("{}: Deleting current session", session_path.display());
|
||||
if session_path.exists() {
|
||||
@ -428,55 +414,7 @@ pub fn list_files(
|
||||
Ok(files)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_reflog_line() {
|
||||
let test_cases = vec![
|
||||
(
|
||||
"9ea641990993cb60c7d89c41606f6b457adb9681 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676275740 +0100 commit: try sturdy mac dev certificate",
|
||||
Activity{ activity_type: "commit".to_string(), timestamp: 1676275740, message: "try sturdy mac dev certificate".to_string() }
|
||||
),
|
||||
(
|
||||
"999bc2f0194ea001f71ba65b5422a742b5e66d9f bb98b5411d597fdede63053c190260a38d459ecb Nikita Galaiko <nikita@galaiko.rocks> 1675428111 +0100 checkout: moving from production-build to master",
|
||||
Activity{ activity_type: "checkout".to_string(), timestamp: 1675428111, message: "moving from production-build to master".to_string() },
|
||||
),
|
||||
(
|
||||
"0000000000000000000000000000000000000000 9aa96f488fbdb8f7b15151d9d2e47690d3b21b46 Nikita Galaiko <nikita@galaiko.rocks> 1675176957 +0100 commit (initial): simple tauri example",
|
||||
Activity{ activity_type: "commit (initial)".to_string(), timestamp: 1675176957, message: "simple tauri example".to_string() },
|
||||
),
|
||||
(
|
||||
"d083bb9213fc5e0bb6d07c2c6c1eae5be483be25 dc870a80fddb843583baa36cb637c5c820b1e863 Nikita Galaiko <nikita@galaiko.rocks> 1675425613 +0100 commit (amend): build app with github actions",
|
||||
Activity{ activity_type: "commit (amend)".to_string(), timestamp: 1675425613, message: "build app with github actions".to_string() },
|
||||
),
|
||||
(
|
||||
"2843be38a72ac8418c7e5c5630cba3c4803916d1 fbb7a9356484b948bde4c7ee9fdeb6439edff8c0 Nikita Galaiko <nikita@galaiko.rocks> 1676274883 +0100 pull: Fast-forward",
|
||||
Activity{ activity_type: "pull".to_string(), timestamp: 1676274883, message: "Fast-forward".to_string() },
|
||||
),
|
||||
(
|
||||
"3f2657e0d1eae57f58d7734aae10310a861de8e8 3f2657e0d1eae57f58d7734aae10310a861de8e8 Nikita Galaiko <nikita@galaiko.rocks> 1676277401 +0100 reset: moving to HEAD",
|
||||
Activity{ activity_type: "reset".to_string() , timestamp: 1676277401, message: "moving to HEAD".to_string() },
|
||||
),
|
||||
(
|
||||
"9a831ba2fa07aa6a399bbb498e8effd913cec2e0 add94e65594e4c240b0f6b03973a3be3ff594306 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (start): checkout add94e65594e4c240b0f6b03973a3be3ff594306",
|
||||
Activity{ activity_type: "pull --rebase (start)".to_string(), timestamp: 1676039997, message: "checkout add94e65594e4c240b0f6b03973a3be3ff594306".to_string() },
|
||||
),
|
||||
(
|
||||
"add94e65594e4c240b0f6b03973a3be3ff594306 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (pick): make app run in background",
|
||||
Activity{ activity_type: "pull --rebase (pick)".to_string(), timestamp: 1676039997, message: "make app run in background".to_string() },
|
||||
),
|
||||
(
|
||||
"bcc93167c068649868aa3df4999ba154468a62b5 bcc93167c068649868aa3df4999ba154468a62b5 Nikita Galaiko <nikita@galaiko.rocks> 1676039997 +0100 pull --rebase (finish): returning to refs/heads/master",
|
||||
Activity{ activity_type: "pull --rebase (finish)".to_string(), timestamp: 1676039997, message: "returning to refs/heads/master".to_string() },
|
||||
)
|
||||
];
|
||||
|
||||
for (line, expected) in test_cases {
|
||||
let actual = parse_reflog_line(line);
|
||||
assert!(actual.is_ok());
|
||||
assert_eq!(actual.unwrap(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush_session(
|
||||
fn flush(
|
||||
repo: &git2::Repository,
|
||||
user: &Option<users::User>,
|
||||
project: &projects::Project,
|
||||
@ -540,7 +478,7 @@ pub fn flush_session(
|
||||
commit_oid
|
||||
);
|
||||
session.hash = Some(commit_oid.to_string());
|
||||
delete_session(project).with_context(|| format!("failed to delete session"))?;
|
||||
delete(project).with_context(|| format!("failed to delete session"))?;
|
||||
|
||||
push_to_remote(repo, user, project)
|
||||
.with_context(|| format!("failed to push gb commit {} to remote", commit_oid))?;
|
@ -239,8 +239,9 @@ fn write_beginning_meta_files<R: tauri::Runtime>(
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
session.meta.last_ts = now_ts;
|
||||
sessions::update_session(project, &session)
|
||||
.map_err(|e| format!("Error while updating current session: {}", e.to_string()))?;
|
||||
session
|
||||
.update(project)
|
||||
.with_context(|| "failed to update session")?;
|
||||
events::session(&window, &project, &session);
|
||||
Ok(session)
|
||||
}
|
||||
|
@ -96,7 +96,8 @@ impl GitWatcher {
|
||||
{
|
||||
None => Ok(None),
|
||||
Some(mut session) => {
|
||||
sessions::flush_session(&repo, user, project, &mut session)
|
||||
session
|
||||
.flush(&repo, user, project)
|
||||
.with_context(|| "Error while flushing session")?;
|
||||
Ok(Some(session))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user