mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
147 lines
4.3 KiB
Go
Executable File
147 lines
4.3 KiB
Go
Executable File
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// IsGitURL checks if a string is likely a Git repository URL (not a raw file URL).
|
|
// It checks for "git@" prefix or URLs ending with ".git".
|
|
func IsGitURL(url string) bool {
|
|
if strings.HasPrefix(url, "git@") {
|
|
return true
|
|
}
|
|
if strings.HasSuffix(url, ".git") {
|
|
return true
|
|
}
|
|
// Check for common git hosting patterns (but not raw file URLs)
|
|
gitPatterns := []string{
|
|
"github.com/",
|
|
"gitlab.com/",
|
|
"bitbucket.org/",
|
|
}
|
|
for _, pattern := range gitPatterns {
|
|
if strings.Contains(url, pattern) && !IsRawFileURL(url) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsRawFileURL checks if a URL is a direct raw file URL.
|
|
func IsRawFileURL(url string) bool {
|
|
rawPatterns := []string{
|
|
"raw.githubusercontent.com",
|
|
"/-/raw/", // GitLab raw URL pattern
|
|
"/raw/", // Bitbucket raw URL pattern
|
|
"raw.github.com",
|
|
}
|
|
for _, pattern := range rawPatterns {
|
|
if strings.Contains(url, pattern) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GitURLInfo holds parsed information from a Git URL.
|
|
type GitURLInfo struct {
|
|
Host string // e.g., "github.com", "gitlab.com"
|
|
Owner string // e.g., "chenasraf"
|
|
Repo string // e.g., "sofmani"
|
|
}
|
|
|
|
// ParseGitURL parses a Git URL (SSH or HTTPS) and extracts host, owner, and repo.
|
|
// Supports formats:
|
|
// - git@github.com:owner/repo.git
|
|
// - https://github.com/owner/repo.git
|
|
// - https://github.com/owner/repo
|
|
func ParseGitURL(url string) (*GitURLInfo, error) {
|
|
// SSH format: git@host:owner/repo.git
|
|
sshRegex := regexp.MustCompile(`^git@([^:]+):([^/]+)/(.+?)(?:\.git)?$`)
|
|
if matches := sshRegex.FindStringSubmatch(url); matches != nil {
|
|
return &GitURLInfo{
|
|
Host: matches[1],
|
|
Owner: matches[2],
|
|
Repo: matches[3],
|
|
}, nil
|
|
}
|
|
|
|
// HTTPS format: https://host/owner/repo.git or https://host/owner/repo
|
|
httpsRegex := regexp.MustCompile(`^https://([^/]+)/([^/]+)/(.+?)(?:\.git)?$`)
|
|
if matches := httpsRegex.FindStringSubmatch(url); matches != nil {
|
|
return &GitURLInfo{
|
|
Host: matches[1],
|
|
Owner: matches[2],
|
|
Repo: matches[3],
|
|
}, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("unable to parse Git URL: %s", url)
|
|
}
|
|
|
|
// GitHostType represents the type of Git hosting service.
|
|
type GitHostType string
|
|
|
|
const (
|
|
GitHostGitHub GitHostType = "github"
|
|
GitHostGitLab GitHostType = "gitlab"
|
|
GitHostBitbucket GitHostType = "bitbucket"
|
|
GitHostUnknown GitHostType = "unknown"
|
|
)
|
|
|
|
// DetectGitHostType detects the Git hosting service from a host string.
|
|
// It checks for known patterns in the hostname.
|
|
func DetectGitHostType(host string) GitHostType {
|
|
host = strings.ToLower(host)
|
|
switch {
|
|
case strings.Contains(host, "github"):
|
|
return GitHostGitHub
|
|
case strings.Contains(host, "gitlab"):
|
|
return GitHostGitLab
|
|
case strings.Contains(host, "bitbucket"):
|
|
return GitHostBitbucket
|
|
default:
|
|
return GitHostUnknown
|
|
}
|
|
}
|
|
|
|
// GetRawFileURL converts a Git repository URL to a raw file URL for direct access.
|
|
// Supports GitHub, GitLab (including self-hosted), and Bitbucket (including self-hosted).
|
|
// For unknown hosts, it attempts to use GitLab-style raw URLs as a fallback.
|
|
// Parameters:
|
|
// - gitURL: The Git repository URL (SSH or HTTPS)
|
|
// - ref: The branch, tag, or commit (defaults to "master" if empty)
|
|
// - path: The file path within the repository
|
|
func GetRawFileURL(gitURL, ref, path string) (string, error) {
|
|
info, err := ParseGitURL(gitURL)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if ref == "" {
|
|
ref = "master"
|
|
}
|
|
|
|
// Remove leading slash from path if present
|
|
path = strings.TrimPrefix(path, "/")
|
|
|
|
hostType := DetectGitHostType(info.Host)
|
|
|
|
switch hostType {
|
|
case GitHostGitHub:
|
|
// GitHub: https://raw.githubusercontent.com/owner/repo/ref/path
|
|
return fmt.Sprintf("https://raw.githubusercontent.com/%s/%s/%s/%s", info.Owner, info.Repo, ref, path), nil
|
|
case GitHostGitLab:
|
|
// GitLab (including self-hosted): https://host/owner/repo/-/raw/ref/path
|
|
return fmt.Sprintf("https://%s/%s/%s/-/raw/%s/%s", info.Host, info.Owner, info.Repo, ref, path), nil
|
|
case GitHostBitbucket:
|
|
// Bitbucket (including self-hosted): https://host/owner/repo/raw/ref/path
|
|
return fmt.Sprintf("https://%s/%s/%s/raw/%s/%s", info.Host, info.Owner, info.Repo, ref, path), nil
|
|
default:
|
|
// For unknown hosts, try GitLab-style as it's common for self-hosted instances
|
|
return fmt.Sprintf("https://%s/%s/%s/-/raw/%s/%s", info.Host, info.Owner, info.Repo, ref, path), nil
|
|
}
|
|
}
|