Onboard iPhone password-store clone
This commit is contained in:
@@ -6,7 +6,7 @@ use std::{
|
||||
error::Error,
|
||||
fs,
|
||||
io::Cursor,
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
@@ -204,6 +204,22 @@ impl GitFetchTransport for CloningFetch {
|
||||
}
|
||||
}
|
||||
|
||||
struct OccupyingFetch(PathBuf);
|
||||
|
||||
impl GitFetchTransport for OccupyingFetch {
|
||||
fn fetch(
|
||||
&self,
|
||||
repository: &GitRepository,
|
||||
configured: &GitRemote,
|
||||
credential: &GitCredential,
|
||||
) -> Result<bool, GitError> {
|
||||
let fetched = CloningFetch.fetch(repository, configured, credential)?;
|
||||
fs::write(self.0.join("keep"), b"concurrent contents")
|
||||
.map_err(|error| GitError::InvalidRepository(error.to_string()))?;
|
||||
Ok(fetched)
|
||||
}
|
||||
}
|
||||
|
||||
struct NoopFetch;
|
||||
|
||||
impl GitFetchTransport for NoopFetch {
|
||||
@@ -547,6 +563,102 @@ fn clone_uses_a_private_directory_and_injected_fetch_transport() -> TestResult {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn branch_discovery_and_controlled_clone_stay_inside_rust() -> TestResult {
|
||||
let temporary = tempfile::tempdir()?;
|
||||
let config = remote_config(&temporary)?;
|
||||
let remote = &config.git_remotes()[0];
|
||||
let control = GitOperationControl::default();
|
||||
let branches = GitRepository::discover_remote_branches_with_transport(
|
||||
temporary.path(),
|
||||
identity(),
|
||||
remote,
|
||||
&Credentials,
|
||||
&CloningFetch,
|
||||
&control,
|
||||
)?;
|
||||
assert_eq!(branches, ["main"]);
|
||||
assert!(
|
||||
!temporary
|
||||
.path()
|
||||
.read_dir()?
|
||||
.filter_map(Result::ok)
|
||||
.any(|entry| {
|
||||
entry
|
||||
.file_name()
|
||||
.to_string_lossy()
|
||||
.starts_with(".ironstorage-probe-")
|
||||
})
|
||||
);
|
||||
|
||||
let destination = temporary.path().join("selected-branch");
|
||||
let cloned = GitRepository::clone_into_with_transport_controlled(
|
||||
&destination,
|
||||
identity(),
|
||||
remote,
|
||||
Some(&branches[0]),
|
||||
&Credentials,
|
||||
&CloningFetch,
|
||||
&control,
|
||||
)?;
|
||||
assert_eq!(cloned.current_branch()?, "main");
|
||||
assert_eq!(fs::read(destination.join(".gpg-id"))?, b"ALICE\n");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cancelled_clone_never_touches_an_existing_destination() -> TestResult {
|
||||
let temporary = tempfile::tempdir()?;
|
||||
let config = remote_config(&temporary)?;
|
||||
let destination = temporary.path().join("existing");
|
||||
fs::create_dir(&destination)?;
|
||||
fs::write(destination.join("keep"), b"unchanged")?;
|
||||
let control = GitOperationControl::default();
|
||||
control.cancel();
|
||||
let result = GitRepository::clone_into_with_transport_controlled(
|
||||
&destination,
|
||||
identity(),
|
||||
&config.git_remotes()[0],
|
||||
Some("main"),
|
||||
&Credentials,
|
||||
&CloningFetch,
|
||||
&control,
|
||||
);
|
||||
assert!(matches!(result, Err(GitError::Cancelled)));
|
||||
assert_eq!(fs::read(destination.join("keep"))?, b"unchanged");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_race_preserves_the_destination_and_removes_private_work() -> TestResult {
|
||||
let temporary = tempfile::tempdir()?;
|
||||
let config = remote_config(&temporary)?;
|
||||
let destination = temporary.path().join("concurrent");
|
||||
fs::create_dir(&destination)?;
|
||||
let result = GitRepository::clone_into_with_transport(
|
||||
&destination,
|
||||
identity(),
|
||||
&config.git_remotes()[0],
|
||||
&Credentials,
|
||||
&OccupyingFetch(destination.clone()),
|
||||
);
|
||||
assert!(matches!(result, Err(GitError::Io { .. })));
|
||||
assert_eq!(fs::read(destination.join("keep"))?, b"concurrent contents");
|
||||
assert!(
|
||||
!temporary
|
||||
.path()
|
||||
.read_dir()?
|
||||
.filter_map(Result::ok)
|
||||
.any(|entry| {
|
||||
entry
|
||||
.file_name()
|
||||
.to_string_lossy()
|
||||
.starts_with(".ironstorage-clone-")
|
||||
})
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signed_commits_have_a_verifiable_ascii_armored_gpgsig() -> TestResult {
|
||||
let fixture = FixtureSet::load()?;
|
||||
|
||||
Reference in New Issue
Block a user