diff options
Diffstat (limited to 'src/git.rs')
| -rw-r--r-- | src/git.rs | 124 |
1 files changed, 124 insertions, 0 deletions
| @@ -886,6 +886,64 @@ pub fn nostr_git_url_to_repo_coordinates(url: &str) -> Result<HashSet<Coordinate | |||
| 886 | ); | 886 | ); |
| 887 | } | 887 | } |
| 888 | 888 | ||
| 889 | /** produce error when using local repo or custom protocols */ | ||
| 890 | pub fn convert_clone_url_to_https(url: &str) -> Result<String> { | ||
| 891 | // Strip credentials if present | ||
| 892 | let stripped_url = strip_credentials(url); | ||
| 893 | |||
| 894 | // Check if the URL is already in HTTPS format | ||
| 895 | if stripped_url.starts_with("https://") { | ||
| 896 | return Ok(stripped_url); | ||
| 897 | } | ||
| 898 | // Convert http:// to https:// | ||
| 899 | else if stripped_url.starts_with("http://") { | ||
| 900 | return Ok(stripped_url.replace("http://", "https://")); | ||
| 901 | } | ||
| 902 | // Check if the URL starts with SSH | ||
| 903 | else if stripped_url.starts_with("ssh://") { | ||
| 904 | // Convert SSH to HTTPS | ||
| 905 | let parts: Vec<&str> = stripped_url | ||
| 906 | .trim_start_matches("ssh://") | ||
| 907 | .split('/') | ||
| 908 | .collect(); | ||
| 909 | if parts.len() >= 2 { | ||
| 910 | // Construct the HTTPS URL | ||
| 911 | return Ok(format!("https://{}/{}", parts[0], parts[1..].join("/"))); | ||
| 912 | } | ||
| 913 | bail!("Invalid SSH URL format: {}", url); | ||
| 914 | } | ||
| 915 | // Convert ftp:// to https:// | ||
| 916 | else if stripped_url.starts_with("ftp://") { | ||
| 917 | return Ok(stripped_url.replace("ftp://", "https://")); | ||
| 918 | } | ||
| 919 | // Convert git:// to https:// | ||
| 920 | else if stripped_url.starts_with("git://") { | ||
| 921 | return Ok(stripped_url.replace("git://", "https://")); | ||
| 922 | } | ||
| 923 | |||
| 924 | // If the URL is neither HTTPS, SSH, nor git@, return an error | ||
| 925 | bail!("Unsupported URL protocol: {}", url); | ||
| 926 | } | ||
| 927 | |||
| 928 | // Function to strip username and password from the URL | ||
| 929 | fn strip_credentials(url: &str) -> String { | ||
| 930 | if let Some(pos) = url.find("://") { | ||
| 931 | let (protocol, rest) = url.split_at(pos + 3); // Split at "://" | ||
| 932 | let rest_parts: Vec<&str> = rest.split('@').collect(); | ||
| 933 | if rest_parts.len() > 1 { | ||
| 934 | // If there are credentials, return the URL without them | ||
| 935 | return format!("{}{}", protocol, rest_parts[1]); | ||
| 936 | } | ||
| 937 | } else if let Some(at_pos) = url.find('@') { | ||
| 938 | // Handle user@host:path format | ||
| 939 | let (_, rest) = url.split_at(at_pos); | ||
| 940 | // This is a git@ syntax | ||
| 941 | let host_and_repo = &rest[1..]; // Skip the ':' | ||
| 942 | return format!("ssh://{}", host_and_repo.replace(':', "/")); | ||
| 943 | } | ||
| 944 | url.to_string() // Return the original URL if no credentials are found | ||
| 945 | } | ||
| 946 | |||
| 889 | #[cfg(test)] | 947 | #[cfg(test)] |
| 890 | mod tests { | 948 | mod tests { |
| 891 | use std::fs; | 949 | use std::fs; |
| @@ -2366,4 +2424,70 @@ mod tests { | |||
| 2366 | Ok(()) | 2424 | Ok(()) |
| 2367 | } | 2425 | } |
| 2368 | } | 2426 | } |
| 2427 | mod convert_clone_url_to_https { | ||
| 2428 | use super::*; | ||
| 2429 | |||
| 2430 | #[test] | ||
| 2431 | fn test_https_url() { | ||
| 2432 | let url = "https://github.com/user/repo.git"; | ||
| 2433 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2434 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2435 | } | ||
| 2436 | |||
| 2437 | #[test] | ||
| 2438 | fn test_http_url() { | ||
| 2439 | let url = "http://github.com/user/repo.git"; | ||
| 2440 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2441 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | #[test] | ||
| 2445 | fn test_http_url_with_credentials() { | ||
| 2446 | let url = "http://username:password@github.com/user/repo.git"; | ||
| 2447 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2448 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2449 | } | ||
| 2450 | |||
| 2451 | #[test] | ||
| 2452 | fn test_git_at_url() { | ||
| 2453 | let url = "git@github.com:user/repo.git"; | ||
| 2454 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2455 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2456 | } | ||
| 2457 | |||
| 2458 | #[test] | ||
| 2459 | fn test_user_at_url() { | ||
| 2460 | let url = "user1@github.com:user/repo.git"; | ||
| 2461 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2462 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2463 | } | ||
| 2464 | |||
| 2465 | #[test] | ||
| 2466 | fn test_ssh_url() { | ||
| 2467 | let url = "ssh://github.com/user/repo.git"; | ||
| 2468 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2469 | assert_eq!(result, "https://github.com/user/repo.git"); | ||
| 2470 | } | ||
| 2471 | |||
| 2472 | #[test] | ||
| 2473 | fn test_ftp_url() { | ||
| 2474 | let url = "ftp://example.com/repo.git"; | ||
| 2475 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2476 | assert_eq!(result, "https://example.com/repo.git"); | ||
| 2477 | } | ||
| 2478 | |||
| 2479 | #[test] | ||
| 2480 | fn test_git_protocol_url() { | ||
| 2481 | let url = "git://example.com/repo.git"; | ||
| 2482 | let result = convert_clone_url_to_https(url).unwrap(); | ||
| 2483 | assert_eq!(result, "https://example.com/repo.git"); | ||
| 2484 | } | ||
| 2485 | |||
| 2486 | #[test] | ||
| 2487 | fn test_invalid_url() { | ||
| 2488 | let url = "unsupported://example.com/repo.git"; | ||
| 2489 | let result = convert_clone_url_to_https(url); | ||
| 2490 | assert!(result.is_err()); | ||
| 2491 | } | ||
| 2492 | } | ||
| 2369 | } | 2493 | } |