Introduces the `gitlocal` command-line tool for managing nested Git repositories. Includes the following main commands: - `convert`: Renames `.git` to `.gitlocal`, allowing a parent repository to ignore the converted child repository. Supports recursive scanning and dry-run options. Tracks converted repositories in a global configuration. - `revert`: Restores `.gitlocal` to `.git`. Includes an option to revert all tracked repositories. - `status`: Displays a list of all repositories currently tracked by `gitlocal`, showing their path, conversion time, and original remote/branch. Establishes internal modules for Git operations, configuration management, and recursive repository scanning. Adds a comprehensive test suite covering core command logic and utility functions. Initializes Go module and basic project `.gitignore`.
159 lines
4.1 KiB
Go
159 lines
4.1 KiB
Go
package testutil
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// CreateTempGitRepo creates a temporary directory with a git repository
|
|
func CreateTempGitRepo(t *testing.T) string {
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
|
|
// Initialize git repo
|
|
cmd := exec.Command("git", "init")
|
|
cmd.Dir = dir
|
|
if err := cmd.Run(); err != nil {
|
|
t.Fatalf("failed to init git repo: %v", err)
|
|
}
|
|
|
|
// Configure git user for the test repo
|
|
configName := exec.Command("git", "config", "user.name", "Test User")
|
|
configName.Dir = dir
|
|
if err := configName.Run(); err != nil {
|
|
t.Fatalf("failed to configure git user.name: %v", err)
|
|
}
|
|
|
|
configEmail := exec.Command("git", "config", "user.email", "test@example.com")
|
|
configEmail.Dir = dir
|
|
if err := configEmail.Run(); err != nil {
|
|
t.Fatalf("failed to configure git user.email: %v", err)
|
|
}
|
|
|
|
// Create initial commit
|
|
readmePath := filepath.Join(dir, "README.md")
|
|
if err := os.WriteFile(readmePath, []byte("# Test Repo\n"), 0644); err != nil {
|
|
t.Fatalf("failed to create README: %v", err)
|
|
}
|
|
|
|
add := exec.Command("git", "add", "README.md")
|
|
add.Dir = dir
|
|
if err := add.Run(); err != nil {
|
|
t.Fatalf("failed to git add: %v", err)
|
|
}
|
|
|
|
commit := exec.Command("git", "commit", "-m", "Initial commit")
|
|
commit.Dir = dir
|
|
if err := commit.Run(); err != nil {
|
|
t.Fatalf("failed to git commit: %v", err)
|
|
}
|
|
|
|
return dir
|
|
}
|
|
|
|
// CreateTempGitRepoWithRemote creates a temporary git repo with a remote URL configured
|
|
func CreateTempGitRepoWithRemote(t *testing.T, remoteURL string) string {
|
|
t.Helper()
|
|
|
|
dir := CreateTempGitRepo(t)
|
|
|
|
// Add remote
|
|
cmd := exec.Command("git", "remote", "add", "origin", remoteURL)
|
|
cmd.Dir = dir
|
|
if err := cmd.Run(); err != nil {
|
|
t.Fatalf("failed to add git remote: %v", err)
|
|
}
|
|
|
|
return dir
|
|
}
|
|
|
|
// CreateTempGitRepoWithBranch creates a temporary git repo on a specific branch
|
|
func CreateTempGitRepoWithBranch(t *testing.T, branch string) string {
|
|
t.Helper()
|
|
|
|
dir := CreateTempGitRepo(t)
|
|
|
|
// Create and checkout branch
|
|
cmd := exec.Command("git", "checkout", "-b", branch)
|
|
cmd.Dir = dir
|
|
if err := cmd.Run(); err != nil {
|
|
t.Fatalf("failed to create branch: %v", err)
|
|
}
|
|
|
|
return dir
|
|
}
|
|
|
|
// CreateNestedRepoStructure creates a directory structure with nested git repos
|
|
// Returns the root directory path
|
|
func CreateNestedRepoStructure(t *testing.T) (rootDir string, nestedDirs []string) {
|
|
t.Helper()
|
|
|
|
rootDir = CreateTempGitRepo(t)
|
|
|
|
// Create nested repos
|
|
nested1 := filepath.Join(rootDir, "project1")
|
|
if err := os.MkdirAll(nested1, 0755); err != nil {
|
|
t.Fatalf("failed to create nested dir: %v", err)
|
|
}
|
|
initGit(t, nested1)
|
|
|
|
nested2 := filepath.Join(rootDir, "subdir", "project2")
|
|
if err := os.MkdirAll(nested2, 0755); err != nil {
|
|
t.Fatalf("failed to create nested dir: %v", err)
|
|
}
|
|
initGit(t, nested2)
|
|
|
|
nested3 := filepath.Join(rootDir, "subdir", "deep", "project3")
|
|
if err := os.MkdirAll(nested3, 0755); err != nil {
|
|
t.Fatalf("failed to create nested dir: %v", err)
|
|
}
|
|
initGit(t, nested3)
|
|
|
|
return rootDir, []string{nested1, nested2, nested3}
|
|
}
|
|
|
|
// initGit initializes a git repo in the given directory
|
|
func initGit(t *testing.T, dir string) {
|
|
t.Helper()
|
|
|
|
cmd := exec.Command("git", "init")
|
|
cmd.Dir = dir
|
|
if err := cmd.Run(); err != nil {
|
|
t.Fatalf("failed to init git repo: %v", err)
|
|
}
|
|
|
|
// Configure git user
|
|
configName := exec.Command("git", "config", "user.name", "Test User")
|
|
configName.Dir = dir
|
|
if err := configName.Run(); err != nil {
|
|
t.Fatalf("failed to configure git user.name: %v", err)
|
|
}
|
|
|
|
configEmail := exec.Command("git", "config", "user.email", "test@example.com")
|
|
configEmail.Dir = dir
|
|
if err := configEmail.Run(); err != nil {
|
|
t.Fatalf("failed to configure git user.email: %v", err)
|
|
}
|
|
|
|
// Create initial commit
|
|
readmePath := filepath.Join(dir, "README.md")
|
|
if err := os.WriteFile(readmePath, []byte("# Test\n"), 0644); err != nil {
|
|
t.Fatalf("failed to create README: %v", err)
|
|
}
|
|
|
|
add := exec.Command("git", "add", "README.md")
|
|
add.Dir = dir
|
|
if err := add.Run(); err != nil {
|
|
t.Fatalf("failed to git add: %v", err)
|
|
}
|
|
|
|
commit := exec.Command("git", "commit", "-m", "Initial commit")
|
|
commit.Dir = dir
|
|
if err := commit.Run(); err != nil {
|
|
t.Fatalf("failed to git commit: %v", err)
|
|
}
|
|
}
|