forked from ddollar/forego
-
Notifications
You must be signed in to change notification settings - Fork 0
/
start.go
104 lines (86 loc) · 2.21 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"fmt"
"os"
"os/signal"
"path/filepath"
"strconv"
"sync"
"time"
)
const shutdownGraceTime = 3 * time.Second
var flagPort int
var processes = map[string]*Process{}
var shutdown_mutex = new(sync.Mutex)
var wg sync.WaitGroup
var cmdStart = &Command{
Run: runStart,
Usage: "start [process name] [-f procfile] [-e env] [-c concurrency] [-p port]",
Short: "Start the application",
Long: `
Start the application specified by a Procfile (defaults to ./Procfile)
Examples:
forego start
forego start web
forego start -f Procfile.test -e .env.test
`,
}
func init() {
cmdStart.Flag.StringVar(&flagProcfile, "f", "Procfile", "procfile")
cmdStart.Flag.StringVar(&flagEnv, "e", "", "env")
cmdStart.Flag.IntVar(&flagPort, "p", 5000, "port")
}
func runStart(cmd *Command, args []string) {
root := filepath.Dir(flagProcfile)
if flagEnv == "" {
flagEnv = filepath.Join(root, ".env")
}
pf, err := ReadProcfile(flagProcfile)
handleError(err)
env, err := ReadEnv(flagEnv)
handleError(err)
of := NewOutletFactory()
of.Padding = pf.LongestProcessName()
handler := make(chan os.Signal, 1)
signal.Notify(handler, os.Interrupt)
go func() {
for sig := range handler {
switch sig {
case os.Interrupt:
fmt.Println(" | ctrl-c detected")
go func() { ShutdownProcesses(of) }()
}
}
}()
var singleton string = ""
if len(args) > 0 {
singleton = args[0]
if !pf.HasProcess(singleton) {
of.ErrorOutput(fmt.Sprintf("no such process: %s", singleton))
}
}
for idx, proc := range pf.Entries {
if (singleton == "") || (singleton == proc.Name) {
shutdown_mutex.Lock()
wg.Add(1)
port := flagPort + (idx * 100)
ps := NewProcess(proc.Command, env)
processes[proc.Name] = ps
ps.Env["PORT"] = strconv.Itoa(flagPort + (idx * 1000))
ps.Root = filepath.Dir(flagProcfile)
ps.Stdin = nil
ps.Stdout = of.CreateOutlet(proc.Name, idx, false)
ps.Stderr = of.CreateOutlet(proc.Name, idx, true)
ps.Start()
of.SystemOutput(fmt.Sprintf("starting %s on port %d", proc.Name, port))
go func(proc ProcfileEntry, ps *Process) {
ps.Wait()
wg.Done()
delete(processes, proc.Name)
ShutdownProcesses(of)
}(proc, ps)
shutdown_mutex.Unlock()
}
}
wg.Wait()
}