Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6778447

Browse files
committed
[clone] make URL available in transport layer
1 parent df617fd commit 6778447

14 files changed

Lines changed: 112 additions & 74 deletions

File tree

git-transport/src/client/connect.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ quick_error! {
1818
from()
1919
source(&**err)
2020
}
21-
UnsupportedUrlTokens(url: bstr::BString, scheme: git_url::Protocol) {
21+
UnsupportedUrlTokens(url: bstr::BString, scheme: git_url::Scheme) {
2222
display("The url '{}' contains information that would not be used by the '{}' protocol", url, scheme)
2323
}
2424
#[cfg(not(feature = "http-client-curl"))]
25-
CompiledWithoutHttp(scheme: git_url::Protocol) {
25+
CompiledWithoutHttp(scheme: git_url::Scheme) {
2626
display("'{}' is not compiled in. Compile with the 'http' cargo feature", scheme)
2727
}
2828
}
@@ -32,17 +32,17 @@ quick_error! {
3232
pub fn connect(url: &[u8], version: crate::Protocol) -> Result<Box<dyn Transport>, Error> {
3333
let urlb = url;
3434
let url = git_url::parse(urlb)?;
35-
Ok(match url.protocol {
36-
git_url::Protocol::File => {
35+
Ok(match url.scheme {
36+
git_url::Scheme::File => {
3737
if url.user.is_some() || url.host.is_some() || url.port.is_some() {
38-
return Err(Error::UnsupportedUrlTokens(urlb.into(), url.protocol));
38+
return Err(Error::UnsupportedUrlTokens(urlb.into(), url.scheme));
3939
}
4040
Box::new(
4141
crate::client::file::connect(url.path)
4242
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?,
4343
)
4444
}
45-
git_url::Protocol::Ssh => Box::new(
45+
git_url::Scheme::Ssh => Box::new(
4646
crate::client::ssh::connect(
4747
&url.host.as_ref().expect("host is present in url"),
4848
url.path,
@@ -52,9 +52,9 @@ pub fn connect(url: &[u8], version: crate::Protocol) -> Result<Box<dyn Transport
5252
)
5353
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?,
5454
),
55-
git_url::Protocol::Git => {
55+
git_url::Scheme::Git => {
5656
if url.user.is_some() {
57-
return Err(Error::UnsupportedUrlTokens(urlb.into(), url.protocol));
57+
return Err(Error::UnsupportedUrlTokens(urlb.into(), url.scheme));
5858
}
5959
Box::new(
6060
crate::client::git::connect(
@@ -67,9 +67,9 @@ pub fn connect(url: &[u8], version: crate::Protocol) -> Result<Box<dyn Transport
6767
)
6868
}
6969
#[cfg(not(feature = "http-client-curl"))]
70-
git_url::Protocol::Https | git_url::Protocol::Http => return Err(Error::CompiledWithoutHttp(url.protocol)),
70+
git_url::Scheme::Https | git_url::Scheme::Http => return Err(Error::CompiledWithoutHttp(url.scheme)),
7171
#[cfg(feature = "http-client-curl")]
72-
git_url::Protocol::Https | git_url::Protocol::Http => {
72+
git_url::Scheme::Https | git_url::Scheme::Http => {
7373
use bstr::ByteSlice;
7474
Box::new(
7575
crate::client::http::connect(urlb.to_str()?, version)

git-transport/src/client/file.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const ENV_VARS_TO_REMOVE: &[&str] = &[
2525
];
2626

2727
pub struct SpawnProcessOnDemand {
28+
url: git_url::Url,
2829
path: BString,
2930
ssh_program: Option<String>,
3031
ssh_args: Vec<String>,
@@ -43,12 +44,14 @@ impl Drop for SpawnProcessOnDemand {
4344

4445
impl SpawnProcessOnDemand {
4546
pub(crate) fn new_ssh(
47+
url: git_url::Url,
4648
program: String,
4749
args: impl IntoIterator<Item = impl Into<String>>,
4850
env: impl IntoIterator<Item = (&'static str, impl Into<String>)>,
4951
path: BString,
5052
) -> SpawnProcessOnDemand {
5153
SpawnProcessOnDemand {
54+
url,
5255
path,
5356
ssh_program: Some(program),
5457
ssh_args: args.into_iter().map(|s| s.into()).collect(),
@@ -57,8 +60,15 @@ impl SpawnProcessOnDemand {
5760
connection: None,
5861
}
5962
}
60-
pub(crate) fn new(path: BString) -> SpawnProcessOnDemand {
63+
pub(crate) fn new_local(path: BString) -> SpawnProcessOnDemand {
6164
SpawnProcessOnDemand {
65+
url: git_url::Url {
66+
scheme: git_url::Scheme::File,
67+
user: None,
68+
host: None,
69+
port: None,
70+
path: path.clone(),
71+
},
6272
path,
6373
ssh_program: None,
6474
ssh_args: Vec::new(),
@@ -110,8 +120,12 @@ impl client::Transport for SpawnProcessOnDemand {
110120
.expect("handshake() to have been called first")
111121
.request(write_mode, on_drop)
112122
}
123+
124+
fn to_url(&self) -> String {
125+
self.url.to_string()
126+
}
113127
}
114128

115129
pub fn connect(path: impl Into<BString>) -> Result<SpawnProcessOnDemand, std::convert::Infallible> {
116-
Ok(SpawnProcessOnDemand::new(path.into()))
130+
Ok(SpawnProcessOnDemand::new_local(path.into()))
117131
}

git-transport/src/client/git.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ where
118118
on_drop,
119119
))
120120
}
121+
fn to_url(&self) -> String {
122+
git_url::Url {
123+
scheme: git_url::Scheme::File,
124+
user: None,
125+
host: None,
126+
port: None,
127+
path: self.path.clone(),
128+
}
129+
.to_string()
130+
}
121131
}
122132

123133
impl<R, W> Connection<R, W>

git-transport/src/client/http/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ impl<H: Http> client::Transport for Transport<H> {
164164
on_drop,
165165
))
166166
}
167+
fn to_url(&self) -> String {
168+
self.url.to_owned()
169+
}
167170
}
168171

169172
struct HeadersThenBody<H: Http, B> {

git-transport/src/client/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ pub trait Transport {
210210
/// which messages to write when the writer is dropped. This happens naturally when switching to reading the response with `into_read()`.
211211
/// If `handle_progress` is not None, it's function passed a text line without trailing LF from which progress information can be parsed.
212212
fn request(&mut self, write_mode: WriteMode, on_drop: Vec<MessageKind>) -> Result<RequestWriter, Error>;
213+
214+
/// Returns the canonical URL pointing to the destination of this transport.
215+
/// Please note that local paths may not be represented correctly, as they will go through a potentially lossy
216+
/// unicode conversion.
217+
fn to_url(&self) -> String;
213218
}
214219

215220
pub trait TransportV2Ext {

git-transport/src/client/ssh.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,27 @@ pub fn connect(
3939
_ => return Err(Error::UnsupportedSshCommand(ssh_cmd.into())),
4040
};
4141

42-
let host = match user {
42+
let host = match user.as_ref() {
4343
Some(user) => format!("{}@{}", user, host),
4444
None => host.into(),
4545
};
46+
let url = git_url::Url {
47+
scheme: git_url::Scheme::Ssh,
48+
user: user.map(Into::into),
49+
host: Some(host.clone()),
50+
port,
51+
path: path.clone(),
52+
};
4653
Ok(match args_and_env {
4754
Some((args, envs)) => client::file::SpawnProcessOnDemand::new_ssh(
55+
url,
4856
ssh_cmd.into(),
4957
ssh_cmd_line.map(Cow::from).chain(args).chain(Some(host.into())),
5058
envs,
5159
path,
5260
),
5361
None => client::file::SpawnProcessOnDemand::new_ssh(
62+
url,
5463
ssh_cmd.into(),
5564
ssh_cmd_line.chain(Some(host.as_str())),
5665
None::<(&str, String)>,

git-transport/tests/client/git.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ fn handshake_v1_and_request() -> crate::Result {
6666
Some(("example.org", None)),
6767
git::ConnectMode::Daemon,
6868
);
69+
assert_eq!(c.to_url(), "file:///foo.git");
6970
let mut res = c.handshake(Service::UploadPack)?;
7071
assert_eq!(res.actual_protocol, Protocol::V1);
7172
assert_eq!(

git-transport/tests/client/http/mock.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::fixture_bytes;
22
use bstr::ByteVec;
3+
use git_transport::client::Transport;
34
use git_transport::{client::http, Protocol};
45
use std::{
56
io::{Read, Write},
@@ -101,14 +102,13 @@ pub fn serve_and_connect(
101102
version: Protocol,
102103
) -> Result<(Server, http::Transport<http::Impl>), crate::Error> {
103104
let server = serve_once(name);
104-
let client = git_transport::client::http::connect(
105-
&format!(
106-
"http://{}:{}/{}",
107-
&server.addr().ip().to_string(),
108-
&server.addr().port(),
109-
path
110-
),
111-
version,
112-
)?;
105+
let url = format!(
106+
"http://{}:{}/{}",
107+
&server.addr().ip().to_string(),
108+
&server.addr().port(),
109+
path
110+
);
111+
let client = git_transport::client::http::connect(&url, version)?;
112+
assert_eq!(url, client.to_url());
113113
Ok((server, client))
114114
}

git-url/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ use std::{convert::TryFrom, fmt};
44

55
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
66
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
7-
pub enum Protocol {
7+
pub enum Scheme {
88
File,
99
Git,
1010
Ssh,
1111
Http,
1212
Https,
1313
}
1414

15-
impl fmt::Display for Protocol {
15+
impl fmt::Display for Scheme {
1616
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17-
use Protocol::*;
17+
use Scheme::*;
1818
f.write_str(match self {
1919
File => "file",
2020
Git => "git",
@@ -28,7 +28,7 @@ impl fmt::Display for Protocol {
2828
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
2929
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
3030
pub struct Url {
31-
pub protocol: Protocol,
31+
pub scheme: Scheme,
3232
pub user: Option<String>,
3333
pub host: Option<String>,
3434
pub port: Option<u16>,
@@ -38,7 +38,7 @@ pub struct Url {
3838
impl Default for Url {
3939
fn default() -> Self {
4040
Url {
41-
protocol: Protocol::Ssh,
41+
scheme: Scheme::Ssh,
4242
user: None,
4343
host: None,
4444
port: None,
@@ -49,7 +49,7 @@ impl Default for Url {
4949

5050
impl fmt::Display for Url {
5151
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52-
self.protocol.fmt(f)?;
52+
self.scheme.fmt(f)?;
5353
f.write_str("://")?;
5454
match (&self.user, &self.host) {
5555
(Some(user), Some(host)) => f.write_fmt(format_args!("{}@{}", user, host)),

git-url/src/parse.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::Protocol;
1+
use crate::Scheme;
22
use bstr::ByteSlice;
33
use quick_error::quick_error;
44
use std::borrow::Cow;
@@ -26,13 +26,13 @@ quick_error! {
2626
}
2727
}
2828

29-
fn str_to_protocol(s: &str) -> Result<Protocol, Error> {
29+
fn str_to_protocol(s: &str) -> Result<Scheme, Error> {
3030
Ok(match s {
31-
"ssh" => Protocol::Ssh,
32-
"file" => Protocol::File,
33-
"git" => Protocol::Git,
34-
"http" => Protocol::Http,
35-
"https" => Protocol::Https,
31+
"ssh" => Scheme::Ssh,
32+
"file" => Scheme::File,
33+
"git" => Scheme::Git,
34+
"http" => Scheme::Http,
35+
"https" => Scheme::Https,
3636
_ => return Err(Error::UnsupportedProtocol(s.into())),
3737
})
3838
}
@@ -71,7 +71,7 @@ fn possibly_strip_file_protocol(url: &[u8]) -> &[u8] {
7171

7272
fn to_owned_url(url: url::Url) -> Result<crate::Url, Error> {
7373
Ok(crate::Url {
74-
protocol: str_to_protocol(url.scheme())?,
74+
scheme: str_to_protocol(url.scheme())?,
7575
user: if url.username().is_empty() {
7676
None
7777
} else {
@@ -89,7 +89,7 @@ pub fn parse(url: &[u8]) -> Result<crate::Url, Error> {
8989
let guessed_protocol = guess_protocol(url);
9090
if possibly_strip_file_protocol(url) != url || (has_no_explicit_protocol(url) && guessed_protocol == "file") {
9191
return Ok(crate::Url {
92-
protocol: Protocol::File,
92+
scheme: Scheme::File,
9393
path: possibly_strip_file_protocol(url).into(),
9494
..Default::default()
9595
});

0 commit comments

Comments
 (0)