diff --git a/git/clone.go b/git/clone.go index 0136bb3..7ded806 100644 --- a/git/clone.go +++ b/git/clone.go @@ -8,15 +8,15 @@ import ( ) // FetchSource fetches the source from remote. -func FetchSource(repo Repository) *types.Cmd { +func (r *Repository) FetchSource() *types.Cmd { args := []string{ "fetch", "origin", - fmt.Sprintf("+%s:", repo.Branch), + fmt.Sprintf("+%s:", r.Branch), } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -24,15 +24,15 @@ func FetchSource(repo Repository) *types.Cmd { } // CheckoutHead handles branch checkout. -func CheckoutHead(repo Repository) *types.Cmd { +func (r *Repository) CheckoutHead() *types.Cmd { args := []string{ "checkout", "-qf", - repo.Branch, + r.Branch, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, diff --git a/git/clone_test.go b/git/clone_test.go index fc7fa90..6e93165 100644 --- a/git/clone_test.go +++ b/git/clone_test.go @@ -32,7 +32,7 @@ func TestFetchSource(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := FetchSource(tt.repo) + cmd := tt.repo.FetchSource() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -65,7 +65,7 @@ func TestCheckoutHead(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := CheckoutHead(tt.repo) + cmd := tt.repo.CheckoutHead() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) diff --git a/git/commit.go b/git/commit.go index 82dc2f9..4ce2ad7 100644 --- a/git/commit.go +++ b/git/commit.go @@ -5,34 +5,14 @@ import ( "golang.org/x/sys/execabs" ) -// ForceAdd forces the addition of all dirty files. -func ForceAdd(repo Repository) *types.Cmd { +// Add updates the index to match the working tree. +func (r *Repository) Add() *types.Cmd { cmd := execabs.Command( gitBin, "add", "--all", - "--force", ) - cmd.Dir = repo.WorkDir - - return &types.Cmd{ - Cmd: cmd, - } -} - -// Add updates the index to match the working tree. -func Add(repo Repository) *types.Cmd { - cmd := execabs.Command( - gitBin, - "add", - ) - cmd.Dir = repo.WorkDir - - if repo.Add != "" { - cmd.Args = append(cmd.Args, repo.Add) - } else { - cmd.Args = append(cmd.Args, "--all") - } + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -40,7 +20,7 @@ func Add(repo Repository) *types.Cmd { } // TestCleanTree returns non-zero if diff between index and local repository. -func IsCleanTree(repo Repository) *types.Cmd { +func (r *Repository) IsCleanTree() *types.Cmd { cmd := execabs.Command( gitBin, "diff-index", @@ -48,47 +28,31 @@ func IsCleanTree(repo Repository) *types.Cmd { "HEAD", "--ignore-submodules", ) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, } } -// EmptyCommit simply create an empty commit. -func EmptyCommit(repo Repository) *types.Cmd { - args := []string{ - "commit", - "--allow-empty", - "-m", - repo.CommitMsg, - } - - cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir - - if repo.NoVerify { - cmd.Args = append(cmd.Args, "--no-verify") - } - - return &types.Cmd{ - Cmd: cmd, - } -} - -func Commit(repo Repository) *types.Cmd { +// Commit creates a new commit with the specified commit message. +func (r *Repository) Commit() *types.Cmd { args := []string{ "commit", "-m", - repo.CommitMsg, + r.CommitMsg, + } + + if r.EmptyCommit { + args = append(args, "--allow-empty") + } + + if r.NoVerify { + args = append(args, "--no-verify") } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir - - if repo.NoVerify { - cmd.Args = append(cmd.Args, "--no-verify") - } + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, diff --git a/git/commit_test.go b/git/commit_test.go index b898b82..f8a4c14 100644 --- a/git/commit_test.go +++ b/git/commit_test.go @@ -16,23 +16,14 @@ func TestAdd(t *testing.T) { name: "add all files", repo: Repository{ WorkDir: "/path/to/repo", - Add: "", }, want: []string{gitBin, "add", "--all"}, }, - { - name: "add specific file", - repo: Repository{ - WorkDir: "/path/to/repo", - Add: "file.go", - }, - want: []string{gitBin, "add", "file.go"}, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := Add(tt.repo) + cmd := tt.repo.Add() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -63,41 +54,50 @@ func TestIsCleanTree(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := IsCleanTree(tt.repo) + cmd := tt.repo.IsCleanTree() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) } } -func TestEmptyCommit(t *testing.T) { +func TestCommit(t *testing.T) { tests := []struct { name string repo Repository want []string }{ { - name: "empty commit with default options", + name: "commit with message", repo: Repository{ WorkDir: "/path/to/repo", - CommitMsg: "Empty commit", + CommitMsg: "Initial commit", }, - want: []string{gitBin, "commit", "--allow-empty", "-m", "Empty commit"}, + want: []string{gitBin, "commit", "-m", "Initial commit"}, }, { - name: "empty commit with no-verify option", + name: "commit with empty commit", + repo: Repository{ + WorkDir: "/path/to/repo", + CommitMsg: "Empty commit", + EmptyCommit: true, + }, + want: []string{gitBin, "commit", "-m", "Empty commit", "--allow-empty"}, + }, + { + name: "commit with no verify", repo: Repository{ WorkDir: "/path/to/repo", - CommitMsg: "Empty commit", + CommitMsg: "No verify commit", NoVerify: true, }, - want: []string{gitBin, "commit", "--allow-empty", "-m", "Empty commit", "--no-verify"}, + want: []string{gitBin, "commit", "-m", "No verify commit", "--no-verify"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := EmptyCommit(tt.repo) + cmd := tt.repo.Commit() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) diff --git a/git/config.go b/git/config.go index 1cc97e1..2cbd170 100644 --- a/git/config.go +++ b/git/config.go @@ -9,16 +9,16 @@ import ( // ConfigAutocorrect sets the local git autocorrect configuration for the given repository. // The autocorrect setting determines how git handles minor typos in commands. -func ConfigAutocorrect(repo Repository) *types.Cmd { +func (r *Repository) ConfigAutocorrect() *types.Cmd { args := []string{ "config", "--local", "help.autocorrect", - repo.Autocorrect, + r.Autocorrect, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -26,16 +26,16 @@ func ConfigAutocorrect(repo Repository) *types.Cmd { } // ConfigUserEmail sets the global git author email. -func ConfigUserEmail(repo Repository) *types.Cmd { +func (r *Repository) ConfigUserEmail() *types.Cmd { args := []string{ "config", "--local", "user.email", - repo.Author.Email, + r.Author.Email, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -43,16 +43,16 @@ func ConfigUserEmail(repo Repository) *types.Cmd { } // ConfigUserName configures the user.name git config setting for the given repository. -func ConfigUserName(repo Repository) *types.Cmd { +func (r *Repository) ConfigUserName() *types.Cmd { args := []string{ "config", "--local", "user.name", - repo.Author.Name, + r.Author.Name, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -60,7 +60,7 @@ func ConfigUserName(repo Repository) *types.Cmd { } // ConfigSSLVerify configures the http.sslVerify git config setting for the given repository. -func ConfigSSLVerify(repo Repository, skipVerify bool) *types.Cmd { +func (r *Repository) ConfigSSLVerify(skipVerify bool) *types.Cmd { args := []string{ "config", "--local", @@ -69,7 +69,7 @@ func ConfigSSLVerify(repo Repository, skipVerify bool) *types.Cmd { } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, diff --git a/git/config_test.go b/git/config_test.go index e0d9651..e7d6f62 100644 --- a/git/config_test.go +++ b/git/config_test.go @@ -32,7 +32,7 @@ func TestConfigAutocorrect(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := ConfigAutocorrect(tt.repo) + cmd := tt.repo.ConfigAutocorrect() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -59,7 +59,7 @@ func TestConfigUserEmail(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := ConfigUserEmail(tt.repo) + cmd := tt.repo.ConfigUserEmail() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -86,7 +86,7 @@ func TestConfigUserName(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := ConfigUserName(tt.repo) + cmd := tt.repo.ConfigUserName() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -116,7 +116,7 @@ func TestConfigSSLVerify(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := ConfigSSLVerify(tt.repo, tt.skipVerify) + cmd := tt.repo.ConfigSSLVerify(tt.skipVerify) require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) diff --git a/git/type.go b/git/git.go similarity index 95% rename from git/type.go rename to git/git.go index 6d748fa..fadf380 100644 --- a/git/type.go +++ b/git/git.go @@ -1,7 +1,5 @@ package git -const gitBin = "/usr/bin/git" - type Author struct { Name string Email string @@ -12,7 +10,6 @@ type Repository struct { RemoteURL string Branch string - Add string CommitMsg string Autocorrect string @@ -25,3 +22,5 @@ type Repository struct { Author Author } + +const gitBin = "/usr/bin/git" diff --git a/git/init.go b/git/init.go index 962c5f8..ea7ec4b 100644 --- a/git/init.go +++ b/git/init.go @@ -6,15 +6,15 @@ import ( ) // Init creates a new Git repository in the specified directory. -func Init(repo Repository) *types.Cmd { +func (r *Repository) Init() *types.Cmd { args := []string{ "init", "-b", - repo.Branch, + r.Branch, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, diff --git a/git/init_test.go b/git/init_test.go index bb82790..bd3787a 100644 --- a/git/init_test.go +++ b/git/init_test.go @@ -24,7 +24,7 @@ func TestInit(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := Init(tt.repo) + cmd := tt.repo.Init() require.Equal(t, tt.expected, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) diff --git a/git/remote.go b/git/remote.go index 4ab71d4..d308bfa 100644 --- a/git/remote.go +++ b/git/remote.go @@ -8,15 +8,15 @@ import ( ) // RemoteRemove drops the defined remote from a git repo. -func RemoteRemove(repo Repository) *types.Cmd { +func (r *Repository) RemoteRemove() *types.Cmd { args := []string{ "remote", "rm", - repo.RemoteName, + r.RemoteName, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -24,16 +24,16 @@ func RemoteRemove(repo Repository) *types.Cmd { } // RemoteAdd adds an additional remote to a git repo. -func RemoteAdd(repo Repository) *types.Cmd { +func (r *Repository) RemoteAdd() *types.Cmd { args := []string{ "remote", "add", - repo.RemoteName, - repo.RemoteURL, + r.RemoteName, + r.RemoteURL, } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -41,21 +41,21 @@ func RemoteAdd(repo Repository) *types.Cmd { } // RemotePush pushs the changes from the local head to a remote branch. -func RemotePush(repo Repository) *types.Cmd { +func (r *Repository) RemotePush() *types.Cmd { args := []string{ "push", - repo.RemoteName, - fmt.Sprintf("HEAD:%s", repo.Branch), + r.RemoteName, + fmt.Sprintf("HEAD:%s", r.Branch), } cmd := execabs.Command(gitBin, args...) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir - if repo.ForcePush { + if r.ForcePush { cmd.Args = append(cmd.Args, "--force") } - if repo.PushFollowTags { + if r.PushFollowTags { cmd.Args = append(cmd.Args, "--follow-tags") } diff --git a/git/remote_test.go b/git/remote_test.go index 5afc3b7..859f513 100644 --- a/git/remote_test.go +++ b/git/remote_test.go @@ -39,7 +39,7 @@ func TestRemoteRemove(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := RemoteRemove(tt.repo) + cmd := tt.repo.RemoteRemove() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -73,7 +73,7 @@ func TestRemoteAdd(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := RemoteAdd(tt.repo) + cmd := tt.repo.RemoteAdd() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -131,7 +131,7 @@ func TestRemotePush(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := RemotePush(tt.repo) + cmd := tt.repo.RemotePush() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) diff --git a/git/status.go b/git/status.go index c3b82f0..e5fb570 100644 --- a/git/status.go +++ b/git/status.go @@ -7,13 +7,13 @@ import ( ) // Status returns a command that runs `git status --porcelain` for the given repository. -func Status(repo Repository) *types.Cmd { +func (r *Repository) Status() *types.Cmd { cmd := execabs.Command( gitBin, "status", "--porcelain", ) - cmd.Dir = repo.WorkDir + cmd.Dir = r.WorkDir return &types.Cmd{ Cmd: cmd, @@ -24,9 +24,9 @@ func Status(repo Repository) *types.Cmd { // It runs `git status --porcelain` and returns true if the output is non-empty, // indicating that there are uncommitted changes in the repository. // If there is an error running the git command, it returns false. -func IsDirty(repo Repository) bool { - cmd := Status(repo) - cmd.Dir = repo.WorkDir +func (r *Repository) IsDirty() bool { + cmd := r.Status() + cmd.Dir = r.WorkDir out, err := cmd.CombinedOutput() if err != nil { diff --git a/git/status_test.go b/git/status_test.go index 9f12d65..b5752bb 100644 --- a/git/status_test.go +++ b/git/status_test.go @@ -37,7 +37,7 @@ func TestStatus(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := Status(tt.repo) + cmd := tt.repo.Status() require.Equal(t, tt.want, cmd.Cmd.Args) require.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir) }) @@ -70,7 +70,7 @@ func TestIsDirty(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := Init(tt.repo).Run(); err != nil { + if err := tt.repo.Init().Run(); err != nil { require.NoError(t, err) } @@ -79,7 +79,7 @@ func TestIsDirty(t *testing.T) { require.NoError(t, err) } - isDirty := IsDirty(tt.repo) + isDirty := tt.repo.IsDirty() require.Equal(t, tt.want, isDirty) }) } diff --git a/git/util.go b/git/util.go deleted file mode 100644 index 300d3e1..0000000 --- a/git/util.go +++ /dev/null @@ -1,56 +0,0 @@ -package git - -import ( - "fmt" - "os" - "path/filepath" -) - -const ( - netrcFile = `machine %s -login %s -password %s -` - configFile = `Host * -StrictHostKeyChecking no -UserKnownHostsFile=/dev/null -` -) - -const ( - strictFilePerm = 0o600 - strictDirPerm = 0o700 -) - -// WriteKey writes the SSH private key. -func WriteSSHKey(path, key string) error { - sshPath := filepath.Join(path, ".ssh") - confPath := filepath.Join(sshPath, "config") - keyPath := filepath.Join(sshPath, "id_rsa") - - if err := os.MkdirAll(sshPath, strictDirPerm); err != nil { - return fmt.Errorf("failed to create .ssh directory: %w", err) - } - - if err := os.WriteFile(confPath, []byte(configFile), strictFilePerm); err != nil { - return fmt.Errorf("failed to create .ssh/config file: %w", err) - } - - if err := os.WriteFile(keyPath, []byte(key), strictFilePerm); err != nil { - return fmt.Errorf("failed to create .ssh/id_rsa file: %w", err) - } - - return nil -} - -// WriteNetrc writes the netrc file. -func WriteNetrc(path, machine, login, password string) error { - netrcPath := filepath.Join(path, ".netrc") - netrcContent := fmt.Sprintf(netrcFile, machine, login, password) - - if err := os.WriteFile(netrcPath, []byte(netrcContent), strictFilePerm); err != nil { - return fmt.Errorf("failed to create .netrc file: %w", err) - } - - return nil -} diff --git a/go.mod b/go.mod index 7b2af17..13fcfb1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( github.com/rs/zerolog v1.32.0 github.com/stretchr/testify v1.9.0 - github.com/thegeeklab/wp-plugin-go/v2 v2.2.0 + github.com/thegeeklab/wp-plugin-go/v2 v2.3.0 github.com/urfave/cli/v2 v2.27.2 golang.org/x/sys v0.20.0 ) diff --git a/go.sum b/go.sum index c0ce16c..1cd47d6 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/thegeeklab/wp-plugin-go/v2 v2.2.0 h1:Z6UzL8N0v3J2uuk67DBnH19QNV1vXihaKC2OoH2TMAY= -github.com/thegeeklab/wp-plugin-go/v2 v2.2.0/go.mod h1:I/3M/4OPvr4FFS+s0aaImpX1llA/lS2KC6Bnp+qzsCs= +github.com/thegeeklab/wp-plugin-go/v2 v2.3.0 h1:9LOdITzjxEEbgcH9yU0tDZL0dcDZzNYzbk2+hZ5QsBA= +github.com/thegeeklab/wp-plugin-go/v2 v2.3.0/go.mod h1:I/3M/4OPvr4FFS+s0aaImpX1llA/lS2KC6Bnp+qzsCs= github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= diff --git a/plugin/impl.go b/plugin/impl.go index c28d6d0..fcd7cbd 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -7,9 +7,9 @@ import ( "os" "path/filepath" - "github.com/thegeeklab/wp-git-action/git" "github.com/thegeeklab/wp-plugin-go/v2/file" "github.com/thegeeklab/wp-plugin-go/v2/types" + "github.com/thegeeklab/wp-plugin-go/v2/util" ) var ( @@ -46,16 +46,14 @@ func (p *Plugin) run(ctx context.Context) error { func (p *Plugin) Validate() error { var err error - if p.Settings.Repo.WorkDir == "" { - p.Settings.Repo.WorkDir, err = os.Getwd() - } - p.Settings.Repo.Autocorrect = "never" p.Settings.Repo.RemoteName = "origin" - p.Settings.Repo.Add = "" - if err != nil { - return fmt.Errorf("failed to get working directory: %w", err) + if p.Settings.Repo.WorkDir == "" { + p.Settings.Repo.WorkDir, err = os.Getwd() + if err != nil { + return fmt.Errorf("failed to get working directory: %w", err) + } } for _, actionStr := range p.Settings.Action.Value() { @@ -104,7 +102,7 @@ func (p *Plugin) Validate() error { func (p *Plugin) Execute() error { var err error - homeDir := getUserHomeDir() + homeDir := util.GetUserHomeDir() batchCmd := make([]*types.Cmd, 0) gitEnv := []string{ "GIT_AUTHOR_NAME", @@ -127,13 +125,13 @@ func (p *Plugin) Execute() error { // Write SSH key and netrc file. if p.Settings.SSHKey != "" { - if err := git.WriteSSHKey(homeDir, p.Settings.SSHKey); err != nil { + if err := WriteSSHKey(homeDir, p.Settings.SSHKey); err != nil { return err } } netrc := p.Settings.Netrc - if err := git.WriteNetrc(homeDir, netrc.Machine, netrc.Login, netrc.Password); err != nil { + if err := WriteNetrc(homeDir, netrc.Machine, netrc.Login, netrc.Password); err != nil { return err } @@ -153,14 +151,14 @@ func (p *Plugin) Execute() error { } if !isDir { - batchCmd = append(batchCmd, git.Init(p.Settings.Repo)) + batchCmd = append(batchCmd, p.Settings.Repo.Init()) } // Handle repo configuration. - batchCmd = append(batchCmd, git.ConfigAutocorrect(p.Settings.Repo)) - batchCmd = append(batchCmd, git.ConfigUserName(p.Settings.Repo)) - batchCmd = append(batchCmd, git.ConfigUserEmail(p.Settings.Repo)) - batchCmd = append(batchCmd, git.ConfigSSLVerify(p.Settings.Repo, p.Network.InsecureSkipVerify)) + batchCmd = append(batchCmd, p.Settings.Repo.ConfigAutocorrect()) + batchCmd = append(batchCmd, p.Settings.Repo.ConfigUserName()) + batchCmd = append(batchCmd, p.Settings.Repo.ConfigUserEmail()) + batchCmd = append(batchCmd, p.Settings.Repo.ConfigSSLVerify(p.Network.InsecureSkipVerify)) for _, actionStr := range p.Settings.Action.Value() { action := Action(actionStr) @@ -205,11 +203,11 @@ func (p *Plugin) handleClone() ([]*types.Cmd, error) { } if p.Settings.Repo.RemoteURL != "" { - cmds = append(cmds, git.RemoteAdd(p.Settings.Repo)) + cmds = append(cmds, p.Settings.Repo.RemoteAdd()) } - cmds = append(cmds, git.FetchSource(p.Settings.Repo)) - cmds = append(cmds, git.CheckoutHead(p.Settings.Repo)) + cmds = append(cmds, p.Settings.Repo.FetchSource()) + cmds = append(cmds, p.Settings.Repo.CheckoutHead()) return cmds, nil } @@ -218,14 +216,10 @@ func (p *Plugin) handleClone() ([]*types.Cmd, error) { func (p *Plugin) handleCommit() []*types.Cmd { var cmds []*types.Cmd - cmds = append(cmds, git.Add(p.Settings.Repo)) + cmds = append(cmds, p.Settings.Repo.Add()) - if err := git.IsCleanTree(p.Settings.Repo).Run(); err != nil { - cmds = append(cmds, git.Commit(p.Settings.Repo)) - } - - if p.Settings.Repo.EmptyCommit { - cmds = append(cmds, git.EmptyCommit(p.Settings.Repo)) + if err := p.Settings.Repo.IsCleanTree().Run(); err != nil || p.Settings.Repo.EmptyCommit { + cmds = append(cmds, p.Settings.Repo.Commit()) } return cmds @@ -233,7 +227,7 @@ func (p *Plugin) handleCommit() []*types.Cmd { // HandlePush pushs changes to remote. func (p *Plugin) handlePush() []*types.Cmd { - return []*types.Cmd{git.RemotePush(p.Settings.Repo)} + return []*types.Cmd{p.Settings.Repo.RemotePush()} } // HandlePages syncs, commits and pushes the changes from the pages directory to the pages branch. diff --git a/plugin/util.go b/plugin/util.go index ed001f3..143beca 100644 --- a/plugin/util.go +++ b/plugin/util.go @@ -1,15 +1,56 @@ package plugin import ( - "os/user" + "fmt" + "os" + "path/filepath" ) -func getUserHomeDir() string { - home := "/root" +const ( + netrcFile = `machine %s +login %s +password %s +` + configFile = `Host * +StrictHostKeyChecking no +UserKnownHostsFile=/dev/null +` +) - if currentUser, err := user.Current(); err == nil { - home = currentUser.HomeDir +const ( + strictFilePerm = 0o600 + strictDirPerm = 0o700 +) + +// WriteKey writes the SSH private key. +func WriteSSHKey(path, key string) error { + sshPath := filepath.Join(path, ".ssh") + confPath := filepath.Join(sshPath, "config") + keyPath := filepath.Join(sshPath, "id_rsa") + + if err := os.MkdirAll(sshPath, strictDirPerm); err != nil { + return fmt.Errorf("failed to create .ssh directory: %w", err) } - return home + if err := os.WriteFile(confPath, []byte(configFile), strictFilePerm); err != nil { + return fmt.Errorf("failed to create .ssh/config file: %w", err) + } + + if err := os.WriteFile(keyPath, []byte(key), strictFilePerm); err != nil { + return fmt.Errorf("failed to create .ssh/id_rsa file: %w", err) + } + + return nil +} + +// WriteNetrc writes the netrc file. +func WriteNetrc(path, machine, login, password string) error { + netrcPath := filepath.Join(path, ".netrc") + netrcContent := fmt.Sprintf(netrcFile, machine, login, password) + + if err := os.WriteFile(netrcPath, []byte(netrcContent), strictFilePerm); err != nil { + return fmt.Errorf("failed to create .netrc file: %w", err) + } + + return nil } diff --git a/git/util_test.go b/plugin/util_test.go similarity index 99% rename from git/util_test.go rename to plugin/util_test.go index 81b4580..9d35e5d 100644 --- a/git/util_test.go +++ b/plugin/util_test.go @@ -1,4 +1,4 @@ -package git +package plugin import ( "fmt"