Skip to content
This repository was archived by the owner on May 8, 2023. It is now read-only.

Commit bd8a962

Browse files
Merge branch 'develop'
2 parents 0cadc51 + 9cec946 commit bd8a962

60 files changed

Lines changed: 1632 additions & 1435 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: go
22

33
before_script:
4-
- wget https://github.com/spf13/hugo/releases/download/v0.29/hugo_0.29_Linux-64bit.tar.gz -O /tmp/hugo.tar.gz
4+
- wget https://github.com/spf13/hugo/releases/download/v0.32.3/hugo_0.32.3_Linux-64bit.tar.gz -O /tmp/hugo.tar.gz
55
- mkdir /tmp/hugo
66
- tar -xvf /tmp/hugo.tar.gz -C /tmp/hugo
77
- export PATH=$PATH:/tmp/hugo/
@@ -10,7 +10,6 @@ before_install:
1010
- go get github.com/mitchellh/gox
1111

1212
go:
13-
- 1.7
1413
- 1.8
1514
- 1.9
1615
deploy:

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ build:
99
./build.sh
1010

1111
test:
12-
go test -race -cover $(PKGS)
12+
go test -timeout 3m -race -cover $(PKGS)
1313

1414
checkdocs:
1515
./check_docs.sh

build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//+build !go1.7
1+
//+build !go1.8
22

33
package main
44

5-
// Upgrade to Go version 1.7 to compile edward.
6-
func init() { Go_version_1_7_required_for_compilation() }
5+
// Upgrade to Go version 1.8 to compile edward.
6+
func init() { Go_version_1_8_required_for_compilation() }

builder/build.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package builder
2+
3+
import (
4+
"github.com/pkg/errors"
5+
"github.com/yext/edward/commandline"
6+
"github.com/yext/edward/home"
7+
"github.com/yext/edward/instance"
8+
"github.com/yext/edward/services"
9+
"github.com/yext/edward/tracker"
10+
)
11+
12+
type builder struct {
13+
Cfg services.OperationConfig
14+
Overrides services.ContextOverride
15+
}
16+
17+
func New(cfg services.OperationConfig, overrides services.ContextOverride) *builder {
18+
return &builder{
19+
Cfg: cfg,
20+
Overrides: overrides,
21+
}
22+
}
23+
24+
func (b *builder) Build(dirConfig *home.EdwardConfiguration, task tracker.Task, service ...*services.ServiceConfig) error {
25+
for _, service := range service {
26+
if b.Cfg.IsExcluded(service) {
27+
return nil
28+
}
29+
err := b.BuildWithTracker(dirConfig, task.Child(service.GetName()), service, false)
30+
if err != nil {
31+
return errors.WithStack(err)
32+
}
33+
}
34+
return nil
35+
}
36+
37+
// BuildWithTracker builds a service.
38+
// If force is false, the build will be skipped if the service is already running.
39+
func (b *builder) BuildWithTracker(dirConfig *home.EdwardConfiguration, task tracker.Task, service *services.ServiceConfig, force bool) error {
40+
if service.Commands.Build == "" {
41+
return nil
42+
}
43+
if task == nil {
44+
return errors.New("task is nil")
45+
}
46+
job := task.Child("Build")
47+
job.SetState(tracker.TaskStateInProgress)
48+
49+
c, err := instance.Load(dirConfig, service, b.Overrides)
50+
if err != nil {
51+
return errors.WithStack(err)
52+
}
53+
if !force && c.Pid != 0 {
54+
job.SetState(tracker.TaskStateWarning, "Already running")
55+
return nil
56+
}
57+
58+
err = instance.DeleteAllStatusesForService(service, dirConfig.StateDir)
59+
if err != nil {
60+
return errors.WithStack(err)
61+
}
62+
63+
cmd, err := commandline.ConstructCommand(b.Cfg.WorkingDir, service.Path, service.Commands.Build, c.Getenv)
64+
if err != nil {
65+
job.SetState(tracker.TaskStateFailed, err.Error())
66+
return errors.WithStack(err)
67+
}
68+
69+
out, err := cmd.CombinedOutput()
70+
if err != nil {
71+
job.SetState(tracker.TaskStateFailed, err.Error(), string(out))
72+
return errors.WithMessage(err, "running build command")
73+
}
74+
75+
job.SetState(tracker.TaskStateSuccess)
76+
return nil
77+
}

cmd/autocomplete.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import (
99
"github.com/yext/edward/config"
1010
)
1111

