fix: lock around shared map write

This commit is contained in:
lnu 2021-01-10 11:52:59 +01:00 committed by Jan De Dobbeleer
parent b876744721
commit b1e2a52a04
3 changed files with 22 additions and 32 deletions

View file

@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"sync"
"time" "time"
"github.com/distatus/battery" "github.com/distatus/battery"
@ -65,11 +66,15 @@ type environmentInfo interface {
} }
type environment struct { type environment struct {
args *args args *args
cwd string cwd string
commands map[string]string
} }
var (
commands map[string]string = make(map[string]string)
lock = sync.Mutex{}
)
func (env *environment) getenv(key string) string { func (env *environment) getenv(key string) string {
return os.Getenv(key) return os.Getenv(key)
} }
@ -160,7 +165,7 @@ func (env *environment) getPlatform() string {
} }
func (env *environment) runCommand(command string, args ...string) (string, error) { func (env *environment) runCommand(command string, args ...string) (string, error) {
if cmd, ok := env.commands[command]; ok { if cmd, ok := commands[command]; ok {
command = cmd command = cmd
} }
out, err := exec.Command(command, args...).Output() out, err := exec.Command(command, args...).Output()
@ -176,12 +181,14 @@ func (env *environment) runShellCommand(shell, command string) string {
} }
func (env *environment) hasCommand(command string) bool { func (env *environment) hasCommand(command string) bool {
if _, ok := env.commands[command]; ok { if _, ok := commands[command]; ok {
return true return true
} }
path, err := exec.LookPath(command) path, err := exec.LookPath(command)
if err == nil { if err == nil {
env.commands[command] = path lock.Lock()
commands[command] = path
lock.Unlock()
return true return true
} }
return false return false

View file

@ -101,8 +101,7 @@ func main() {
} }
flag.Parse() flag.Parse()
env := &environment{ env := &environment{
args: args, args: args,
commands: make(map[string]string),
} }
if *args.Millis { if *args.Millis {
fmt.Print(time.Now().UnixNano() / 1000000) fmt.Print(time.Now().UnixNano() / 1000000)

View file

@ -7,9 +7,7 @@ import (
) )
func TestExecuteCommand(t *testing.T) { func TestExecuteCommand(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "echo hello", Command: "echo hello",
@ -25,9 +23,7 @@ func TestExecuteCommand(t *testing.T) {
} }
func TestExecuteMultipleCommandsOrFirst(t *testing.T) { func TestExecuteMultipleCommandsOrFirst(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "exit 1 || echo hello", Command: "exit 1 || echo hello",
@ -43,9 +39,7 @@ func TestExecuteMultipleCommandsOrFirst(t *testing.T) {
} }
func TestExecuteMultipleCommandsOrSecond(t *testing.T) { func TestExecuteMultipleCommandsOrSecond(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "echo hello || echo world", Command: "echo hello || echo world",
@ -61,9 +55,7 @@ func TestExecuteMultipleCommandsOrSecond(t *testing.T) {
} }
func TestExecuteMultipleCommandsAnd(t *testing.T) { func TestExecuteMultipleCommandsAnd(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "echo hello && echo world", Command: "echo hello && echo world",
@ -79,9 +71,7 @@ func TestExecuteMultipleCommandsAnd(t *testing.T) {
} }
func TestExecuteSingleCommandEmpty(t *testing.T) { func TestExecuteSingleCommandEmpty(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "", Command: "",
@ -96,9 +86,7 @@ func TestExecuteSingleCommandEmpty(t *testing.T) {
} }
func TestExecuteSingleCommandNoCommandProperty(t *testing.T) { func TestExecuteSingleCommandNoCommandProperty(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{} props := &properties{}
c := &command{ c := &command{
props: props, props: props,
@ -110,9 +98,7 @@ func TestExecuteSingleCommandNoCommandProperty(t *testing.T) {
} }
func TestExecuteMultipleCommandsAndDisabled(t *testing.T) { func TestExecuteMultipleCommandsAndDisabled(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "echo && echo", Command: "echo && echo",
@ -127,9 +113,7 @@ func TestExecuteMultipleCommandsAndDisabled(t *testing.T) {
} }
func TestExecuteMultipleCommandsOrDisabled(t *testing.T) { func TestExecuteMultipleCommandsOrDisabled(t *testing.T) {
env := &environment{ env := &environment{}
commands: make(map[string]string),
}
props := &properties{ props := &properties{
values: map[Property]interface{}{ values: map[Property]interface{}{
Command: "echo|| echo", Command: "echo|| echo",