2019-03-13 04:14:30 -07:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-11-19 00:02:51 -08:00
|
|
|
"bufio"
|
|
|
|
"bytes"
|
2020-11-19 19:12:20 -08:00
|
|
|
"context"
|
2020-10-16 08:43:02 -07:00
|
|
|
"fmt"
|
2020-10-07 04:32:42 -07:00
|
|
|
"io/ioutil"
|
2019-03-13 04:14:30 -07:00
|
|
|
"log"
|
2020-11-19 19:12:20 -08:00
|
|
|
"net/http"
|
2019-03-13 04:14:30 -07:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
2020-10-01 11:57:02 -07:00
|
|
|
"path/filepath"
|
2019-03-13 04:14:30 -07:00
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/distatus/battery"
|
2020-10-21 19:49:14 -07:00
|
|
|
"github.com/shirou/gopsutil/host"
|
2020-10-23 07:36:40 -07:00
|
|
|
"github.com/shirou/gopsutil/process"
|
2019-03-13 04:14:30 -07:00
|
|
|
)
|
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
const (
|
|
|
|
unknown = "unknown"
|
|
|
|
windowsPlatform = "windows"
|
|
|
|
)
|
|
|
|
|
2019-03-13 04:14:30 -07:00
|
|
|
type environmentInfo interface {
|
|
|
|
getenv(key string) string
|
2020-10-02 12:50:13 -07:00
|
|
|
getcwd() string
|
|
|
|
homeDir() string
|
2020-10-01 11:57:02 -07:00
|
|
|
hasFiles(pattern string) bool
|
2020-12-01 11:43:30 -08:00
|
|
|
hasFilesInDir(dir, pattern string) bool
|
2020-10-07 04:32:42 -07:00
|
|
|
hasFolder(folder string) bool
|
|
|
|
getFileContent(file string) string
|
2019-03-13 04:14:30 -07:00
|
|
|
getPathSeperator() string
|
2020-10-12 03:53:54 -07:00
|
|
|
getCurrentUser() string
|
2019-03-13 04:14:30 -07:00
|
|
|
isRunningAsRoot() bool
|
|
|
|
getHostName() (string, error)
|
|
|
|
getRuntimeGOOS() string
|
2020-10-21 19:49:14 -07:00
|
|
|
getPlatform() string
|
2019-03-13 04:14:30 -07:00
|
|
|
hasCommand(command string) bool
|
2020-10-16 08:43:02 -07:00
|
|
|
runCommand(command string, args ...string) (string, error)
|
2020-11-12 00:43:32 -08:00
|
|
|
runShellCommand(shell, command string) string
|
2019-03-13 04:14:30 -07:00
|
|
|
lastErrorCode() int
|
2020-12-06 13:03:40 -08:00
|
|
|
executionTime() float64
|
2019-03-13 04:14:30 -07:00
|
|
|
getArgs() *args
|
|
|
|
getBatteryInfo() (*battery.Battery, error)
|
2020-09-24 10:11:56 -07:00
|
|
|
getShellName() string
|
2020-11-12 00:43:32 -08:00
|
|
|
getWindowTitle(imageName, windowTitleRegex string) (string, error)
|
2020-11-19 19:12:20 -08:00
|
|
|
doGet(url string) ([]byte, error)
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type environment struct {
|
|
|
|
args *args
|
2020-10-12 00:04:37 -07:00
|
|
|
cwd string
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
2020-10-16 08:43:02 -07:00
|
|
|
type commandError struct {
|
|
|
|
exitCode int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *commandError) Error() string {
|
|
|
|
return fmt.Sprintf("%d", e.exitCode)
|
|
|
|
}
|
|
|
|
|
2019-03-13 04:14:30 -07:00
|
|
|
func (env *environment) getenv(key string) string {
|
|
|
|
return os.Getenv(key)
|
|
|
|
}
|
|
|
|
|
2020-10-02 12:50:13 -07:00
|
|
|
func (env *environment) getcwd() string {
|
2020-10-12 00:04:37 -07:00
|
|
|
if env.cwd != "" {
|
|
|
|
return env.cwd
|
|
|
|
}
|
2020-10-08 10:23:20 -07:00
|
|
|
correctPath := func(pwd string) string {
|
|
|
|
// on Windows, and being case sentisitive and not consistent and all, this gives silly issues
|
|
|
|
return strings.Replace(pwd, "c:", "C:", 1)
|
|
|
|
}
|
2020-10-10 10:16:58 -07:00
|
|
|
if env.args != nil && *env.args.PWD != "" {
|
2020-10-12 00:04:37 -07:00
|
|
|
env.cwd = correctPath(*env.args.PWD)
|
|
|
|
return env.cwd
|
2020-10-08 10:23:20 -07:00
|
|
|
}
|
2020-10-02 12:50:13 -07:00
|
|
|
dir, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
2020-10-12 00:04:37 -07:00
|
|
|
env.cwd = correctPath(dir)
|
|
|
|
return env.cwd
|
2020-10-02 12:50:13 -07:00
|
|
|
}
|
|
|
|
|
2020-10-01 11:57:02 -07:00
|
|
|
func (env *environment) hasFiles(pattern string) bool {
|
2020-10-02 12:50:13 -07:00
|
|
|
cwd := env.getcwd()
|
2020-10-01 11:57:02 -07:00
|
|
|
pattern = cwd + env.getPathSeperator() + pattern
|
|
|
|
matches, err := filepath.Glob(pattern)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return len(matches) > 0
|
|
|
|
}
|
|
|
|
|
2020-12-01 11:43:30 -08:00
|
|
|
func (env *environment) hasFilesInDir(dir, pattern string) bool {
|
|
|
|
pattern = dir + env.getPathSeperator() + pattern
|
|
|
|
matches, err := filepath.Glob(pattern)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return len(matches) > 0
|
|
|
|
}
|
|
|
|
|
2020-10-07 04:32:42 -07:00
|
|
|
func (env *environment) hasFolder(folder string) bool {
|
|
|
|
_, err := os.Stat(folder)
|
|
|
|
return !os.IsNotExist(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) getFileContent(file string) string {
|
|
|
|
content, err := ioutil.ReadFile(file)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return string(content)
|
|
|
|
}
|
|
|
|
|
2019-03-13 04:14:30 -07:00
|
|
|
func (env *environment) getPathSeperator() string {
|
|
|
|
return string(os.PathSeparator)
|
|
|
|
}
|
|
|
|
|
2020-10-12 03:53:54 -07:00
|
|
|
func (env *environment) getCurrentUser() string {
|
|
|
|
user := os.Getenv("USER")
|
|
|
|
if user == "" {
|
|
|
|
user = os.Getenv("USERNAME")
|
|
|
|
}
|
|
|
|
return user
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) getHostName() (string, error) {
|
|
|
|
hostName, err := os.Hostname()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return cleanHostName(hostName), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) getRuntimeGOOS() string {
|
|
|
|
return runtime.GOOS
|
|
|
|
}
|
|
|
|
|
2020-10-21 19:49:14 -07:00
|
|
|
func (env *environment) getPlatform() string {
|
2020-11-12 00:43:32 -08:00
|
|
|
if runtime.GOOS == windowsPlatform {
|
|
|
|
return windowsPlatform
|
2020-10-21 19:49:14 -07:00
|
|
|
}
|
|
|
|
p, _, _, _ := host.PlatformInformation()
|
|
|
|
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2020-10-16 08:43:02 -07:00
|
|
|
func (env *environment) runCommand(command string, args ...string) (string, error) {
|
2020-11-19 00:02:51 -08:00
|
|
|
cmd := exec.Command(command, args...)
|
|
|
|
stdout, err := cmd.StdoutPipe()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
2020-10-16 08:43:02 -07:00
|
|
|
}
|
2020-11-19 00:02:51 -08:00
|
|
|
err = cmd.Start()
|
2019-03-13 04:14:30 -07:00
|
|
|
if err != nil {
|
2020-10-16 08:43:02 -07:00
|
|
|
return "", err
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
2020-11-19 00:02:51 -08:00
|
|
|
defer func() {
|
|
|
|
_ = cmd.Process.Kill()
|
|
|
|
}()
|
|
|
|
output := new(bytes.Buffer)
|
|
|
|
defer output.Reset()
|
|
|
|
buf := bufio.NewReader(stdout)
|
|
|
|
multiline := false
|
|
|
|
for {
|
|
|
|
line, _, _ := buf.ReadLine()
|
|
|
|
if line == nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if multiline {
|
|
|
|
output.WriteString("\n")
|
|
|
|
}
|
|
|
|
output.Write(line)
|
|
|
|
multiline = true
|
|
|
|
}
|
|
|
|
return output.String(), nil
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
|
2020-11-12 00:43:32 -08:00
|
|
|
func (env *environment) runShellCommand(shell, command string) string {
|
2019-03-13 04:14:30 -07:00
|
|
|
out, err := exec.Command(shell, "-c", command).Output()
|
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return strings.TrimSpace(string(out))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) hasCommand(command string) bool {
|
|
|
|
_, err := exec.LookPath(command)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) lastErrorCode() int {
|
|
|
|
return *env.args.ErrorCode
|
|
|
|
}
|
|
|
|
|
2020-12-06 13:03:40 -08:00
|
|
|
func (env *environment) executionTime() float64 {
|
2020-12-12 03:54:25 -08:00
|
|
|
if *env.args.ExecutionTime < 0 {
|
|
|
|
return 0
|
|
|
|
}
|
2020-12-06 13:03:40 -08:00
|
|
|
return *env.args.ExecutionTime
|
|
|
|
}
|
|
|
|
|
2019-03-13 04:14:30 -07:00
|
|
|
func (env *environment) getArgs() *args {
|
|
|
|
return env.args
|
|
|
|
}
|
|
|
|
|
|
|
|
func (env *environment) getBatteryInfo() (*battery.Battery, error) {
|
|
|
|
return battery.Get(0)
|
|
|
|
}
|
|
|
|
|
2020-09-24 10:11:56 -07:00
|
|
|
func (env *environment) getShellName() string {
|
2020-09-15 04:44:53 -07:00
|
|
|
pid := os.Getppid()
|
2020-10-23 07:36:40 -07:00
|
|
|
p, _ := process.NewProcess(int32(pid))
|
|
|
|
name, err := p.Name()
|
2020-09-24 10:11:56 -07:00
|
|
|
if err != nil {
|
2020-11-12 00:43:32 -08:00
|
|
|
return unknown
|
2020-09-24 10:11:56 -07:00
|
|
|
}
|
2020-11-02 09:43:10 -08:00
|
|
|
if name == "cmd.exe" {
|
|
|
|
p, _ = p.Parent()
|
|
|
|
name, err = p.Name()
|
|
|
|
}
|
|
|
|
if err != nil {
|
2020-11-12 00:43:32 -08:00
|
|
|
return unknown
|
2020-11-02 09:43:10 -08:00
|
|
|
}
|
2020-10-23 07:36:40 -07:00
|
|
|
shell := strings.Replace(name, ".exe", "", 1)
|
2020-09-24 10:11:56 -07:00
|
|
|
return strings.Trim(shell, " ")
|
2020-09-15 04:44:53 -07:00
|
|
|
}
|
|
|
|
|
2020-11-19 19:12:20 -08:00
|
|
|
func (env *environment) doGet(url string) ([]byte, error) {
|
|
|
|
request, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
response, err := client.Do(request)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer response.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(response.Body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return body, nil
|
|
|
|
}
|
|
|
|
|
2019-03-13 04:14:30 -07:00
|
|
|
func cleanHostName(hostName string) string {
|
|
|
|
garbage := []string{
|
|
|
|
".lan",
|
|
|
|
".local",
|
2020-10-07 08:14:26 -07:00
|
|
|
".localdomain",
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
for _, g := range garbage {
|
2020-10-07 08:14:26 -07:00
|
|
|
if strings.HasSuffix(hostName, g) {
|
|
|
|
hostName = strings.Replace(hostName, g, "", 1)
|
|
|
|
}
|
2019-03-13 04:14:30 -07:00
|
|
|
}
|
|
|
|
return hostName
|
|
|
|
}
|