History

[git-protocol] move everything into `blocking_io` for later translation…

…into async-io, as usual.

Sebastian Thiel committed 5 years ago

Commit fa033741 parent 0d39b5d12 files · +295 −254Browse files

Showing the changes to git-protocol/src/fetch/command.rs (1 of 12 files). Show all

Unified · Split

git-protocol/src/fetch/command.rs+0−196
@@ -1,196 +0,0 @@
1−use crate::fetch::agent;
2−use bstr::{BString, ByteSlice};
3−use git_transport::client::Capabilities;
4−
5−/// The kind of command to invoke on the server side.
6−#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
7−pub enum Command {
8− /// List references.
9− LsRefs,
10− /// Fetch a pack.
11− Fetch,
12−}
13−
14−/// A key value pair of values known at compile time.
15−pub type Feature = (&'static str, Option<&'static str>);
16−
17−impl Command {
18− /// Produce the name of the command as known by the server side.
19− pub fn as_str(&self) -> &'static str {
20− match self {
21− Command::LsRefs => "ls-refs",
22− Command::Fetch => "fetch",
23− }
24− }
25−
26− /// Only V2
27− fn all_argument_prefixes(&self) -> &'static [&'static str] {
28− match self {
29− Command::LsRefs => &["symrefs", "peel", "ref-prefix "],
30− Command::Fetch => &[
31− "want ", // hex oid
32− "have ", // hex oid
33− "done",
34− "thin-pack",
35− "no-progress",
36− "include-tag",
37− "ofs-delta",
38− // Shallow feature/capability
39− "shallow ", // hex oid
40− "deepen ", // commit depth
41− "deepen-relative",
42− "deepen-since ", // time-stamp
43− "deepen-not ", // rev
44− // filter feature/capability
45− "filter ", // filter-spec
46− // ref-in-want feature
47− "want-ref ", // ref path
48− "sideband-all",
49− // packfile-uris feature
50− "packfile-uris ", // protocols
51− ],
52− }
53− }
54−
55− fn all_features(&self, version: git_transport::Protocol) -> &'static [&'static str] {
56− match self {
57− Command::LsRefs => &[],
58− Command::Fetch => match version {
59− git_transport::Protocol::V1 => &[
60− "multi_ack",
61− "thin-pack",
62− "side-band",
63− "side-band-64k",
64− "ofs-delta",
65− "shallow",
66− "deepen-since",
67− "deepen-not",
68− "deepen-relative",
69− "no-progress",
70− "include-tag",
71− "multi_ack_detailed",
72− "allow-tip-sha1-in-want",
73− "allow-reachable-sha1-in-want",
74− "no-done",
75− "filter",
76− ],
77− git_transport::Protocol::V2 => &["shallow", "filter", "ref-in-want", "sideband-all", "packfile-uris"],
78− },
79− }
80− }
81−
82− /// Compute initial arguments based on the given `features`. They are typically provided by the `default_features(…)` method.
83− /// Only useful for V2
84− pub(crate) fn initial_arguments(&self, features: &[Feature]) -> Vec<BString> {
85− match self {
86− Command::Fetch => ["thin-pack", "include-tag", "ofs-delta"]
87− .iter()
88− .map(|s| s.as_bytes().as_bstr().to_owned())
89− .chain(
90− ["sideband-all", "ref-in-want", "packfile-uris"]
91− .iter()
92− .filter(|f| features.iter().any(|(sf, _)| sf == *f))
93− .map(|f| f.as_bytes().as_bstr().to_owned()),
94− )
95− .collect(),
96− Command::LsRefs => vec![b"symrefs".as_bstr().to_owned(), b"peel".as_bstr().to_owned()],
97− }
98− }
99−
100− pub(crate) fn default_features(
101− &self,
102− version: git_transport::Protocol,
103− server_capabilities: &Capabilities,
104− ) -> Vec<Feature> {
105− match self {
106− Command::Fetch => match version {
107− git_transport::Protocol::V1 => {
108− let has_multi_ack_detailed = server_capabilities.contains("multi_ack_detailed");
109− let has_sideband_64k = server_capabilities.contains("side-band-64k");
110− self.all_features(version)
111− .iter()
112− .copied()
113− .filter(|feature| match *feature {
114− "side-band" if has_sideband_64k => false,
115− "multi_ack" if has_multi_ack_detailed => false,
116− "include-tag" | "no-progress" => false,
117− feature => server_capabilities.contains(feature),
118− })
119− .map(|s| (s, None))
120− .chain(Some(agent()))
121− .collect()
122− }
123− git_transport::Protocol::V2 => {
124− let supported_features = server_capabilities
125− .iter()
126− .find_map(|c| {
127− if c.name() == Command::Fetch.as_str().as_bytes().as_bstr() {
128− c.values().map(|v| v.map(|f| f.to_owned()).collect())
129− } else {
130− None
131− }
132− })
133− .unwrap_or_else(Vec::new);
134− self.all_features(version)
135− .iter()
136− .copied()
137− .filter(|feature| supported_features.iter().any(|supported| supported == feature))
138− .map(|s| (s, None))
139− .chain(Some(agent()))
140− .collect()
141− }
142− },
143− Command::LsRefs => vec![agent()],
144− }
145− }
146− /// Panics if the given arguments and features don't match what's statically known. It's considered a bug in the delegate.
147− pub(crate) fn validate_argument_prefixes_or_panic(
148− &self,
149− version: git_transport::Protocol,
150− server: &Capabilities,
151− arguments: &[BString],
152− features: &[Feature],
153− ) {
154− let allowed = self.all_argument_prefixes();
155− for arg in arguments {
156− if allowed.iter().any(|allowed| arg.starts_with(allowed.as_bytes())) {
157− continue;
158− }
159− panic!("{}: argument {} is not known or allowed", self.as_str(), arg);
160− }
161− match version {
162− git_transport::Protocol::V1 => {
163− for (feature, _) in features {
164− if server
165− .iter()
166− .any(|c| feature.starts_with(c.name().to_str_lossy().as_ref()))
167− {
168− continue;
169− }
170− panic!("{}: capability {} is not supported", self.as_str(), feature);
171− }
172− }
173− git_transport::Protocol::V2 => {
174− let allowed = server
175− .iter()
176− .find_map(|c| {
177− if c.name() == self.as_str().as_bytes().as_bstr() {
178− c.values().map(|v| v.map(|f| f.to_string()).collect::<Vec<_>>())
179− } else {
180− None
181− }
182− })
183− .unwrap_or_default();
184− for (feature, _) in features {
185− if allowed.iter().any(|allowed| feature == allowed) {
186− continue;
187− }
188− match *feature {
189− "agent" => {}
190− _ => panic!("{}: V2 feature/capability {} is not supported", self.as_str(), feature),
191− }
192− }
193− }
194− }
195− }
196−}