mirror of
https://github.com/Jguer/yay.git
synced 2025-10-11 00:03:47 -04: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 {
|
func passToGit(dir string, _args ...string) *exec.Cmd {
|
||||||
gitflags := strings.Fields(config.GitFlags)
|
args := strings.Fields(config.GitFlags)
|
||||||
args := []string{"-C", dir}
|
if dir != "" {
|
||||||
args = append(args, gitflags...)
|
args = append(args, "-C", dir)
|
||||||
|
}
|
||||||
args = append(args, _args...)
|
args = append(args, _args...)
|
||||||
|
|
||||||
cmd := exec.Command(config.GitBin, args...)
|
cmd := exec.Command(config.GitBin, args...)
|
||||||
|
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func isTty() bool {
|
func isTty() bool {
|
||||||
return terminal.IsTerminal(int(os.Stdout.Fd()))
|
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
|
package settings
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Morganamilo/go-pacmanconf"
|
"github.com/Morganamilo/go-pacmanconf"
|
||||||
"github.com/leonelquinteros/gotext"
|
"github.com/leonelquinteros/gotext"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/Jguer/yay/v10/pkg/text"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TargetMode int
|
type TargetMode int
|
||||||
@ -25,6 +32,62 @@ const (
|
|||||||
ModeRepo
|
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 {
|
type Runtime struct {
|
||||||
Mode TargetMode
|
Mode TargetMode
|
||||||
SaveConfig bool
|
SaveConfig bool
|
||||||
@ -32,6 +95,7 @@ type Runtime struct {
|
|||||||
ConfigPath string
|
ConfigPath string
|
||||||
VCSPath string
|
VCSPath string
|
||||||
PacmanConf *pacmanconf.Config
|
PacmanConf *pacmanconf.Config
|
||||||
|
CmdRunner Runner
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeRuntime() (*Runtime, error) {
|
func MakeRuntime() (*Runtime, error) {
|
||||||
@ -42,6 +106,7 @@ func MakeRuntime() (*Runtime, error) {
|
|||||||
Mode: ModeAny,
|
Mode: ModeAny,
|
||||||
SaveConfig: false,
|
SaveConfig: false,
|
||||||
CompletionPath: "",
|
CompletionPath: "",
|
||||||
|
CmdRunner: &OSRunner{},
|
||||||
}
|
}
|
||||||
|
|
||||||
if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
||||||
|
123
upgrade_test.go
123
upgrade_test.go
@ -1,17 +1,22 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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"
|
"github.com/bradleyjkemp/cupaloy"
|
||||||
rpc "github.com/mikkeloscar/aur"
|
rpc "github.com/mikkeloscar/aur"
|
||||||
"github.com/stretchr/testify/assert"
|
"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) {
|
func Test_upAUR(t *testing.T) {
|
||||||
@ -68,7 +73,41 @@ 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) {
|
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 {
|
type args struct {
|
||||||
remote []db.RepoPackage
|
remote []db.RepoPackage
|
||||||
aurdata map[string]*rpc.Pkg
|
aurdata map[string]*rpc.Pkg
|
||||||
@ -78,6 +117,7 @@ func Test_upDevel(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
want upgrade.UpSlice
|
want upgrade.UpSlice
|
||||||
|
finalLen int
|
||||||
}{
|
}{
|
||||||
{name: "No Updates",
|
{name: "No Updates",
|
||||||
args: args{
|
args: args{
|
||||||
@ -92,22 +132,89 @@ func Test_upDevel(t *testing.T) {
|
|||||||
},
|
},
|
||||||
want: upgrade.UpSlice{}},
|
want: upgrade.UpSlice{}},
|
||||||
{name: "Simple Update",
|
{name: "Simple Update",
|
||||||
|
finalLen: 3,
|
||||||
args: args{
|
args: args{
|
||||||
cached: vcsInfo{
|
cached: vcsInfo{
|
||||||
"hello": shaInfos{
|
"hello": shaInfos{
|
||||||
"github.com/Jguer/yay.git": shaInfo{
|
"github.com/Jguer/z.git": shaInfo{
|
||||||
Protocols: []string{"https"},
|
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"}}},
|
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1"}}},
|
||||||
remote: []db.RepoPackage{&mock.Package{PName: "hello", PVersion: "2.0.0"}},
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
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)
|
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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
gosrc "github.com/Morganamilo/go-srcinfo"
|
gosrc "github.com/Morganamilo/go-srcinfo"
|
||||||
"github.com/leonelquinteros/gotext"
|
"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 {
|
func getCommit(url, branch string, protocols []string) string {
|
||||||
if len(protocols) > 0 {
|
if len(protocols) > 0 {
|
||||||
protocol := protocols[len(protocols)-1]
|
protocol := protocols[len(protocols)-1]
|
||||||
var outbuf bytes.Buffer
|
|
||||||
|
|
||||||
cmd := passToGit("", "ls-remote", protocol+"://"+url, branch)
|
cmd := passToGit("", "ls-remote", protocol+"://"+url, branch)
|
||||||
cmd.Stdout = &outbuf
|
stdout, _, err := config.Runtime.CmdRunner.Capture(cmd, 5)
|
||||||
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
|
|
||||||
|
|
||||||
err := cmd.Start()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
text.Warnln(err)
|
||||||
return ""
|
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)
|
split := strings.Fields(stdout)
|
||||||
|
|
||||||
if len(split) < 2 {
|
if len(split) < 2 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user