mirror of
https://github.com/foomo/gograpple.git
synced 2026-08-12 12:20:22 +00:00
113 lines
2.3 KiB
Go
113 lines
2.3 KiB
Go
package gograpple
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"text/template"
|
|
"time"
|
|
|
|
"github.com/foomo/squadron/util"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func FindFreePort(host string) (int, error) {
|
|
tcpAddr, err := CheckTCPConnection(host, 0)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return tcpAddr.Port, nil
|
|
}
|
|
|
|
func CheckTCPConnection(host string, port int) (*net.TCPAddr, error) {
|
|
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%v:%v", host, port))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l, err := net.ListenTCP("tcp", addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer l.Close()
|
|
return l.Addr().(*net.TCPAddr), nil
|
|
}
|
|
|
|
func runOpen(l *logrus.Entry, path string) (string, error) {
|
|
var cmd *util.Cmd
|
|
switch runtime.GOOS {
|
|
case "linux":
|
|
cmd = util.NewCommand(l, "xdg-open").Args(path)
|
|
case "windows":
|
|
cmd = util.NewCommand(l, "rundll32").Args("url.dll,FileProtocolHandler", path)
|
|
case "darwin":
|
|
cmd = util.NewCommand(l, "open").Args(path)
|
|
default:
|
|
return "", fmt.Errorf("unsupported platform")
|
|
}
|
|
return cmd.Run()
|
|
}
|
|
|
|
func tryCall(tries int, waitBetweenAttempts time.Duration, f func(i int) error) error {
|
|
var err error
|
|
for i := 1; i < tries+1; i++ {
|
|
err = f(i)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
time.Sleep(waitBetweenAttempts)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func findGoProjectRoot(path string) (string, error) {
|
|
abs, errAbs := filepath.Abs(path)
|
|
if errAbs != nil {
|
|
return "", errAbs
|
|
}
|
|
dir := filepath.Dir(abs)
|
|
statDir, errStatDir := os.Stat(dir)
|
|
if errStatDir != nil {
|
|
return "", errStatDir
|
|
}
|
|
if !statDir.IsDir() {
|
|
return "", fmt.Errorf("%q is not a dir", dir)
|
|
}
|
|
modFile := filepath.Join(dir, "go.mod")
|
|
stat, errStat := os.Stat(modFile)
|
|
if errStat == nil {
|
|
if stat.IsDir() {
|
|
return "", fmt.Errorf("go.mod is a directory")
|
|
}
|
|
return dir, nil
|
|
}
|
|
if dir == "/" {
|
|
return "", fmt.Errorf("reached / without finding go.mod")
|
|
}
|
|
return findGoProjectRoot(dir)
|
|
}
|
|
|
|
func renderTemplate(path string, values interface{}) (string, error) {
|
|
tpl, err := template.ParseFiles(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
buf := new(bytes.Buffer)
|
|
err = tpl.Execute(buf, values)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return buf.String(), nil
|
|
}
|
|
|
|
func stringIsInSlice(a string, list []string) bool {
|
|
for _, b := range list {
|
|
if b == a {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|