Skip to content

Commit

Permalink
feat(vcs): test upDevel and extract OS runner
Browse files Browse the repository at this point in the history
  • Loading branch information
Jguer committed Aug 18, 2020
1 parent 4a761c2 commit 9ad2862
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 80 deletions.
49 changes: 5 additions & 44 deletions exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
65 changes: 65 additions & 0 deletions pkg/settings/runtime.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -25,13 +32,70 @@ 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
CompletionPath string
ConfigPath string
VCSPath string
PacmanConf *pacmanconf.Config
CmdRunner Runner
}

func MakeRuntime() (*Runtime, error) {
Expand All @@ -42,6 +106,7 @@ func MakeRuntime() (*Runtime, error) {
Mode: ModeAny,
SaveConfig: false,
CompletionPath: "",
CmdRunner: &OSRunner{},
}

if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
Expand Down
129 changes: 118 additions & 11 deletions upgrade_test.go
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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{
Expand All @@ -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: "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: "main",
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 changes: 2 additions & 25 deletions vcs.go
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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()
if err != nil {
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()
stdout, _, err := config.Runtime.CmdRunner.Capture(cmd, 5)
if err != nil {
text.Warnln(err)
return ""
}

stdout := outbuf.String()
split := strings.Fields(stdout)

if len(split) < 2 {
Expand Down

0 comments on commit 9ad2862

Please sign in to comment.