split up stuff into new remote mod

This commit is contained in:
Stephan Dilly 2021-02-24 11:32:38 +01:00
parent a53ec16161
commit 59acccc484
5 changed files with 205 additions and 184 deletions

View file

@ -1,4 +1,7 @@
use crate::{error::Result, sync};
use crate::{
error::Result,
sync::{self, branch::get_branch_name},
};
use sync::Head;
///
@ -38,7 +41,7 @@ impl BranchName {
}
fn fetch(&mut self, head: Head) -> Result<String> {
let name = sync::get_branch_name(self.repo_path.as_str())?;
let name = get_branch_name(self.repo_path.as_str())?;
self.last_result = Some((head, name.clone()));
Ok(name)
}

View file

@ -1,7 +1,10 @@
use crate::sync::cred::BasicAuthCredential;
use crate::{
error::{Error, Result},
sync, AsyncNotification, CWD,
sync::{
cred::BasicAuthCredential, remotes::push::push,
remotes::push::ProgressNotification,
},
AsyncNotification, CWD,
};
use crossbeam_channel::{unbounded, Receiver, Sender};
use git2::PackBuilderStage;
@ -11,7 +14,6 @@ use std::{
thread,
time::Duration,
};
use sync::ProgressNotification;
use thread::JoinHandle;
///
@ -162,7 +164,7 @@ impl AsyncPush {
arc_progress,
);
let res = sync::push(
let res = push(
CWD,
params.remote.as_str(),
params.branch.as_str(),

View file

@ -3,7 +3,7 @@
//TODO: remove once we have this activated on the toplevel
#![deny(clippy::expect_used)]
mod branch;
pub mod branch;
mod commit;
mod commit_details;
mod commit_files;
@ -14,14 +14,13 @@ mod hooks;
mod hunks;
mod ignore;
mod logwalker;
mod remotes;
pub mod remotes;
mod reset;
mod stash;
pub mod status;
mod tags;
pub mod utils;
pub(crate) use branch::get_branch_name;
pub use branch::{
branch_compare_upstream, checkout_branch, create_branch,
delete_branch, get_branches_to_display, rename_branch,
@ -40,10 +39,7 @@ pub use hooks::{
pub use hunks::{reset_hunk, stage_hunk, unstage_hunk};
pub use ignore::add_to_ignore;
pub use logwalker::LogWalker;
pub use remotes::{
fetch_origin, get_default_remote, get_remotes, push,
ProgressNotification,
};
pub use remotes::{fetch_origin, get_default_remote, get_remotes};
pub use reset::{reset_stage, reset_workdir};
pub use stash::{get_stashes, stash_apply, stash_drop, stash_save};
pub use tags::{get_tags, CommitTags, Tags};

View file

@ -0,0 +1,177 @@
//!
pub(crate) mod push;
use crate::{
error::{Error, Result},
sync::utils,
};
use git2::{FetchOptions, Repository};
use push::remote_callbacks;
use scopetime::scope_time;
/// origin
pub const DEFAULT_REMOTE_NAME: &str = "origin";
///
pub fn get_remotes(repo_path: &str) -> Result<Vec<String>> {
scope_time!("get_remotes");
let repo = utils::repo(repo_path)?;
let remotes = repo.remotes()?;
let remotes: Vec<String> =
remotes.iter().flatten().map(String::from).collect();
Ok(remotes)
}
/// tries to find origin or the only remote that is defined if any
/// in case of multiple remotes and none named *origin* we fail
pub fn get_default_remote(repo_path: &str) -> Result<String> {
let repo = utils::repo(repo_path)?;
get_default_remote_in_repo(&repo)
}
/// see `get_default_remote`
pub(crate) fn get_default_remote_in_repo(
repo: &Repository,
) -> Result<String> {
scope_time!("get_default_remote_in_repo");
let remotes = repo.remotes()?;
// if `origin` exists return that
let found_origin = remotes.iter().any(|r| {
r.map(|r| r == DEFAULT_REMOTE_NAME).unwrap_or_default()
});
if found_origin {
return Ok(DEFAULT_REMOTE_NAME.into());
}
//if only one remote exists pick that
if remotes.len() == 1 {
let first_remote = remotes
.iter()
.next()
.flatten()
.map(String::from)
.ok_or_else(|| {
Error::Generic("no remote found".into())
})?;
return Ok(first_remote);
}
//inconclusive
Err(Error::NoDefaultRemoteFound)
}
///
pub fn fetch_origin(repo_path: &str, branch: &str) -> Result<usize> {
scope_time!("fetch_origin");
let repo = utils::repo(repo_path)?;
let mut remote =
repo.find_remote(&get_default_remote_in_repo(&repo)?)?;
let mut options = FetchOptions::new();
options.remote_callbacks(remote_callbacks(None, None));
remote.fetch(&[branch], Some(&mut options), None)?;
Ok(remote.stats().received_bytes())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sync::tests::debug_cmd_print;
use tempfile::TempDir;
#[test]
fn test_smoke() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(remotes, vec![String::from("origin")]);
fetch_origin(repo_path, "master").unwrap();
}
#[test]
fn test_default_remote() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote add second https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(
remotes,
vec![String::from("origin"), String::from("second")]
);
let first = get_default_remote_in_repo(
&utils::repo(repo_path).unwrap(),
)
.unwrap();
assert_eq!(first, String::from("origin"));
}
#[test]
fn test_default_remote_out_of_order() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote rename origin alternate",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote add origin https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
//NOTE: aparently remotes are not chronolically sorted but alphabetically
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(
remotes,
vec![String::from("alternate"), String::from("origin")]
);
let first = get_default_remote_in_repo(
&utils::repo(repo_path).unwrap(),
)
.unwrap();
assert_eq!(first, String::from("origin"));
}
}

View file

@ -1,23 +1,21 @@
//!
use super::{branch::branch_set_upstream, CommitId};
use super::utils;
use crate::{
error::{Error, Result},
sync::cred::BasicAuthCredential,
sync::utils,
error::Result,
sync::{
branch::branch_set_upstream, cred::BasicAuthCredential,
CommitId,
},
};
use crossbeam_channel::Sender;
use git2::{
Cred, Error as GitError, FetchOptions, PackBuilderStage,
PushOptions, RemoteCallbacks, Repository,
Cred, Error as GitError, PackBuilderStage, PushOptions,
RemoteCallbacks,
};
use scopetime::scope_time;
pub const DEFAULT_REMOTE_NAME: &str = "origin";
///
#[derive(Debug, Clone)]
pub enum ProgressNotification {
pub(crate) enum ProgressNotification {
///
UpdateTips {
///
@ -57,76 +55,7 @@ pub enum ProgressNotification {
}
///
pub fn get_remotes(repo_path: &str) -> Result<Vec<String>> {
scope_time!("get_remotes");
let repo = utils::repo(repo_path)?;
let remotes = repo.remotes()?;
let remotes: Vec<String> =
remotes.iter().flatten().map(String::from).collect();
Ok(remotes)
}
/// tries to find origin or the only remote that is defined if any
/// in case of multiple remotes and none named *origin* we fail
pub fn get_default_remote(repo_path: &str) -> Result<String> {
let repo = utils::repo(repo_path)?;
get_default_remote_in_repo(&repo)
}
/// see `get_default_remote`
pub(crate) fn get_default_remote_in_repo(
repo: &Repository,
) -> Result<String> {
scope_time!("get_default_remote_in_repo");
let remotes = repo.remotes()?;
// if `origin` exists return that
let found_origin = remotes.iter().any(|r| {
r.map(|r| r == DEFAULT_REMOTE_NAME).unwrap_or_default()
});
if found_origin {
return Ok(DEFAULT_REMOTE_NAME.into());
}
//if only one remote exists pick that
if remotes.len() == 1 {
let first_remote = remotes
.iter()
.next()
.flatten()
.map(String::from)
.ok_or_else(|| {
Error::Generic("no remote found".into())
})?;
return Ok(first_remote);
}
//inconclusive
Err(Error::NoDefaultRemoteFound)
}
///
pub fn fetch_origin(repo_path: &str, branch: &str) -> Result<usize> {
scope_time!("fetch_origin");
let repo = utils::repo(repo_path)?;
let mut remote =
repo.find_remote(&get_default_remote_in_repo(&repo)?)?;
let mut options = FetchOptions::new();
options.remote_callbacks(remote_callbacks(None, None));
remote.fetch(&[branch], Some(&mut options), None)?;
Ok(remote.stats().received_bytes())
}
///
pub fn push(
pub(crate) fn push(
repo_path: &str,
remote: &str,
branch: &str,
@ -161,7 +90,7 @@ pub fn push(
Ok(())
}
fn remote_callbacks<'a>(
pub(crate) fn remote_callbacks<'a>(
sender: Option<Sender<ProgressNotification>>,
basic_credential: Option<BasicAuthCredential>,
) -> RemoteCallbacks<'a> {
@ -278,101 +207,15 @@ fn remote_callbacks<'a>(
#[cfg(test)]
mod tests {
use git2::Repository;
use super::*;
use crate::sync::{
self,
tests::{debug_cmd_print, repo_init, repo_init_bare},
tests::{repo_init, repo_init_bare},
LogWalker,
};
use std::{fs::File, io::Write, path::Path};
use tempfile::TempDir;
#[test]
fn test_smoke() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(remotes, vec![String::from("origin")]);
fetch_origin(repo_path, "master").unwrap();
}
#[test]
fn test_default_remote() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote add second https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(
remotes,
vec![String::from("origin"), String::from("second")]
);
let first = get_default_remote_in_repo(
&utils::repo(repo_path).unwrap(),
)
.unwrap();
assert_eq!(first, String::from("origin"));
}
#[test]
fn test_default_remote_out_of_order() {
let td = TempDir::new().unwrap();
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"git clone https://github.com/extrawurst/brewdump.git",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote rename origin alternate",
);
debug_cmd_print(
td.path().as_os_str().to_str().unwrap(),
"cd brewdump && git remote add origin https://github.com/extrawurst/brewdump.git",
);
let repo_path = td.path().join("brewdump");
let repo_path = repo_path.as_os_str().to_str().unwrap();
//NOTE: aparently remotes are not chronolically sorted but alphabetically
let remotes = get_remotes(repo_path).unwrap();
assert_eq!(
remotes,
vec![String::from("alternate"), String::from("origin")]
);
let first = get_default_remote_in_repo(
&utils::repo(repo_path).unwrap(),
)
.unwrap();
assert_eq!(first, String::from("origin"));
}
#[test]
fn test_force_push() {