Skip to content

Commit

Permalink
feat: add push.default config key
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 18, 2023
1 parent 3e13152 commit 8ac2dcc
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 2 deletions.
7 changes: 5 additions & 2 deletions gix/src/config/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub(crate) mod root {
pub const PACK: sections::Pack = sections::Pack;
/// The `protocol` section.
pub const PROTOCOL: sections::Protocol = sections::Protocol;
/// The `push` section.
pub const PUSH: sections::Push = sections::Push;
/// The `remote` section.
pub const REMOTE: sections::Remote = sections::Remote;
/// The `safe` section.
Expand Down Expand Up @@ -83,6 +85,7 @@ pub(crate) mod root {
&Self::MAILMAP,
&Self::PACK,
&Self::PROTOCOL,
&Self::PUSH,
&Self::REMOTE,
&Self::SAFE,
&Self::SSH,
Expand All @@ -95,9 +98,9 @@ pub(crate) mod root {

mod sections;
pub use sections::{
branch, checkout, core, credential, extensions, fetch, gitoxide, http, index, protocol, remote, ssh, Author,
branch, checkout, core, credential, extensions, fetch, gitoxide, http, index, protocol, push, remote, ssh, Author,
Branch, Checkout, Clone, Committer, Core, Credential, Extensions, Fetch, Gitoxide, Http, Index, Init, Mailmap,
Pack, Protocol, Remote, Safe, Ssh, Url, User,
Pack, Protocol, Push, Remote, Safe, Ssh, Url, User,
};
#[cfg(feature = "blob-diff")]
pub use sections::{diff, Diff};
Expand Down
5 changes: 5 additions & 0 deletions gix/src/config/tree/sections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ pub mod pack;
pub struct Protocol;
pub mod protocol;

/// The `push` top-level section.
#[derive(Copy, Clone, Default)]
pub struct Push;
pub mod push;

/// The `remote` top-level section.
#[derive(Copy, Clone, Default)]
pub struct Remote;
Expand Down
64 changes: 64 additions & 0 deletions gix/src/config/tree/sections/push.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::{
config,
config::tree::{keys, Key, Push, Section},
};

impl Push {
/// The `push.default` key
pub const DEFAULT: Default = Default::new_with_validate("default", &config::Tree::PUSH, validate::Default);
}

impl Section for Push {
fn name(&self) -> &str {
"push"
}

fn keys(&self) -> &[&dyn Key] {
&[&Self::DEFAULT]
}
}

/// The `remote.<name>.tagOpt` key type.
pub type Default = keys::Any<validate::Default>;

mod default {
use std::borrow::Cow;

use crate::{
bstr::{BStr, ByteSlice},
config,
config::tree::push::Default,
push,
};

impl Default {
/// Try to interpret `value` as `push.default`.
pub fn try_into_default(
&'static self,
value: Cow<'_, BStr>,
) -> Result<push::Default, config::key::GenericErrorWithValue> {
Ok(match value.as_ref().as_bytes() {
b"nothing" => push::Default::Nothing,
b"current" => push::Default::Current,
b"upstream" | b"tracking" => push::Default::Upstream,
b"simple" => push::Default::Simple,
b"matching" => push::Default::Matching,
_ => return Err(config::key::GenericErrorWithValue::from_value(self, value.into_owned())),
})
}
}
}

mod validate {
pub struct Default;
use std::{borrow::Cow, error::Error};

use crate::{bstr::BStr, config::tree::keys::Validate};

impl Validate for Default {
fn validate(&self, value: &BStr) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
super::Push::DEFAULT.try_into_default(Cow::Borrowed(value))?;
Ok(())
}
}
}
2 changes: 2 additions & 0 deletions gix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ pub mod tag;

///
pub mod progress;
///
pub mod push;

///
pub mod diff;
Expand Down
21 changes: 21 additions & 0 deletions gix/src/push.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// All possible values of `push.default`.
#[derive(Default, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Debug)]
pub enum Default {
/// Do not push anything unless a refspec is provided explicitly.
///
/// This is for safety.
Nothing,
/// Push the current branch to update a remote branch with the same name.
Current,
/// Push the current branch to the branch it would fetch from and merge with,
/// i.e. what is configured in `branch.<name>.merge`, retrievable with
/// the `@{upstream}` refspec.
Upstream,
/// Push the current branch with the same name to the remote.
/// This is the same as [`Current`](Default::Current), but fails if
/// `branch.<name>.merge` is set to a branch that is named differently.
#[default]
Simple,
/// Push *all* branches to their similarly named counterpart on the remote.
Matching,
}
27 changes: 27 additions & 0 deletions gix/tests/config/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,33 @@ mod ssh {
}
}

mod push {
use crate::config::tree::bcow;
use gix::config::tree::Push;
use gix::push;

#[test]
fn default() -> crate::Result {
for (actual, expected) in [
("nothing", push::Default::Nothing),
("current", push::Default::Current),
("upstream", push::Default::Upstream),
("tracking", push::Default::Upstream),
("simple", push::Default::Simple),
("matching", push::Default::Matching),
] {
assert_eq!(Push::DEFAULT.try_into_default(bcow(actual))?, expected);
}

assert_eq!(
Push::DEFAULT.try_into_default(bcow("Nothing")).unwrap_err().to_string(),
"The key \"push.default=Nothing\" was invalid",
"case-sensitive comparisons"
);
Ok(())
}
}

mod fetch {

#[test]
Expand Down

0 comments on commit 8ac2dcc

Please sign in to comment.