82 lines
2.3 KiB
Go
82 lines
2.3 KiB
Go
//go:build linux || darwin
|
|
|
|
package gitinit
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
|
|
"github.com/kandev/kandev/internal/common/subproc"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
const inheritedDirectoryFD = 3
|
|
|
|
// init handles the explicitly marked helper subprocess before a test binary or
|
|
// another Kandev entry point can interpret the private helper argument.
|
|
func init() {
|
|
if os.Getenv(helperEnvironmentVariable) != "1" {
|
|
return
|
|
}
|
|
if code, handled := runHelper(os.Args[1:]); handled {
|
|
os.Exit(code)
|
|
}
|
|
}
|
|
|
|
// CommandContext creates a Git initialization command bound to targetDirectory.
|
|
func CommandContext(ctx context.Context, targetPath string, targetDirectory *os.File) (*exec.Cmd, error) {
|
|
return commandContext(ctx, targetPath, targetDirectory, "init", "--initial-branch=main")
|
|
}
|
|
|
|
// CommitCommandContext creates a Git commit command bound to targetDirectory.
|
|
func CommitCommandContext(
|
|
ctx context.Context,
|
|
targetPath string,
|
|
targetDirectory *os.File,
|
|
args ...string,
|
|
) (*exec.Cmd, error) {
|
|
command, err := commandContext(ctx, targetPath, targetDirectory, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
command.Env = withIsolatedCommitEnvironment(command.Env)
|
|
return command, nil
|
|
}
|
|
|
|
func commandContext(ctx context.Context, _ string, targetDirectory *os.File, gitArgs ...string) (*exec.Cmd, error) {
|
|
gitPath, err := subproc.GitExecutablePath()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("find git: %w", err)
|
|
}
|
|
if !filepath.IsAbs(gitPath) {
|
|
gitPath, err = filepath.Abs(gitPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve git executable: %w", err)
|
|
}
|
|
}
|
|
executable, err := os.Executable()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve kandev executable: %w", err)
|
|
}
|
|
commandArgs := append([]string{helperArgument, gitPath}, gitArgs...)
|
|
command := exec.CommandContext(ctx, executable, commandArgs...)
|
|
command.ExtraFiles = []*os.File{targetDirectory}
|
|
command.Env = withHelperEnvironment(os.Environ())
|
|
return command, nil
|
|
}
|
|
|
|
func runInheritedDirectory(gitPath string, gitArgs []string) int {
|
|
if err := unix.Fchdir(inheritedDirectoryFD); err != nil {
|
|
fmt.Fprintf(os.Stderr, "git init helper: enter inherited directory: %v\n", err)
|
|
return 1
|
|
}
|
|
if err := subproc.ExecGit(gitPath, gitArgs, withoutHelperEnvironment(os.Environ())); err != nil {
|
|
fmt.Fprintf(os.Stderr, "git init helper: execute git: %v\n", err)
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|