mirror of
https://github.com/Jguer/yay
synced 2024-10-05 23:59:13 +00:00
feat(vcs): test upDevel and extract OS runner
This commit is contained in:
parent
4a761c287b
commit
9ad2862b7d
49
exec.go
49
exec.go
|
@ -121,56 +121,17 @@ func passToMakepkg(dir string, args ...string) *exec.Cmd {
|
|||
}
|
||||
|
||||
func passToGit(dir string, _args ...string) *exec.Cmd {
|
||||
gitflags := strings.Fields(config.GitFlags)
|
||||
args := []string{"-C", dir}
|
||||
args = append(args, gitflags...)
|
||||
args := strings.Fields(config.GitFlags)
|
||||
if dir != "" {
|
||||
args = append(args, "-C", dir)
|
||||
}
|
||||
args = append(args, _args...)
|
||||
|
||||
cmd := exec.Command(config.GitBin, args...)
|
||||
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func isTty() bool {
|
||||
return terminal.IsTerminal(int(os.Stdout.Fd()))
|
||||
}
|
||||
|
||||
type Runner interface {
|
||||
Capture(string, int64, ...string) (string, string, error)
|
||||
}
|
||||
|
||||
type OSRunner struct{}
|
||||
|
||||
func (r *OSRunner) Capture(command string, timeout int64, args ...string) (stdout, stderr string, err error) {
|
||||
var outbuf, errbuf bytes.Buffer
|
||||
var timer *time.Timer
|
||||
|
||||
cmd := exec.Command(command, args...)
|
||||
cmd.Stdout = &outbuf
|
||||
cmd.Stderr = &errbuf
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if timeout != 0 {
|
||||
timer = time.AfterFunc(time.Duration(timeout)*time.Second, func() {
|
||||
err = cmd.Process.Kill()
|
||||
if err != nil {
|
||||
text.Errorln(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if timeout != 0 {
|
||||
timer.Stop()
|
||||
}
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
stdout = strings.TrimSpace(outbuf.String())
|
||||
stderr = strings.TrimSpace(errbuf.String())
|
||||
|
||||
return stdout, stderr, err
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Morganamilo/go-pacmanconf"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Jguer/yay/v10/pkg/text"
|
||||
)
|
||||
|
||||
type TargetMode int
|
||||
|
@ -25,6 +32,62 @@ const (
|
|||
ModeRepo
|
||||
)
|
||||
|
||||
type Runner interface {
|
||||
Capture(cmd *exec.Cmd, timeout int64) (stdout string, stderr string, err error)
|
||||
Show(cmd *exec.Cmd) error
|
||||
}
|
||||
|
||||
type OSRunner struct {
|
||||
}
|
||||
|
||||
func (r *OSRunner) Show(cmd *exec.Cmd) error {
|
||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
|
||||
var outbuf, errbuf bytes.Buffer
|
||||
var timer *time.Timer
|
||||
timedOut := false
|
||||
|
||||
cmd.Stdout = &outbuf
|
||||
cmd.Stderr = &errbuf
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if timeout != 0 {
|
||||
timer = time.AfterFunc(time.Duration(timeout)*time.Second, func() {
|
||||
err = cmd.Process.Kill()
|
||||
if err != nil {
|
||||
text.Errorln(err)
|
||||
}
|
||||
timedOut = true
|
||||
})
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if timeout != 0 {
|
||||
timer.Stop()
|
||||
}
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
stdout = strings.TrimSpace(outbuf.String())
|
||||
stderr = strings.TrimSpace(errbuf.String())
|
||||
if timedOut {
|
||||
err = fmt.Errorf("command timed out")
|
||||
}
|
||||
|
||||
return stdout, stderr, err
|
||||
}
|
||||
|
||||
type Runtime struct {
|
||||
Mode TargetMode
|
||||
SaveConfig bool
|
||||
|
@ -32,6 +95,7 @@ type Runtime struct {
|
|||
ConfigPath string
|
||||
VCSPath string
|
||||
PacmanConf *pacmanconf.Config
|
||||
CmdRunner Runner
|
||||
}
|
||||
|
||||
func MakeRuntime() (*Runtime, error) {
|
||||
|
@ -42,6 +106,7 @@ func MakeRuntime() (*Runtime, error) {
|
|||
Mode: ModeAny,
|
||||
SaveConfig: false,
|
||||
CompletionPath: "",
|
||||
CmdRunner: &OSRunner{},
|
||||
}
|
||||
|
||||
if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
||||
|
|
129
upgrade_test.go
129
upgrade_test.go
|
@ -1,17 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Jguer/yay/v10/pkg/db"
|
||||
"github.com/Jguer/yay/v10/pkg/db/mock"
|
||||
"github.com/Jguer/yay/v10/pkg/upgrade"
|
||||
"github.com/bradleyjkemp/cupaloy"
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/Jguer/yay/v10/pkg/db"
|
||||
"github.com/Jguer/yay/v10/pkg/db/mock"
|
||||
"github.com/Jguer/yay/v10/pkg/settings"
|
||||
"github.com/Jguer/yay/v10/pkg/upgrade"
|
||||
)
|
||||
|
||||
func Test_upAUR(t *testing.T) {
|
||||
|
@ -68,16 +73,51 @@ func Test_upAUR(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type MockRunner struct {
|
||||
Returned []string
|
||||
Index int
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (r *MockRunner) Show(cmd *exec.Cmd) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *MockRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
|
||||
i, _ := strconv.Atoi(cmd.Args[len(cmd.Args)-1])
|
||||
if i >= len(r.Returned) {
|
||||
fmt.Println(r.Returned)
|
||||
fmt.Println(cmd.Args)
|
||||
fmt.Println(i)
|
||||
}
|
||||
stdout = r.Returned[i]
|
||||
assert.Contains(r.t, cmd.Args, "ls-remote")
|
||||
return stdout, stderr, err
|
||||
}
|
||||
|
||||
func Test_upDevel(t *testing.T) {
|
||||
config = settings.MakeConfig()
|
||||
config.Runtime, _ = settings.MakeRuntime()
|
||||
config.Runtime.CmdRunner = &MockRunner{
|
||||
Returned: []string{
|
||||
"7f4c277ce7149665d1c79b76ca8fbb832a65a03b HEAD",
|
||||
"7f4c277ce7149665d1c79b76ca8fbb832a65a03b HEAD",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa HEAD",
|
||||
"cccccccccccccccccccccccccccccccccccccccc HEAD",
|
||||
"991c5b4146fd27f4aacf4e3111258a848934aaa1 HEAD",
|
||||
},
|
||||
}
|
||||
|
||||
type args struct {
|
||||
remote []db.RepoPackage
|
||||
aurdata map[string]*rpc.Pkg
|
||||
cached vcsInfo
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want upgrade.UpSlice
|
||||
name string
|
||||
args args
|
||||
want upgrade.UpSlice
|
||||
finalLen int
|
||||
}{
|
||||
{name: "No Updates",
|
||||
args: args{
|
||||
|
@ -92,22 +132,89 @@ func Test_upDevel(t *testing.T) {
|
|||
},
|
||||
want: upgrade.UpSlice{}},
|
||||
{name: "Simple Update",
|
||||
finalLen: 3,
|
||||
args: args{
|
||||
cached: vcsInfo{
|
||||
"hello": shaInfos{
|
||||
"github.com/Jguer/yay.git": shaInfo{
|
||||
"github.com/Jguer/z.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "main",
|
||||
Branch: "0",
|
||||
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1"}},
|
||||
"hello-non-existant": shaInfos{
|
||||
"github.com/Jguer/y.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "0",
|
||||
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1"}},
|
||||
"hello2": shaInfos{
|
||||
"github.com/Jguer/a.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "1",
|
||||
SHA: "7f4c277ce7149665d1c79b76ca8fbb832a65a03b"}},
|
||||
"hello4": shaInfos{
|
||||
"github.com/Jguer/b.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "2",
|
||||
SHA: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
|
||||
"github.com/Jguer/c.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "3",
|
||||
SHA: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},
|
||||
},
|
||||
},
|
||||
remote: []db.RepoPackage{
|
||||
&mock.Package{PName: "hello", PVersion: "2.0.0"},
|
||||
&mock.Package{PName: "hello2", PVersion: "3.0.0"},
|
||||
&mock.Package{PName: "hello4", PVersion: "4.0.0"}},
|
||||
aurdata: map[string]*rpc.Pkg{
|
||||
"hello": {Version: "2.0.0", Name: "hello"},
|
||||
"hello2": {Version: "2.0.0", Name: "hello2"},
|
||||
"hello4": {Version: "2.0.0", Name: "hello4"},
|
||||
},
|
||||
},
|
||||
want: upgrade.UpSlice{upgrade.Upgrade{
|
||||
Name: "hello",
|
||||
Repository: "devel",
|
||||
LocalVersion: "2.0.0",
|
||||
RemoteVersion: "latest-commit"},
|
||||
upgrade.Upgrade{
|
||||
Name: "hello4",
|
||||
Repository: "devel",
|
||||
LocalVersion: "4.0.0",
|
||||
RemoteVersion: "latest-commit"},
|
||||
}},
|
||||
{name: "No update returned",
|
||||
finalLen: 1,
|
||||
args: args{
|
||||
cached: vcsInfo{
|
||||
"hello": shaInfos{
|
||||
"github.com/Jguer/d.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "4",
|
||||
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1"}}},
|
||||
remote: []db.RepoPackage{&mock.Package{PName: "hello", PVersion: "2.0.0"}},
|
||||
aurdata: map[string]*rpc.Pkg{"hello": {Version: "2.1.0", Name: "hello"}},
|
||||
aurdata: map[string]*rpc.Pkg{"hello": {Version: "2.0.0", Name: "hello"}},
|
||||
},
|
||||
want: upgrade.UpSlice{upgrade.Upgrade{Name: "hello", Repository: "aur", LocalVersion: "2.0.0", RemoteVersion: "2.1.0"}}},
|
||||
want: upgrade.UpSlice{}},
|
||||
{name: "No update returned - ignored",
|
||||
finalLen: 1,
|
||||
args: args{
|
||||
cached: vcsInfo{
|
||||
"hello": shaInfos{
|
||||
"github.com/Jguer/e.git": shaInfo{
|
||||
Protocols: []string{"https"},
|
||||
Branch: "3",
|
||||
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1"}}},
|
||||
remote: []db.RepoPackage{&mock.Package{PName: "hello", PVersion: "2.0.0", PShouldIgnore: true}},
|
||||
aurdata: map[string]*rpc.Pkg{"hello": {Version: "2.0.0", Name: "hello"}},
|
||||
},
|
||||
want: upgrade.UpSlice{}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
config.Runtime.CmdRunner.(*MockRunner).t = t
|
||||
got := upDevel(tt.args.remote, tt.args.aurdata, tt.args.cached)
|
||||
assert.EqualValues(t, tt.want, got)
|
||||
assert.ElementsMatch(t, tt.want, got)
|
||||
assert.Equal(t, tt.finalLen, len(tt.args.cached))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
27
vcs.go
27
vcs.go
|
@ -1,13 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
|
@ -165,35 +163,14 @@ func updateVCSData(vcsFilePath, pkgName string, sources []gosrc.ArchString, mux
|
|||
func getCommit(url, branch string, protocols []string) string {
|
||||
if len(protocols) > 0 {
|
||||
protocol := protocols[len(protocols)-1]
|
||||
var outbuf bytes.Buffer
|
||||
|
||||
cmd := passToGit("", "ls-remote", protocol+"://"+url, branch)
|
||||
cmd.Stdout = &outbuf
|
||||
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
|
||||
|
||||
err := cmd.Start()
|
||||
stdout, _, err := config.Runtime.CmdRunner.Capture(cmd, 5)
|
||||
if err != nil {
|
||||
text.Warnln(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
// for some reason
|
||||
// git://bitbucket.org/volumesoffun/polyvox.git` hangs on my
|
||||
// machine but using http:// instead of git does not hang.
|
||||
// Introduce a time out so this can not hang
|
||||
timer := time.AfterFunc(5*time.Second, func() {
|
||||
err = cmd.Process.Kill()
|
||||
if err != nil {
|
||||
text.Errorln(err)
|
||||
}
|
||||
})
|
||||
|
||||
err = cmd.Wait()
|
||||
timer.Stop()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
stdout := outbuf.String()
|
||||
split := strings.Fields(stdout)
|
||||
|
||||
if len(split) < 2 {
|
||||
|
|
Loading…
Reference in a new issue