|
1 |
| -use std::env; |
| 1 | +use std::{env, panic}; |
2 | 2 |
|
3 | 3 | use git2::{Reference, Repository};
|
4 | 4 | use git_url_parse::GitUrl;
|
@@ -103,35 +103,42 @@ impl GitContext {
|
103 | 103 | // will return None
|
104 | 104 | fn sanitize_remote_url(remote_url: &str) -> Option<String> {
|
105 | 105 | // try to parse url into git info
|
106 |
| - let mut parsed_remote_url = match GitUrl::parse(remote_url) { |
107 |
| - Ok(parsed_remote_url) => parsed_remote_url, |
108 |
| - Err(_) => return None, |
109 |
| - }; |
110 |
| - |
111 |
| - // return None for any remote that is not a supported host |
112 |
| - if let Some(host) = &parsed_remote_url.host { |
113 |
| - match host.as_str() { |
114 |
| - "github.com" | "gitlab.com" | "bitbucket.org" => {} |
115 |
| - _ => return None, |
116 |
| - } |
117 |
| - } else { |
118 |
| - return None; |
119 |
| - }; |
120 |
| - |
121 |
| - let optional_user = parsed_remote_url.user.clone(); |
122 |
| - parsed_remote_url = parsed_remote_url.trim_auth(); |
123 | 106 |
|
124 |
| - // if the user is "git" we can add back in the user. Otherwise, return |
125 |
| - // the clean remote url |
126 |
| - // this is done previously here: |
127 |
| - // https://github.com/apollographql/apollo-tooling/blob/fd642ab59620cd836651dcab4c3ecbcbcca3f780/packages/apollo/src/git.ts#L49 |
128 |
| - if let Some(user) = &optional_user { |
129 |
| - if user == "git" { |
130 |
| - parsed_remote_url.user = optional_user; |
131 |
| - } |
132 |
| - }; |
| 107 | + // GitUrl::parse can panic, so we attempt to catch it and |
| 108 | + // just return None if the parsing fails. |
133 | 109 |
|
134 |
| - Some(parsed_remote_url.to_string()) |
| 110 | + let parsed_remote_url = panic::catch_unwind(|| GitUrl::parse(remote_url).ok()) |
| 111 | + .ok() |
| 112 | + .flatten(); |
| 113 | + |
| 114 | + if let Some(mut parsed_remote_url) = parsed_remote_url { |
| 115 | + // return None for any remote that is not a supported host |
| 116 | + if let Some(host) = &parsed_remote_url.host { |
| 117 | + match host.as_str() { |
| 118 | + "github.com" | "gitlab.com" | "bitbucket.org" => {} |
| 119 | + _ => return None, |
| 120 | + } |
| 121 | + } else { |
| 122 | + return None; |
| 123 | + }; |
| 124 | + |
| 125 | + let optional_user = parsed_remote_url.user.clone(); |
| 126 | + parsed_remote_url = parsed_remote_url.trim_auth(); |
| 127 | + |
| 128 | + // if the user is "git" we can add back in the user. Otherwise, return |
| 129 | + // the clean remote url |
| 130 | + // this is done previously here: |
| 131 | + // https://github.com/apollographql/apollo-tooling/blob/fd642ab59620cd836651dcab4c3ecbcbcca3f780/packages/apollo/src/git.ts#L49 |
| 132 | + if let Some(user) = &optional_user { |
| 133 | + if user == "git" { |
| 134 | + parsed_remote_url.user = optional_user; |
| 135 | + } |
| 136 | + }; |
| 137 | + |
| 138 | + Some(parsed_remote_url.to_string()) |
| 139 | + } else { |
| 140 | + None |
| 141 | + } |
135 | 142 | }
|
136 | 143 | }
|
137 | 144 |
|
@@ -299,4 +306,11 @@ mod tests {
|
299 | 306 | panic!("GitContext could not find the remote url");
|
300 | 307 | }
|
301 | 308 | }
|
| 309 | + |
| 310 | + #[test] |
| 311 | + // regression test for https://github.com/apollographql/rover/issues/670 |
| 312 | + fn it_does_not_panic_on_remote_urls_with_no_apparent_owner() { |
| 313 | + let clean = GitContext::sanitize_remote_url("ssh://[email protected]:4000/repo-name"); |
| 314 | + assert_eq!(clean, None); |
| 315 | + } |
302 | 316 | }
|
0 commit comments