Skip to content

Instantly share code, notes, and snippets.

@auxten
Last active June 22, 2024 12:43
Show Gist options
  • Save auxten/1d04b969f174ecb12c2a58d63e6c7197 to your computer and use it in GitHub Desktop.
Save auxten/1d04b969f174ecb12c2a58d63e6c7197 to your computer and use it in GitHub Desktop.
clone git repo and put it into ${GOPATH}/src/github.com/org/repo like go get -d
package main
import (
"fmt"
"os"
"os/exec"
"strings"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: got <repo-url>")
os.Exit(1)
}
repoURL := os.Args[1]
gopath := os.Getenv("GOPATH")
if gopath == "" {
fmt.Println("GOPATH is not set.")
os.Exit(1)
}
// Determine the correct directory path
destDir, err := getDestDir(repoURL, gopath)
if err != nil {
fmt.Printf("Error processing URL: %v\n", err)
os.Exit(1)
}
// Try cloning via SSH first, then HTTPS if SSH fails
if !cloneRepo(repoURL, destDir, true) && !cloneRepo(repoURL, destDir, false) {
fmt.Println("Failed to clone repository.")
os.Exit(1)
}
fmt.Println("Repository cloned successfully.")
}
func getDestDir(repoURL, gopath string) (string, error) {
// Extract the host and path from the repo URL
var repoPath string
if strings.Contains(repoURL, "git@") {
// SSH URL format: git@host:path
parts := strings.SplitN(repoURL, ":", 2)
if len(parts) != 2 {
return "", fmt.Errorf("invalid SSH URL")
}
hostParts := strings.Split(parts[0], "@")
if len(hostParts) != 2 {
return "", fmt.Errorf("invalid SSH URL")
}
repoPath = hostParts[1] + "/" + parts[1]
} else {
// HTTPS URL format: https://host/path
trimmedURL := strings.TrimPrefix(repoURL, "https://")
repoPath = trimmedURL
}
// Remove possible .git suffix
repoPath = strings.TrimSuffix(repoPath, ".git")
return fmt.Sprintf("%s/src/%s", gopath, repoPath), nil
}
func cloneRepo(repoURL, destDir string, useSSH bool) bool {
if useSSH {
repoURL = convertToSSH(repoURL)
} else if !strings.HasPrefix(repoURL, "https://") {
// If not using SSH and the URL doesn't start with "https://", add the prefix
repoURL = "https://" + repoURL
}
fmt.Printf("Cloning from %s into %s\n", repoURL, destDir)
cmd := exec.Command("git", "clone", repoURL, destDir)
cmd.Stdout = os.Stdout // Redirect standard output to os.Stdout
cmd.Stderr = os.Stderr // Redirect standard error to os.Stderr
err := cmd.Run()
if err != nil {
fmt.Printf("Error cloning repository: %v\n", err)
return false
}
return true
}
func convertToSSH(repoURL string) string {
if strings.HasPrefix(repoURL, "https://") {
// Convert HTTPS URL to SSH
httpsParts := strings.SplitN(repoURL, "/", 4)
if len(httpsParts) >= 4 {
host := httpsParts[2]
path := httpsParts[3]
return fmt.Sprintf("git@%s:%s.git", host, path)
}
}
return repoURL // return original if no conversion is possible
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment