Skip to content

Instantly share code, notes, and snippets.

@gocs
Created April 13, 2025 10:39
Show Gist options
  • Save gocs/807937831ad94b8300418bf5ce316beb to your computer and use it in GitHub Desktop.
Save gocs/807937831ad94b8300418bf5ce316beb to your computer and use it in GitHub Desktop.
golang mod init automatically

mod-init

This will go mod init and go mod tidy based on the .git/config's origin or upstream if it's from a fork. Create this file on an existing Go project with go.mod

Build its binary to the root directory of your .git/config: go build /home/me/mygit/.git/.. -o modinit

Run the binary: ./modinit

package main
import (
"context"
"fmt"
"log/slog"
"net/url"
"os"
"os/exec"
"strings"
"github.com/go-git/go-git/v5"
)
func main() {
if err := Run(context.Background()); err != nil {
slog.Error("failed to run", "error", err)
os.Exit(1)
}
}
func Run(ctx context.Context) error {
// get working directory
dir, err := os.Getwd()
if err != nil {
slog.Error("failed to get working directory", "error", err)
return err
}
// open repository
repo, err := git.PlainOpen(dir)
if err != nil {
slog.Error("failed to open repository", "error", err)
return err
}
// get repository config
cfg, err := repo.Config()
if err != nil {
slog.Error("failed to get repository config", "error", err)
return err
}
// get git url
gitUrl := cfg.Remotes["origin"].URLs[len(cfg.Remotes["origin"].URLs)-1]
if cfg.Remotes["upstream"] != nil {
gitUrl = cfg.Remotes["upstream"].URLs[len(cfg.Remotes["upstream"].URLs)-1]
}
// parse git url to http url
httpUrl, err := parseGitUrlToHttp(gitUrl)
if err != nil {
slog.Error("failed to parse git url", "error", err)
return err
}
// execute command `go mod init` with the golang url
modUrl := fmt.Sprintf("%s/%s", httpUrl.Host, httpUrl.Path)
cmd := exec.CommandContext(ctx, "go", "mod", "init", modUrl)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
slog.Error("failed to run `go mod init`", "error", err)
return err
}
// execute command `go mod tidy`
cmd = exec.CommandContext(ctx, "go", "mod", "tidy")
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
slog.Error("failed to run `go mod tidy`", "error", err)
return err
}
return nil
}
// parseGitUrlToHttp converts a Git SSH URL to an HTTP URL
// Example: [email protected]:golang/go.git -> https://github.com/golang/go
func parseGitUrlToHttp(gitUrl string) (*url.URL, error) {
// Remove the git@ prefix if present
urlStr := strings.TrimPrefix(gitUrl, "git@")
// Split on the first colon
parts := strings.SplitN(urlStr, ":", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid git url format: %s", gitUrl)
}
// Replace the colon with a forward slash
path := strings.Replace(parts[1], ":", "/", 1)
// Remove .git suffix if present
path = strings.TrimSuffix(path, ".git")
// Construct the HTTP URL
httpUrl := &url.URL{
Scheme: "https",
Host: parts[0],
Path: path,
}
return httpUrl, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment