Infer the repository name from a URL. Attempts to extract the project/repository name from the URL path.
(url: &Url)
| 261 | /// |
| 262 | /// Attempts to extract the project/repository name from the URL path. |
| 263 | fn infer_repo_name(url: &Url) -> Option<String> { |
| 264 | let path = url.path(); |
| 265 | let segments: Vec<&str> = path.split('/').filter(|s| !s.is_empty()).collect(); |
| 266 | |
| 267 | // Look for common patterns: |
| 268 | // /.../project/{name}/code -> name |
| 269 | // /.../project/{name}/.atomic -> name |
| 270 | // /{name}.git -> name |
| 271 | // /{name} -> name |
| 272 | |
| 273 | for (i, segment) in segments.iter().enumerate() { |
| 274 | // Pattern: project/{name}/code or project/{name}/.atomic |
| 275 | if (*segment == "code" || *segment == ".atomic") && i > 0 { |
| 276 | return Some(segments[i - 1].to_string()); |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | // Fallback: use the last meaningful segment |
| 281 | for segment in segments.iter().rev() { |
| 282 | if *segment != "code" && *segment != ".atomic" && !segment.is_empty() { |
| 283 | let name = segment.trim_end_matches(".git"); |
| 284 | return Some(name.to_string()); |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | None |
| 289 | } |
| 290 | |
| 291 | /// Parse a changelist response into entries. |
| 292 | pub(crate) fn parse_changelist(text: &str) -> RemoteResult<Vec<ChangelistEntry>> { |
no test coverage detected