0
0
mirror of https://github.com/thegeeklab/wp-git-action.git synced 2024-11-10 03:20:40 +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 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 { func (r *Repository) IsCleanTree() *types.Cmd {
cmd := &types.Cmd{ args := []string{
Cmd: execabs.Command(
gitBin,
"diff-index", "diff-index",
"--quiet", "--quiet",
"HEAD", "HEAD",
"--ignore-submodules", "--ignore-submodules",
),
} }
cmd := &types.Cmd{
Cmd: execabs.Command(gitBin, args...),
}
cmd.Dir = r.WorkDir cmd.Dir = r.WorkDir
cmd.Stdout = io.Discard cmd.Stdout = io.Discard
cmd.Stderr = 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. // Commit creates a new commit with the specified commit message.
func (r *Repository) Commit() *types.Cmd { func (r *Repository) Commit() *types.Cmd {
if err := r.IsCleanTree().Run(); err == nil && !r.EmptyCommit {
return nil
}
args := []string{ args := []string{
"commit", "commit",
"-m", "-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. // Execute provides the implementation of the plugin.
//
//nolint:gocognit
func (p *Plugin) Execute() error { func (p *Plugin) Execute() error {
var err 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.ConfigUserEmail())
batchCmd = append(batchCmd, p.Settings.Repo.ConfigSSLVerify(p.Network.InsecureSkipVerify)) 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() { for _, actionStr := range p.Settings.Action.Value() {
action := GitAction(actionStr) action := GitAction(actionStr)
switch action { switch action {
case GitActionClone: case GitActionClone:
log.Debug().Msg("Compose action cmd: clone") log.Debug().Msg("Compose action cmd: clone")
cmds, err := p.handleClone() if err := p.handleClone(); err != nil {
if err != nil {
return err return err
} }
batchCmd = append(batchCmd, cmds...)
case GitActionCommit: case GitActionCommit:
log.Debug().Msg("Compose action cmd: commit") log.Debug().Msg("Compose action cmd: commit")
batchCmd = append(batchCmd, p.handleCommit()...) if err := p.handleCommit(); err != nil {
return err
}
case GitActionPush: case GitActionPush:
log.Debug().Msg("Compose action cmd: push") log.Debug().Msg("Compose action cmd: push")
batchCmd = append(batchCmd, p.handlePush()...) if err := p.handlePush(); err != nil {
return err
}
case GitActionPages: case GitActionPages:
log.Debug().Msg("Compose action cmd: pages") log.Debug().Msg("Compose action cmd: pages")
cmds, err := p.handlePages() if err := p.handleClone(); err != nil {
if err != nil {
return err return err
} }
batchCmd = append(batchCmd, cmds...) if err := p.handlePages(); err != nil {
}
}
for _, cmd := range batchCmd {
if cmd == nil {
continue
}
if err := cmd.Run(); err != nil {
return err return err
} }
if err := p.handleCommit(); err != nil {
return err
}
if err := p.handlePush(); err != nil {
return err
}
}
} }
return nil return nil
@ -208,65 +214,57 @@ func (p *Plugin) Execute() error {
// handleClone clones the remote repository into the configured working directory. // handleClone clones the remote repository into the configured working directory.
// If the working directory is not empty, it returns an error. // If the working directory is not empty, it returns an error.
func (p *Plugin) handleClone() ([]*types.Cmd, error) { func (p *Plugin) handleClone() error {
var cmds []*types.Cmd var batchCmd []*types.Cmd
if !p.Settings.Repo.IsEmpty { 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 != "" { 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()) batchCmd = append(batchCmd, p.Settings.Repo.FetchSource())
cmds = append(cmds, p.Settings.Repo.CheckoutHead()) batchCmd = append(batchCmd, p.Settings.Repo.CheckoutHead())
return cmds, nil return ExecBatch(batchCmd)
} }
// HandleCommit commits changes locally. // HandleCommit commits changes locally.
func (p *Plugin) handleCommit() []*types.Cmd { func (p *Plugin) handleCommit() error {
var cmds []*types.Cmd if err := p.Settings.Repo.Add().Run(); err != nil {
return err
}
cmds = append(cmds, p.Settings.Repo.Add()) if err := p.Settings.Repo.IsCleanTree().Run(); err == nil {
cmds = append(cmds, p.Settings.Repo.Commit()) 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. // HandlePush pushs changes to remote.
func (p *Plugin) handlePush() []*types.Cmd { func (p *Plugin) handlePush() error {
return []*types.Cmd{p.Settings.Repo.RemotePush()} return p.Settings.Repo.RemotePush().Run()
} }
// HandlePages syncs, commits and pushes the changes from the pages directory to the pages branch. // HandlePages syncs, commits and pushes the changes from the pages directory to the pages branch.
func (p *Plugin) handlePages() ([]*types.Cmd, error) { func (p *Plugin) handlePages() error {
var cmds []*types.Cmd
log.Debug(). log.Debug().
Str("src", p.Settings.Pages.Directory). Str("src", p.Settings.Pages.Directory).
Str("dest", p.Settings.Repo.WorkDir). Str("dest", p.Settings.Repo.WorkDir).
Msg("handlePages") Msg("handlePages")
ccmd, err := p.handleClone() return SyncDirectories(
if err != nil {
return cmds, err
}
cmds = append(cmds, ccmd...)
cmds = append(cmds,
SyncDirectories(
p.Settings.Pages.Exclude.Value(), p.Settings.Pages.Exclude.Value(),
p.Settings.Pages.Delete, p.Settings.Pages.Delete,
p.Settings.Pages.Directory, p.Settings.Pages.Directory,
p.Settings.Repo.WorkDir, p.Settings.Repo.WorkDir,
(zerolog.GlobalLevel() == zerolog.DebugLevel), (zerolog.GlobalLevel() == zerolog.DebugLevel),
), ).Run()
)
cmds = append(cmds, p.handleCommit()...)
cmds = append(cmds, p.handlePush()...)
return cmds, nil
} }

View File

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"github.com/thegeeklab/wp-plugin-go/v2/types"
) )
const ( const (
@ -26,3 +28,18 @@ func WriteNetrc(path, machine, login, password string) error {
return nil 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
}