Skip to content

Commit d75f704

Browse files
authored
Merge pull request #2 from tkw1536/with-accumulated-fixes
Fixup forego to work with nginx-proxy's alpine variant
2 parents e4b8132 + 6853b33 commit d75f704

File tree

8 files changed

+67
-38
lines changed

8 files changed

+67
-38
lines changed

command.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"strings"
77
)
88

9-
var flagEnv string
109
var flagProcfile string
1110

1211
type Command struct {
@@ -37,7 +36,7 @@ func (c *Command) Name() string {
3736
}
3837

3938
func (c *Command) Runnable() bool {
40-
return c.Run != nil && c.Disabled != true
39+
return c.Run != nil && !c.Disabled
4140
}
4241

4342
func (c *Command) List() bool {

env.go

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,35 @@ package main
33
import (
44
"fmt"
55
"os"
6-
"regexp"
6+
"sync"
77

88
"github.com/subosito/gotenv"
99
)
1010

11-
var envEntryRegexp = regexp.MustCompile("^([A-Za-z_0-9]+)=(.*)$")
11+
type Env struct {
12+
m sync.Map
13+
}
1214

13-
type Env map[string]string
15+
func (e *Env) Get(key string) string {
16+
value, ok := e.m.Load(key)
17+
if !ok {
18+
return ""
19+
}
20+
return value.(string)
21+
}
22+
23+
func (e *Env) Set(key, value string) {
24+
e.m.Store(key, value)
25+
}
26+
27+
func (e *Env) Delete(key string) {
28+
e.m.Delete(key)
29+
}
30+
31+
// NewEnv makes a new environment
32+
func NewEnv() *Env {
33+
return &Env{sync.Map{}}
34+
}
1435

1536
type envFiles []string
1637

@@ -23,13 +44,14 @@ func (e *envFiles) Set(value string) error {
2344
return nil
2445
}
2546

26-
func loadEnvs(files []string) (Env, error) {
47+
func loadEnvs(files []string) (*Env, error) {
2748
if len(files) == 0 {
2849
files = []string{".env"}
2950
}
3051

31-
env := make(Env)
52+
env := NewEnv()
3253

54+
// don't need to lock either environment
3355
for _, file := range files {
3456
tmpEnv, err := ReadEnv(file)
3557

@@ -38,35 +60,40 @@ func loadEnvs(files []string) (Env, error) {
3860
}
3961

4062
// Merge the file I just read into the env.
41-
for k, v := range tmpEnv {
42-
env[k] = v
43-
}
63+
tmpEnv.m.Range(func(key, value interface{}) bool {
64+
env.m.Store(key, value)
65+
return true
66+
})
4467
}
4568
return env, nil
4669
}
4770

48-
func ReadEnv(filename string) (Env, error) {
71+
func ReadEnv(filename string) (*Env, error) {
72+
env := NewEnv()
73+
4974
if _, err := os.Stat(filename); os.IsNotExist(err) {
50-
return make(Env), nil
75+
return env, nil
5176
}
77+
5278
fd, err := os.Open(filename)
5379
if err != nil {
5480
return nil, err
5581
}
5682
defer fd.Close()
57-
env := make(Env)
83+
5884
for key, val := range gotenv.Parse(fd) {
59-
env[key] = val
85+
env.Set(key, val)
6086
}
6187
return env, nil
6288
}
6389

6490
func (e *Env) asArray() (env []string) {
65-
for _, pair := range os.Environ() {
66-
env = append(env, pair)
67-
}
68-
for name, val := range *e {
91+
env = append(env, os.Environ()...)
92+
93+
e.m.Range(func(name, val interface{}) bool {
6994
env = append(env, fmt.Sprintf("%s=%s", name, val))
70-
}
95+
return true
96+
})
97+
7198
return
7299
}

env_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ func TestMultipleEnvironmentFiles(t *testing.T) {
1010
t.Fatalf("Could not read environments: %s", err)
1111
}
1212

13-
if env["env1"] == "" {
13+
if env.Get("env1") == "" {
1414
t.Fatal("$env1 should be present and is not")
1515
}
1616

17-
if env["env2"] == "" {
17+
if env.Get("env2") == "" {
1818
t.Fatal("$env2 should be present and is not")
1919
}
2020
}

process.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import (
88

99
type Process struct {
1010
Command string
11-
Env Env
11+
Env *Env
1212
Interactive bool
1313

1414
*exec.Cmd
1515
}
1616

17-
func NewProcess(workdir, command string, env Env, interactive bool) (p *Process) {
17+
func NewProcess(workdir, command string, env *Env, interactive bool) (p *Process) {
1818
argv := ShellInvocationCommand(interactive, workdir, command)
1919
return &Process{
2020
command, env, interactive, exec.Command(argv[0], argv[1:]...),

procfile.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"regexp"
1010
)
1111

12-
var procfileEntryRegexp = regexp.MustCompile("^([A-Za-z0-9_-]+):\\s*(.+)$")
12+
var procfileEntryRegexp = regexp.MustCompile(`^([A-Za-z0-9_-]+):\s*(.+)$`)
1313

1414
type ProcfileEntry struct {
1515
Name string
@@ -68,7 +68,7 @@ func parseProcfile(r io.Reader) (*Procfile, error) {
6868
}
6969
}
7070
if err := scanner.Err(); err != nil {
71-
return nil, fmt.Errorf("Reading Procfile: %s", err)
71+
return nil, fmt.Errorf("reading Procfile: %s", err)
7272
}
7373
return pf, nil
7474
}

start.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ func parseConcurrency(value string) (map[string]int, error) {
121121
parts := strings.Split(value, ",")
122122
for _, part := range parts {
123123
if !strings.Contains(part, "=") {
124-
return concurrency, errors.New("Concurrency should be in the format: foo=1,bar=2")
124+
return concurrency, errors.New("concurrency should be in the format: foo=1,bar=2")
125125
}
126126

127127
nameValue := strings.Split(part, "=")
128128
n, v := strings.TrimSpace(nameValue[0]), strings.TrimSpace(nameValue[1])
129129
if n == "" || v == "" {
130-
return concurrency, errors.New("Concurrency should be in the format: foo=1,bar=2")
130+
return concurrency, errors.New("concurrency should be in the format: foo=1,bar=2")
131131
}
132132

133133
numProcs, err := strconv.ParseInt(v, 10, 16)
@@ -169,18 +169,19 @@ func (f *Forego) monitorInterrupt() {
169169
}
170170
}
171171

172-
func basePort(env Env) (int, error) {
172+
func basePort(env *Env) (int, error) {
173+
173174
if flagPort != defaultPort {
174175
return flagPort, nil
175-
} else if env["PORT"] != "" {
176-
return strconv.Atoi(env["PORT"])
176+
} else if port := env.Get("PORT"); port != "" {
177+
return strconv.Atoi(port)
177178
} else if os.Getenv("PORT") != "" {
178179
return strconv.Atoi(os.Getenv("PORT"))
179180
}
180181
return defaultPort, nil
181182
}
182183

183-
func (f *Forego) startProcess(idx, procNum int, proc ProcfileEntry, env Env, of *OutletFactory) {
184+
func (f *Forego) startProcess(idx, procNum int, proc ProcfileEntry, env *Env, of *OutletFactory) {
184185
port, err := basePort(env)
185186
if err != nil {
186187
panic(err)
@@ -192,7 +193,8 @@ func (f *Forego) startProcess(idx, procNum int, proc ProcfileEntry, env Env, of
192193
workDir := filepath.Dir(flagProcfile)
193194
ps := NewProcess(workDir, proc.Command, env, interactive)
194195
procName := fmt.Sprint(proc.Name, ".", procNum+1)
195-
ps.Env["PORT"] = strconv.Itoa(port)
196+
197+
ps.Env.Set("PORT", strconv.Itoa(port))
196198

197199
ps.Stdin = nil
198200

start_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func TestParseConcurrencyFlagNoValue(t *testing.T) {
111111
}
112112

113113
func TestPortFromEnv(t *testing.T) {
114-
env := make(Env)
114+
env := NewEnv()
115115
port, err := basePort(env)
116116
if err != nil {
117117
t.Fatalf("Can not get base port: %s", err)
@@ -129,7 +129,7 @@ func TestPortFromEnv(t *testing.T) {
129129
t.Fatal("Base port should be 4000")
130130
}
131131

132-
env["PORT"] = "6000"
132+
env.Set("PORT", "6000")
133133
port, err = basePort(env)
134134
if err != nil {
135135
t.Fatalf("Can not get base port: %s", err)
@@ -138,8 +138,8 @@ func TestPortFromEnv(t *testing.T) {
138138
t.Fatal("Base port should be 6000")
139139
}
140140

141-
env["PORT"] = "forego"
142-
port, err = basePort(env)
141+
env.Set("PORT", "forego")
142+
_, err = basePort(env)
143143
if err == nil {
144144
t.Fatalf("Port 'forego' should fail: %s", err)
145145
}

unix.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"syscall"
88
)
99

10+
var osShell string = "bash"
11+
1012
const osHaveSigTerm = true
1113

1214
func ShellInvocationCommand(interactive bool, root, command string) []string {
@@ -15,15 +17,14 @@ func ShellInvocationCommand(interactive bool, root, command string) []string {
1517
shellArgument = "-ic"
1618
}
1719
shellCommand := fmt.Sprintf("cd \"%s\"; source .profile 2>/dev/null; exec %s", root, command)
18-
return []string{"sh", shellArgument, shellCommand}
20+
return []string{osShell, shellArgument, shellCommand}
1921
}
2022

2123
func (p *Process) PlatformSpecificInit() {
2224
if !p.Interactive {
2325
p.SysProcAttr = &syscall.SysProcAttr{}
2426
p.SysProcAttr.Setsid = true
2527
}
26-
return
2728
}
2829

2930
func (p *Process) SendSigTerm() {

0 commit comments

Comments
 (0)