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{
3738Build, 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.
132163func 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() {
163196var configPath string
164197var redirectLogs bool
165198var logFile string
199+ var edwardHome string
166200
167201func 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
0 commit comments