Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ members = [
"settlement",
"simperby"
]
resolver = "2"
4 changes: 2 additions & 2 deletions cli/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ async fn cli() {
clients_path.push(dir.clone());
run_command(format!("cp -a {server_dir}/. {dir}/")).await;

let config = Config {};
let config = Config { git_network: false };
let config = serde_spb::to_string(&config).unwrap();
let auth = Auth {
private_key: key.clone(),
Expand All @@ -95,7 +95,7 @@ async fn cli() {
}

// Add files for cli.
let config = Config {};
let config = Config { git_network: false };
let config = serde_spb::to_string(&config).unwrap();
let auth = Auth {
private_key: keys[3].1.clone(),
Expand Down
2 changes: 1 addition & 1 deletion repository/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ pub fn raw_commit_to_semantic_commit(raw_commit: RawCommit) -> SemanticCommit {
let (title, body) = if let Some((title, body)) = raw_commit.message.split_once("\n\n") {
(title.to_string(), body.to_string())
} else {
(String::new(), String::new())
(raw_commit.message, String::new())
};
SemanticCommit {
title,
Expand Down
25 changes: 0 additions & 25 deletions repository/src/interpret/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,28 +328,3 @@ pub async fn finalize(
Err(eyre!("commit {} is not a block commit", block_commit_hash))
}
}

pub async fn commit_gitignore(raw: &mut RawRepository) -> Result<(), Error> {
raw.check_clean().await?;
if check_gitignore(raw).await? {
return Err(eyre!(".simperby/ entry already exists in .gitignore"));
}
let path = raw.get_working_directory_path().await?;
let path = std::path::Path::new(&path).join(".gitignore");
let mut file = tokio::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
.await?;
file.write_all(b".simperby/\n").await?;

let commit = RawCommit {
message: "Add `.simperby/` entry to .gitignore".to_string(),
diff: None,
author: "Simperby".to_string(),
email: "hi@simperby.net".to_string(),
timestamp: get_timestamp() / 1000,
};
raw.create_commit_all(commit).await?;
Ok(())
}
16 changes: 0 additions & 16 deletions repository/src/interpret/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,19 +364,3 @@ pub async fn read_blocks(raw: &RawRepository) -> Result<Vec<(CommitHash, Hash256
}
Ok(blocks)
}

pub async fn check_gitignore(raw: &RawRepository) -> Result<bool, Error> {
let path = raw.get_working_directory_path().await?;
let path = std::path::Path::new(&path).join(".gitignore");
if !path.exists() {
return Ok(false);
}
let file = tokio::fs::File::open(path).await?;
let mut lines = tokio::io::BufReader::new(file).lines();
while let Some(line) = lines.next_line().await? {
if line == ".simperby/" {
return Ok(true);
}
}
Ok(false)
}
13 changes: 0 additions & 13 deletions repository/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use simperby_core::*;
use simperby_network::*;
use std::sync::Arc;
use std::{collections::HashSet, fmt};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt};
use tokio::sync::RwLock;

pub use network::RepositoryMessage;
Expand Down Expand Up @@ -158,12 +157,6 @@ impl DistributedRepository {
Ok(true)
}

/// Checks the existence of `.gitignore` file and `.simperby/` entry in `.gitignore`.
/// This returns true if both exist.
pub async fn check_gitignore(&self) -> Result<bool, Error> {
check_gitignore(&*self.raw.read().await).await
}

// ---------------
// Operations that interact with possible local works
// (manually added commits or remote tracking branches)
Expand Down Expand Up @@ -311,12 +304,6 @@ impl DistributedRepository {
finalize(&mut *self.raw.write().await, block_commit_hash, proof).await
}

/// Creates a commit that adds `.simperby/` entry to `.gitignore`.
/// It fails if it exists normally.
pub async fn commit_gitignore(&mut self) -> Result<(), Error> {
commit_gitignore(&mut *self.raw.write().await).await
}

// ---------------
// Tag-related operations
// ---------------
Expand Down
97 changes: 79 additions & 18 deletions repository/src/raw/implementation.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::io::{BufRead, Write};

use super::*;

type Error = super::Error;
Expand Down Expand Up @@ -269,7 +271,7 @@ impl RawRepositoryInner {
let statuses = self.repo.statuses(None)?;
has_changes = statuses
.iter()
.any(|entry| entry.status() != Status::WT_NEW);
.any(|entry| entry.status() == Status::WT_NEW);
}
// Stash before creating a commit if those files exist.
if has_changes {
Expand Down Expand Up @@ -347,18 +349,30 @@ impl RawRepositoryInner {
index.write()?;
let id = index.write_tree()?;
let tree = self.repo.find_tree(id)?;
let head = self.get_head()?;
let parent_oid = Oid::from_bytes(&head.hash)?;
let parent_commit = self.repo.find_commit(parent_oid)?;

let oid = self.repo.commit(
Some("HEAD"),
&signature,
&signature,
&commit.message,
&tree,
&[&parent_commit],
)?;

let oid = match self.repo.head() {
Ok(_) => {
let head = self.get_head()?;
let parent_oid = Oid::from_bytes(&head.hash)?;
let parent_commit = self.repo.find_commit(parent_oid)?;
self.repo.commit(
Some("HEAD"),
&signature,
&signature,
&commit.message,
&tree,
&[&parent_commit],
)?
}
Err(_) => self.repo.commit(
Some("HEAD"),
&signature,
&signature,
&commit.message,
&tree,
&[],
)?,
};
let hash =
<[u8; 20]>::try_from(oid.as_bytes()).map_err(|_| Error::Unknown("err".to_string()))?;
Ok(CommitHash { hash })
Expand All @@ -375,7 +389,7 @@ impl RawRepositoryInner {
let diff = if commit.parent_count() == 0 {
None
} else {
let diff = self.get_patch(commit_hash)?;
let diff = self.get_diff_patch(commit_hash)?;
if diff.is_empty() {
None
} else {
Expand Down Expand Up @@ -495,8 +509,8 @@ impl RawRepositoryInner {
let diff = if diff.deltas().len() == 0 {
Diff::None
} else {
let patch = self.show_commit(commit_hash)?;
let hash = patch.to_hash256();
let diff_patch = self.get_diff_patch(commit_hash)?;
let hash = diff_patch.to_hash256();
Diff::NonReserved(hash)
};
/* TODO: If reserved state
Expand Down Expand Up @@ -532,6 +546,34 @@ impl RawRepositoryInner {
Ok(semantic_commit)
}

pub(crate) fn commit_gitignore(&mut self) -> Result<(), Error> {
self.check_clean()?;
if self.check_gitignore()? {
return Err(Error::Unknown(
".simperby/ entry already exists in .gitignore".to_string(),
));
}
let path = self.get_working_directory_path()?;
let path = std::path::Path::new(&path).join(".gitignore");
let mut file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path.clone())
.map_err(|_| Error::Unknown(format!("failed to open file '{}'", path.display())))?;
file.write_all(b".simperby/\n")
.map_err(|_| Error::Unknown(format!("failed to write file '{}'", path.display())))?;

let commit = RawCommit {
message: "Add `.simperby/` entry to .gitignore".to_string(),
diff: None,
author: "Simperby".to_string(),
email: "hi@simperby.net".to_string(),
timestamp: get_timestamp() / 1000,
};
self.create_commit_all(commit)?;
Ok(())
}

pub(crate) fn run_garbage_collection(&mut self) -> Result<(), Error> {
todo!()
}
Expand Down Expand Up @@ -649,6 +691,25 @@ impl RawRepositoryInner {
Ok(())
}

pub(crate) fn check_gitignore(&self) -> Result<bool, Error> {
let path = self.get_working_directory_path()?;
let path = std::path::Path::new(&path).join(".gitignore");
if !path.exists() {
return Ok(false);
}
let file = std::fs::File::open(path)
.map_err(|_| Error::Unknown("unable to open file".to_string()))?;
let reader = std::io::BufReader::new(file);

for line in reader.lines() {
let line = line.map_err(|_| Error::Unknown("unable to read file".to_string()))?;
if line == ".simperby/" {
return Ok(true);
}
}
Ok(false)
}

pub(crate) fn get_working_directory_path(&self) -> Result<String, Error> {
let path = self
.repo
Expand Down Expand Up @@ -701,7 +762,7 @@ impl RawRepositoryInner {
Ok(CommitHash { hash })
}

pub(crate) fn get_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
pub(crate) fn get_diff_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
let oid = Oid::from_bytes(&commit_hash.hash)?;
let commit = self.repo.find_commit(oid)?;
let tree = commit.tree()?;
Expand All @@ -724,7 +785,7 @@ impl RawRepositoryInner {
Ok(patch)
}

pub(crate) fn show_commit(&self, commit_hash: CommitHash) -> Result<String, Error> {
pub(crate) fn get_email_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
let oid = Oid::from_bytes(&commit_hash.hash)?;
let commit = self.repo.find_commit(oid)?;

Expand Down
26 changes: 19 additions & 7 deletions repository/src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct SemanticCommit {
}

/// A commit related to the actual git commit.
/// - `diff` is a string of git patch which is used to make a git commit.
/// - `diff` is a string of git diff which is used to make a git commit.
/// - `author` is same as the author of git commit.
/// The committer is always same as the author.
/// - `timestamp` is a git timestamp which represents up to seconds.
Expand Down Expand Up @@ -257,6 +257,12 @@ impl RawRepository {
helper_1(self, RawRepositoryInner::read_semantic_commit, commit_hash).await
}

/// Creates a commit that adds `.simperby/` entry to `.gitignore`.
/// It fails if it exists normally.
pub async fn commit_gitignore(&mut self) -> Result<(), Error> {
helper_0_mut(self, RawRepositoryInner::commit_gitignore).await
}

/// Removes orphaned commits. Same as `git gc --prune=now --aggressive`
pub async fn run_garbage_collection(&mut self) -> Result<(), Error> {
helper_0_mut(self, RawRepositoryInner::run_garbage_collection).await
Expand Down Expand Up @@ -309,6 +315,12 @@ impl RawRepository {
helper_0(self, RawRepositoryInner::check_clean).await
}

/// Checks the existence of `.gitignore` file and `.simperby/` entry in `.gitignore`.
/// This returns true if both exist.
pub async fn check_gitignore(&self) -> Result<bool, Error> {
helper_0(self, RawRepositoryInner::check_gitignore).await
}

// ---------------
// Various queries
// ---------------
Expand Down Expand Up @@ -336,14 +348,14 @@ impl RawRepository {
helper_0(self, RawRepositoryInner::get_initial_commit).await
}

/// Returns the patch of the given commit.
pub async fn get_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
helper_1(self, RawRepositoryInner::get_patch, commit_hash).await
/// Returns the diff patch of the given commit.
pub async fn get_diff_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
helper_1(self, RawRepositoryInner::get_diff_patch, commit_hash).await
}

/// Returns the diff of the given commit.
pub async fn show_commit(&self, commit_hash: CommitHash) -> Result<String, Error> {
helper_1(self, RawRepositoryInner::show_commit, commit_hash).await
/// Returns the email patch of the given commit.
pub async fn get_email_patch(&self, commit_hash: CommitHash) -> Result<String, Error> {
helper_1(self, RawRepositoryInner::get_email_patch, commit_hash).await
}

/// Lists the ancestor commits of the given commit (The first element is the direct parent).
Expand Down
Loading