12-
func autocompleteServicesAndGroups(logger *log.Logger) {
12+
func autocompleteServicesAndGroups(homeDir string, logger *log.Logger) {
1313
printCommandChildren(RootCmd)
1414

15-
configPath, err := config.GetConfigPathFromWorkingDirectory()
15+
configPath, err := config.GetConfigPathFromWorkingDirectory(homeDir)
1616
if err != nil {
1717
logger.Println("Autocomplete> Error getting config path:", err)
1818
return

cmd/restart.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ var restartCmd = &cobra.Command{
1010
Use: "restart",
1111
Short: "Rebuild and relaunch a service or a group",
1212
RunE: func(cmd *cobra.Command, args []string) error {
13-
return errors.WithStack(
14-
edwardClient.Restart(
15-
args,
16-
*restartFlags.force,
17-
*restartFlags.skipBuild,
18-
*restartFlags.tail,
19-
*restartFlags.noWatch,
20-
*restartFlags.exclude,
21-
),
13+
err := edwardClient.Restart(
14+
args,
15+
*restartFlags.force,
16+
*restartFlags.skipBuild,
17+
*restartFlags.noWatch,
18+
*restartFlags.exclude,
2219
)
20+
if err != nil {
21+
return errors.WithStack(err)
22+
}
23+
if *restartFlags.tail {
24+
return errors.WithStack(edwardClient.Log(args, getSignalChannel()))
25+
}
26+
return nil
2327
},
2428
}
2529

cmd/root.go

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"log"
66
"os"
7+
"path"
78
"path/filepath"
89

910
lumberjack "gopkg.in/natefinch/lumberjack.v2"
@@ -37,37 +38,66 @@ var RootCmd = &cobra.Command{
3738
Build, start and manage service instances with a single command.`,
3839
SilenceUsage: true,
3940
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
41+
42+
var dirConfig *home.EdwardConfiguration
43+
var err error
44+
dirConfig = &home.EdwardConfiguration{}
45+
if edwardHome != "" {
46+
err = dirConfig.InitializeWithDir(edwardHome)
47+
} else {
48+
err = dirConfig.Initialize()
49+
}
50+
if err != nil {
51+
return errors.WithStack(err)
52+
}
53+
4054
if redirectLogs {
4155
logger = log.New(os.Stdout, fmt.Sprintf("%v >", os.Args), log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)
4256
}
43-
if logFile != "" {
44-
prefix := "edward"
45-
if len(args) > 0 {
46-
prefix = fmt.Sprintf("%s %s", cmd.Use, args[0])
47-
}
48-
logger = log.New(&lumberjack.Logger{
49-
Filename: logFile,
50-
MaxSize: 50, // megabytes
51-
MaxBackups: 30,
52-
MaxAge: 1, //days
53-
}, fmt.Sprintf("%s > ", prefix), log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)
57+
58+
prefix := "edward"
59+
if len(args) > 0 {
60+
prefix = fmt.Sprintf("%s %s", cmd.Use, args[0])
5461
}
62+
logger = log.New(&lumberjack.Logger{
63+
Filename: path.Join(dirConfig.EdwardLogDir, "edward.log"),
64+
MaxSize: 50, // megabytes
65+
MaxBackups: 30,
66+
MaxAge: 1, //days
67+
}, fmt.Sprintf("%s > ", prefix), log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)
68+
5569
// Begin logging
5670
logger.Printf("=== Edward v%v ===\n", common.EdwardVersion)
5771
logger.Printf("Args: %v\n", os.Args)
72+
// Recover from any panic and log appropriately
73+
defer func() {
74+
if r := recover(); r != nil {
75+
fmt.Println("Recovered from panic:", r)
76+
if logger != nil {
77+
logger.Printf("Recovered from panic: %v", r)
78+
}
79+
}
80+
if logger != nil {
81+
logger.Printf("=== Exiting ===\n")
82+
}
83+
}()
5884

5985
// Set the default config path
6086
if configPath == "" {
6187
var err error
62-
configPath, err = config.GetConfigPathFromWorkingDirectory()
88+
tmpDirCfg := &home.EdwardConfiguration{}
89+
err = tmpDirCfg.Initialize()
90+
if err != nil {
91+
return errors.WithStack(err)
92+
}
93+
configPath, err = config.GetConfigPathFromWorkingDirectory(tmpDirCfg.Dir)
6394
if err != nil {
6495
return errors.WithStack(err)
6596
}
6697
}
6798

6899
command := cmd.Use
69100

70-
var err error
71101
if command != "generate" {
72102
edwardClient, err = edward.NewClientWithConfig(configPath, common.EdwardVersion, logger)
73103
if err != nil {
@@ -84,6 +114,8 @@ Build, start and manage service instances with a single command.`,
84114
}
85115
}
86116

117+
edwardClient.DirConfig = dirConfig
118+
87119
// Set service checks to restart the client on sudo as needed
88120
edwardClient.ServiceChecks = func(sgs []services.ServiceOrGroup) error {
89121
return errors.WithStack(sudoIfNeeded(sgs))
@@ -102,21 +134,20 @@ Build, start and manage service instances with a single command.`,
102134
if command != "stop" {
103135
// Check for legacy pidfiles and error out if any are found
104136
for _, service := range edwardClient.ServiceMap() {
105-
if _, err := os.Stat(service.GetPidPathLegacy()); !os.IsNotExist(err) {
137+
if _, err := os.Stat(service.GetPidPathLegacy(edwardClient.DirConfig.PidDir)); !os.IsNotExist(err) {
106138
return errors.New("one or more services were started with an older version of Edward. Please run `edward stop` to stop these instances")
107139
}
108140
}
109141
}
110142

111143
if command != "run" {
112144
checkUpdateChan = make(chan interface{})
113-
go checkUpdateAvailable(checkUpdateChan)
145+
go checkUpdateAvailable(edwardClient.DirConfig.Dir, checkUpdateChan)
114146
}
115147

116148
return nil
117149
},
118150
PersistentPostRun: func(cmd *cobra.Command, args []string) {
119-
defer logger.Printf("=== Exiting ===\n")
120151
if checkUpdateChan != nil { //&& !didAutoComplete { // TODO: skip when autocompleting
121152
updateAvailable, ok := (<-checkUpdateChan).(bool)
122153
if ok && updateAvailable {
@@ -131,8 +162,10 @@ Build, start and manage service instances with a single command.`,
131162
// This is called by main.main(). It only needs to happen once to the rootCmd.
132163
func Execute() {
133164

134-
if err := home.EdwardConfig.Initialize(); err != nil {
135-
fmt.Printf("%+v", err)
165+
defaultHome := &home.EdwardConfiguration{}
166+
err := defaultHome.Initialize()
167+
if err != nil {
168+
panic(err)
136169
}
137170

138171
logPrefix := "edward"
@@ -141,15 +174,15 @@ func Execute() {
141174
}
142175

143176
logger = log.New(&lumberjack.Logger{
144-
Filename: filepath.Join(home.EdwardConfig.EdwardLogDir, "edward.log"),
177+
Filename: filepath.Join(defaultHome.EdwardLogDir, "edward.log"),
145178
MaxSize: 50, // megabytes
146179
MaxBackups: 30,
147180
MaxAge: 1, //days
148181
}, logPrefix, log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)
149182

150183
for _, arg := range os.Args {
151184
if arg == "--generate-bash-completion" {
152-
autocompleteServicesAndGroups(logger)
185+
autocompleteServicesAndGroups(defaultHome.Dir, logger)
153186
return
154187
}
155188
}
@@ -163,13 +196,15 @@ func Execute() {
163196
var configPath string
164197
var redirectLogs bool
165198
var logFile string
199+
var edwardHome string
166200

167201
func init() {
168202
cobra.OnInitialize(initConfig)
169203

170204
RootCmd.PersistentFlags().StringVar(&logFile, "logfile", "", "Write logs to `PATH`")
171205
RootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "Use service configuration file at `PATH`")
172206
RootCmd.PersistentFlags().BoolVar(&redirectLogs, "redirect_logs", false, "Redirect edward logs to the console")
207+
RootCmd.PersistentFlags().StringVar(&edwardHome, "edward_home", "", "")
173208
err := RootCmd.PersistentFlags().MarkHidden("redirect_logs")
174209
if err != nil {
175210
panic(err)
@@ -178,6 +213,10 @@ func init() {
178213
if err != nil {
179214
panic(err)
180215
}
216+
err = RootCmd.PersistentFlags().MarkHidden("edward_home")
217+
if err != nil {
218+
panic(err)
219+
}
181220
}
182221

183222
// initConfig reads in config file and ENV variables if set.
@@ -206,9 +245,9 @@ func initConfig() {
206245
}
207246
}
208247

209-
func checkUpdateAvailable(checkUpdateChan chan interface{}) {
248+
func checkUpdateAvailable(homeDir string, checkUpdateChan chan interface{}) {
210249
defer close(checkUpdateChan)
211-
updateAvailable, latestVersion, err := updates.UpdateAvailable("yext", "edward", common.EdwardVersion, filepath.Join(home.EdwardConfig.Dir, ".cache/version"), logger)
250+
updateAvailable, latestVersion, err := updates.UpdateAvailable("yext", "edward", common.EdwardVersion, filepath.Join(homeDir, ".cache/version"), logger)
212251
if err != nil {
213252
logger.Println("Error checking for updates:", err)
214253
return

cmd/run.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ var runCmd = &cobra.Command{
1818
return fmt.Errorf("service not found: %s", args[0])
1919
}
2020
r := &runner.Runner{
21-
Service: service,
21+
Service: service,
22+
DirConfig: edwardClient.DirConfig,
2223
}
2324
r.NoWatch = *runFlags.noWatch
2425
r.WorkingDir = *runFlags.directory
25-
r.Logger = logger
26+
r.Logger = edwardClient.Logger
2627
err := r.Run(args)
2728
return errors.WithStack(err)
2829
},

cmd/start.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ var startCmd = &cobra.Command{
1010
Use: "start",
1111
Short: "Build and launch a service or a group",
1212
RunE: func(cmd *cobra.Command, args []string) error {
13-
return errors.WithStack(
14-
edwardClient.Start(args, *startFlags.skipBuild, *startFlags.tail, *startFlags.noWatch, *startFlags.exclude),
15-
)
13+
err := edwardClient.Start(args, *startFlags.skipBuild, *startFlags.noWatch, *startFlags.exclude)
14+
if err != nil {
15+
return errors.WithStack(err)
16+
}
17+
if *startFlags.tail {
18+
return errors.WithStack(edwardClient.Log(args, getSignalChannel()))
19+
}
20+
return nil
1621
},
1722
}
1823

0 commit comments

Comments
 (0)