#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TransportCapabilities {
pub http_fetch: bool,
pub http_push: bool,
pub http_protocol_v2_discovery: bool,
pub http_protocol_v2_fetch: bool,
pub shallow_fetch: bool,
pub ssh_fetch: bool,
pub ssh_push: bool,
pub ssh_clone: bool,
pub git_fetch: bool,
pub git_push: bool,
pub git_clone: bool,
pub bundle_fetch: bool,
pub local_fetch: bool,
pub local_push: bool,
pub credential_helper: bool,
pub thin_pack_push: bool,
pub sha256_http: bool,
pub sha256_ssh: bool,
}
pub const HTTP_PROTOCOL_V2_FETCH: bool = true;
pub const SSH_CLONE_SUPPORTED: bool = true;
pub const BUNDLE_FETCH_SUPPORTED: bool = true;
pub const THIN_PACK_PUSH_SUPPORTED: bool = true;
impl TransportCapabilities {
pub const fn current() -> Self {
Self {
http_fetch: cfg!(feature = "http"),
http_push: cfg!(feature = "http"),
http_protocol_v2_discovery: cfg!(feature = "http"),
http_protocol_v2_fetch: cfg!(feature = "http") && HTTP_PROTOCOL_V2_FETCH,
shallow_fetch: true,
ssh_fetch: true,
ssh_push: true,
ssh_clone: SSH_CLONE_SUPPORTED,
git_fetch: true,
git_push: true,
git_clone: true,
bundle_fetch: BUNDLE_FETCH_SUPPORTED,
local_fetch: true,
local_push: true,
credential_helper: true,
thin_pack_push: THIN_PACK_PUSH_SUPPORTED,
sha256_http: cfg!(feature = "http"),
sha256_ssh: true,
}
}
pub fn supports_native_push(&self, transport: RemoteTransportKind) -> bool {
match transport {
RemoteTransportKind::Http => self.http_push,
RemoteTransportKind::Ssh => self.ssh_push,
RemoteTransportKind::Git => self.git_push,
RemoteTransportKind::Local => self.local_push,
RemoteTransportKind::Bundle => false,
}
}
pub fn supports_shallow(&self, transport: RemoteTransportKind) -> bool {
match transport {
RemoteTransportKind::Http | RemoteTransportKind::Ssh | RemoteTransportKind::Git => {
self.shallow_fetch
}
RemoteTransportKind::Local | RemoteTransportKind::Bundle => false,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RemoteTransportKind {
Http,
Ssh,
Git,
Local,
Bundle,
}
#[cfg(all(test, not(feature = "http")))]
mod tests {
use super::TransportCapabilities;
#[test]
fn ssh_only_build_disables_http_fetch_capability() {
let caps = TransportCapabilities::current();
assert!(!caps.http_fetch);
assert!(!caps.http_push);
assert!(!caps.http_protocol_v2_discovery);
assert!(!caps.http_protocol_v2_fetch);
assert!(!caps.sha256_http);
assert!(caps.ssh_fetch);
}
}
impl RemoteTransportKind {
pub fn from_url_scheme(url: &str) -> Option<Self> {
if url.starts_with("http://") || url.starts_with("https://") {
return Some(Self::Http);
}
if url.starts_with("git://") {
return Some(Self::Git);
}
if url.starts_with("ssh://")
|| url.starts_with("git@")
|| url.contains(':') && !url.contains("://")
{
return Some(Self::Ssh);
}
if url.starts_with("file://") || url.starts_with('/') || url.starts_with("./") {
return Some(Self::Local);
}
if url.ends_with(".bundle") {
return Some(Self::Bundle);
}
None
}
}