8b70daed53
- Add git URL parsing utilities (extract_base_repo_url, parse_git_url) - Support GitHub, GitLab, Bitbucket browser URL detection - Add /projects/repositories/parse-url endpoint - Enhance repository creation to detect browser URLs and suggest corrections - Add real-time URL validation in frontend with debouncing - Show visual indicators (green/yellow/red) for URL validity - Display inline suggestions with 'Use Suggested' button - Add comprehensive unit tests for URL parsing - Quality gates: ruff ✓, mypy ✓, typecheck ✓, lint ✓, build ✓
6.4 KiB
6.4 KiB
Smart Git URL Parsing Specification
Requirements
Functional Requirements
- URL Detection: Detect when a provided URL is a browser URL rather than a git clone URL
- URL Extraction: Extract the base repository URL from browser URLs
- User Confirmation: Show extracted URL to user and ask for confirmation
- Flexible Input: Allow users to proceed with original URL if they prefer
- Multiple Hosts: Support GitHub, GitLab, Bitbucket, and generic git hosts
Non-Functional Requirements
- Performance: URL parsing should be instant (< 100ms)
- Accuracy: Should correctly identify 95%+ of browser URLs
- User Experience: Clear, helpful messages without technical jargon
- Backward Compatibility: Existing valid git URLs should continue to work
API Specification
POST /git-repositories/parse-url
Parse a URL and determine if it's a valid clone URL or needs correction.
Request Body:
{
"url": "https://github.com/user/repo/tree/main"
}
Response 200:
{
"original_url": "https://github.com/user/repo/tree/main",
"base_url": "https://github.com/user/repo.git",
"is_valid_clone_url": false,
"needs_parsing": true,
"host": "github.com",
"message": "This URL contains a branch path. The repository URL is: https://github.com/user/repo.git"
}
Response 200 (already valid):
{
"original_url": "https://github.com/user/repo.git",
"base_url": "https://github.com/user/repo.git",
"is_valid_clone_url": true,
"needs_parsing": false,
"host": "github.com",
"message": "Valid git repository URL"
}
Enhanced POST /projects/{project_id}/repositories
Enhanced to return suggestions when URL needs parsing.
New 422 Response:
{
"detail": "The provided URL appears to be a browser URL, not a git clone URL",
"suggested_url": "https://github.com/user/repo.git",
"original_url": "https://github.com/user/repo/tree/main",
"error_code": "URL_NEEDS_PARSING"
}
Request Body (with force flag):
{
"name": "my-repo",
"remote_url": "https://github.com/user/repo/tree/main",
"is_mirror": false,
"force_original_url": true
}
Data Model
URLParseResult
class URLParseResult:
original_url: str
base_url: str | None
is_valid_clone_url: bool
needs_parsing: bool
host: str | None
message: str
error_code: str | None
URL Parsing Rules
Supported Hosts
- github.com
- gitlab.com
- bitbucket.org
- Any custom domain with git hosting
GitHub URL Patterns
https://github.com/{owner}/{repo} → valid
https://github.com/{owner}/{repo}.git → valid
https://github.com/{owner}/{repo}/tree/{branch} → extract base
https://github.com/{owner}/{repo}/blob/{branch}/{path} → extract base
https://github.com/{owner}/{repo}/pull/{number} → extract base
https://github.com/{owner}/{repo}/issues/{number} → extract base
https://github.com/{owner}/{repo}/actions → extract base
GitLab URL Patterns
https://gitlab.com/{owner}/{repo} → valid
https://gitlab.com/{owner}/{repo}.git → valid
https://gitlab.com/{owner}/{repo}/-/tree/{branch} → extract base
https://gitlab.com/{owner}/{repo}/-/blob/{branch}/{path} → extract base
https://gitlab.com/{owner}/{repo}/-/merge_requests/{number} → extract base
Bitbucket URL Patterns
https://bitbucket.org/{owner}/{repo} → valid
https://bitbucket.org/{owner}/{repo}.git → valid
https://bitbucket.org/{owner}/{repo}/src/{branch} → extract base
Extraction Algorithm
- Parse URL components (scheme, netloc, path, query)
- Remove query parameters entirely
- Split path by
/ - Remove trailing segments that indicate non-repo paths:
tree/*,blob/*,pull/*,issues/*,actions-/tree/*,-/blob/*,-/merge_requests/*src/*
- Reconstruct URL with remaining path
- Add
.gitsuffix if missing (for HTTPS URLs) - Return extracted URL
Frontend Specification
URL Input Component
- Input field for repository URL
- Real-time validation (debounced 300ms)
- Visual indicators:
- 🟢 Green border: Valid git URL
- 🟡 Yellow border: Browser URL detected, suggestion shown
- 🔴 Red border: Invalid/malformed URL
- Inline suggestion banner below input:
⚠️ This looks like a browser URL Suggested: https://github.com/user/repo.git [Use Suggested] [Keep Original]
Confirmation Dialog
Shown when backend returns 422 with suggestion:
┌─────────────────────────────────────┐
│ URL Correction Suggestion │
├─────────────────────────────────────┤
│ │
│ The URL you entered appears to be │
│ a browser URL, not a git clone URL. │
│ │
│ Original: │
│ https://github.com/user/repo/tree/main│
│ │
│ Suggested repository URL: │
│ https://github.com/user/repo.git │
│ │
│ [Use Suggested URL] [Use Original] │
│ [Cancel] │
└─────────────────────────────────────┘
Error Codes
| Error Code | Description | User Message |
|---|---|---|
| URL_NEEDS_PARSING | Browser URL detected | "This looks like a browser URL. Did you mean: {suggested_url}?" |
| INVALID_URL | Malformed URL | "Please enter a valid URL" |
| UNSUPPORTED_HOST | Unknown git host | "This git host is not supported" |
| CLONE_FAILED | Git clone failed | "Failed to clone repository: {error}" |
| AUTH_REQUIRED | Private repo, need auth | "This repository requires authentication" |
Testing Strategy
Unit Tests (URL Parsing)
- Test all GitHub URL patterns
- Test all GitLab URL patterns
- Test all Bitbucket URL patterns
- Test valid URLs pass through unchanged
- Test edge cases (subgroups, nested paths, etc.)
Integration Tests
- Test parse-url endpoint with various URLs
- Test repository creation with browser URL (should suggest correction)
- Test repository creation with force flag
- Test clone operation with corrected URL
Frontend Tests
- Test URL input validation states
- Test suggestion banner display
- Test confirmation dialog flow
- Test acceptance/rejection of suggestions