0
0
mirror of https://github.com/thegeeklab/wp-git-action.git synced 2024-11-22 00:00:39 +00:00

fix: revert to adhoc commands for actions (#119)

This commit is contained in:
Robert Kaussow 2024-05-14 13:39:04 +02:00 committed by GitHub
parent c1402d7c33
commit 5a85b78897
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 78 additions and 196 deletions

View File

@ -21,18 +21,18 @@ func (r *Repository) Add() *types.Cmd {
return cmd
}
// TestCleanTree returns non-zero if diff between index and local repository.
// IsCleanTree returns non-zero if diff between index and local repository.
func (r *Repository) IsCleanTree() *types.Cmd {
cmd := &types.Cmd{
Cmd: execabs.Command(
gitBin,
args := []string{
"diff-index",
"--quiet",
"HEAD",
"--ignore-submodules",
),
}
cmd := &types.Cmd{
Cmd: execabs.Command(gitBin, args...),
}
cmd.Dir = r.WorkDir
cmd.Stdout = io.Discard
cmd.Stderr = io.Discard
@ -43,10 +43,6 @@ func (r *Repository) IsCleanTree() *types.Cmd {
// Commit creates a new commit with the specified commit message.
func (r *Repository) Commit() *types.Cmd {
if err := r.IsCleanTree().Run(); err == nil && !r.EmptyCommit {
return nil
}
args := []string{
"commit",
"-m",

View File

@ -1,43 +0,0 @@
package git
import (
"github.com/rs/zerolog/log"
"github.com/thegeeklab/wp-plugin-go/v2/types"
"golang.org/x/sys/execabs"
)
// Status returns a command that runs `git status --porcelain` for the given repository.
func (r *Repository) Status() *types.Cmd {
cmd := &types.Cmd{
Cmd: execabs.Command(
gitBin,
"status",
"--porcelain",
),
}
cmd.Dir = r.WorkDir
return cmd
}
// IsDirty checks if the given repository has any uncommitted changes.
// 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 (r *Repository) IsDirty() bool {
cmd := r.Status()
cmd.Dir = r.WorkDir
out, err := cmd.CombinedOutput()
if err != nil {
return false
}
if len(out) > 0 {
log.Debug().Msg(string(out))
return true
}
return false
}

View File

@ -1,86 +0,0 @@
package git
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestStatus(t *testing.T) {
tests := []struct {
name string
repo Repository
want []string
}{
{
name: "with work dir",
repo: Repository{
WorkDir: "/path/to/repo",
},
want: []string{gitBin, "status", "--porcelain"},
},
{
name: "without work dir",
repo: Repository{},
want: []string{gitBin, "status", "--porcelain"},
},
{
name: "with custom stderr",
repo: Repository{
WorkDir: "/path/to/repo",
},
want: []string{gitBin, "status", "--porcelain"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cmd := tt.repo.Status()
assert.Equal(t, tt.want, cmd.Cmd.Args)
assert.Equal(t, tt.repo.WorkDir, cmd.Cmd.Dir)
})
}
}
func TestIsDirty(t *testing.T) {
tests := []struct {
name string
repo Repository
want bool
}{
{
name: "dirty repo",
repo: Repository{
WorkDir: t.TempDir(),
Branch: "main",
},
want: true,
},
{
name: "clean repo",
repo: Repository{
WorkDir: t.TempDir(),
Branch: "main",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.repo.Init().Run(); err != nil {
assert.NoError(t, err)
}
if tt.want {
_, err := os.Create(filepath.Join(tt.repo.WorkDir, "dummy"))
assert.NoError(t, err)
}
isDirty := tt.repo.IsDirty()
assert.Equal(t, tt.want, isDirty)
})
}
}

View File

@ -101,6 +101,8 @@ func (p *Plugin) Validate() error {
}
// Execute provides the implementation of the plugin.
//
//nolint:gocognit
func (p *Plugin) Execute() error {
var err error
@ -161,46 +163,50 @@ func (p *Plugin) Execute() error {
batchCmd = append(batchCmd, p.Settings.Repo.ConfigUserEmail())
batchCmd = append(batchCmd, p.Settings.Repo.ConfigSSLVerify(p.Network.InsecureSkipVerify))
if err := ExecBatch(batchCmd); err != nil {
return err
}
for _, actionStr := range p.Settings.Action.Value() {
action := GitAction(actionStr)
switch action {
case GitActionClone:
log.Debug().Msg("Compose action cmd: clone")
cmds, err := p.handleClone()
if err != nil {
if err := p.handleClone(); err != nil {
return err
}
batchCmd = append(batchCmd, cmds...)
case GitActionCommit:
log.Debug().Msg("Compose action cmd: commit")
batchCmd = append(batchCmd, p.handleCommit()...)
if err := p.handleCommit(); err != nil {
return err
}
case GitActionPush:
log.Debug().Msg("Compose action cmd: push")
batchCmd = append(batchCmd, p.handlePush()...)
if err := p.handlePush(); err != nil {
return err
}
case GitActionPages:
log.Debug().Msg("Compose action cmd: pages")
cmds, err := p.handlePages()
if err != nil {
if err := p.handleClone(); err != nil {
return err
}
batchCmd = append(batchCmd, cmds...)
}
}
for _, cmd := range batchCmd {
if cmd == nil {
continue
}
if err := cmd.Run(); err != nil {
if err := p.handlePages(); err != nil {
return err
}
if err := p.handleCommit(); err != nil {
return err
}
if err := p.handlePush(); err != nil {
return err
}
}
}
return nil
@ -208,65 +214,57 @@ func (p *Plugin) Execute() error {
// handleClone clones the remote repository into the configured working directory.
// If the working directory is not empty, it returns an error.
func (p *Plugin) handleClone() ([]*types.Cmd, error) {
var cmds []*types.Cmd
func (p *Plugin) handleClone() error {
var batchCmd []*types.Cmd
if !p.Settings.Repo.IsEmpty {
return cmds, fmt.Errorf("%w: %s exists and not empty", ErrGitCloneDestintionNotValid, p.Settings.Repo.WorkDir)
return fmt.Errorf("%w: %s exists and not empty", ErrGitCloneDestintionNotValid, p.Settings.Repo.WorkDir)
}
if p.Settings.Repo.RemoteURL != "" {
cmds = append(cmds, p.Settings.Repo.RemoteAdd())
batchCmd = append(batchCmd, p.Settings.Repo.RemoteAdd())
}
cmds = append(cmds, p.Settings.Repo.FetchSource())
cmds = append(cmds, p.Settings.Repo.CheckoutHead())
batchCmd = append(batchCmd, p.Settings.Repo.FetchSource())
batchCmd = append(batchCmd, p.Settings.Repo.CheckoutHead())
return cmds, nil
return ExecBatch(batchCmd)
}
// HandleCommit commits changes locally.
func (p *Plugin) handleCommit() []*types.Cmd {
var cmds []*types.Cmd
func (p *Plugin) handleCommit() error {
if err := p.Settings.Repo.Add().Run(); err != nil {
return err
}
cmds = append(cmds, p.Settings.Repo.Add())
cmds = append(cmds, p.Settings.Repo.Commit())
if err := p.Settings.Repo.IsCleanTree().Run(); err == nil {
if !p.Settings.Repo.EmptyCommit {
log.Debug().Msg("Commit skipped: no changes")
return cmds
return nil
}
}
return p.Settings.Repo.Commit().Run()
}
// HandlePush pushs changes to remote.
func (p *Plugin) handlePush() []*types.Cmd {
return []*types.Cmd{p.Settings.Repo.RemotePush()}
func (p *Plugin) handlePush() error {
return p.Settings.Repo.RemotePush().Run()
}
// HandlePages syncs, commits and pushes the changes from the pages directory to the pages branch.
func (p *Plugin) handlePages() ([]*types.Cmd, error) {
var cmds []*types.Cmd
func (p *Plugin) handlePages() error {
log.Debug().
Str("src", p.Settings.Pages.Directory).
Str("dest", p.Settings.Repo.WorkDir).
Msg("handlePages")
ccmd, err := p.handleClone()
if err != nil {
return cmds, err
}
cmds = append(cmds, ccmd...)
cmds = append(cmds,
SyncDirectories(
return SyncDirectories(
p.Settings.Pages.Exclude.Value(),
p.Settings.Pages.Delete,
p.Settings.Pages.Directory,
p.Settings.Repo.WorkDir,
(zerolog.GlobalLevel() == zerolog.DebugLevel),
),
)
cmds = append(cmds, p.handleCommit()...)
cmds = append(cmds, p.handlePush()...)
return cmds, nil
).Run()
}

View File

@ -4,6 +4,8 @@ import (
"fmt"
"os"
"path/filepath"
"github.com/thegeeklab/wp-plugin-go/v2/types"
)
const (
@ -26,3 +28,18 @@ func WriteNetrc(path, machine, login, password string) error {
return nil
}
// ExecBatch executes a batch of commands. If any command in the batch fails, the function will return the error.
func ExecBatch(batchCmd []*types.Cmd) error {
for _, cmd := range batchCmd {
if cmd == nil {
continue
}
if err := cmd.Run(); err != nil {
return err
}
}
return nil
}