Skip to content

Commit

Permalink
feat: add fetch::Arguments::add_feature() for unconditional additio…
Browse files Browse the repository at this point in the history
…ns of arguments that are supposed to be features.

This differentiation is important to support V1 and V2 correctly, which have a different notion of features with V1
special-casing them, and V2 just sees everything as arguments.
  • Loading branch information
Byron committed Aug 2, 2023
1 parent 090357e commit d1f9c63
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
4 changes: 1 addition & 3 deletions gix-protocol/src/fetch/arguments/blocking_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ impl Arguments {
}
transport.invoke(
Command::Fetch.as_str(),
self.features
.iter()
.filter_map(|(k, v)| v.as_ref().map(|v| (*k, Some(v.as_ref())))),
self.features.iter().filter(|(_, v)| v.is_some()).cloned(),
Some(std::mem::replace(&mut self.args, retained_state).into_iter()),
)
}
Expand Down
32 changes: 21 additions & 11 deletions gix-protocol/src/fetch/arguments/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,20 +165,30 @@ impl Arguments {
pub fn use_include_tag(&mut self) {
debug_assert!(self.supports_include_tag, "'include-tag' feature required");
if self.supports_include_tag {
match self.version {
gix_transport::Protocol::V0 | gix_transport::Protocol::V1 => {
let features = self
.features_for_first_want
.as_mut()
.expect("call use_include_tag before want()");
features.push("include-tag".into())
}
gix_transport::Protocol::V2 => {
self.args.push("include-tag".into());
}
self.add_feature("include-tag");
}
}

/// Add the given `feature`, unconditionally.
///
/// Note that sending an unknown or unsupported feature may cause the remote to terminate
/// the connection. Use this method if you know what you are doing *and* there is no specialized
/// method for this, e.g. [`Self::use_include_tag()`].
pub fn add_feature(&mut self, feature: &str) {
match self.version {
gix_transport::Protocol::V0 | gix_transport::Protocol::V1 => {
let features = self
.features_for_first_want
.as_mut()
.expect("call add_feature before first want()");
features.push(feature.into())
}
gix_transport::Protocol::V2 => {
self.args.push(feature.into());
}
}
}

fn prefixed(&mut self, prefix: &str, value: impl fmt::Display) {
self.args.push(format!("{prefix}{value}").into());
}
Expand Down
5 changes: 5 additions & 0 deletions gix-protocol/src/fetch/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ mod arguments {
assert!(arguments.is_stateless(true), "V2 is stateless…");
assert!(arguments.is_stateless(false), "…in all cases");

arguments.add_feature("no-progress");
arguments.deepen(1);
arguments.deepen_relative();
arguments.want(id("7b333369de1221f9bfbbe03a3a13e9a09bc1c907"));
Expand All @@ -329,6 +330,7 @@ mod arguments {
b"0012command=fetch
0001000ethin-pack
000eofs-delta
0010no-progress
000ddeepen 1
0014deepen-relative
0032want 7b333369de1221f9bfbbe03a3a13e9a09bc1c907
Expand All @@ -347,6 +349,7 @@ mod arguments {
let mut t = transport(&mut out, *is_stateful);
let mut arguments = arguments_v2(Some("shallow"));

arguments.add_feature("no-progress");
arguments.deepen(1);
arguments.deepen_since(12345);
arguments.shallow(id("7b333369de1221f9bfbbe03a3a13e9a09bc1c9ff"));
Expand All @@ -362,6 +365,7 @@ mod arguments {
b"0012command=fetch
0001000ethin-pack
000eofs-delta
0010no-progress
000ddeepen 1
0017deepen-since 12345
0035shallow 7b333369de1221f9bfbbe03a3a13e9a09bc1c9ff
Expand All @@ -371,6 +375,7 @@ mod arguments {
00000012command=fetch
0001000ethin-pack
000eofs-delta
0010no-progress
000ddeepen 1
0017deepen-since 12345
0035shallow 7b333369de1221f9bfbbe03a3a13e9a09bc1c9ff
Expand Down

0 comments on commit d1f9c63

Please sign in to comment.