@@ -11,6 +11,7 @@ import (
1111 "github.com/loft-sh/devspace/pkg/devspace/plugin"
1212 "github.com/loft-sh/devspace/pkg/util/command"
1313 "github.com/loft-sh/devspace/pkg/util/exit"
14+ "github.com/loft-sh/devspace/pkg/util/interrupt"
1415 "github.com/loft-sh/devspace/pkg/util/log"
1516 "io"
1617 "mvdan.cc/sh/v3/interp"
@@ -158,11 +159,57 @@ func (cmd *RunCmd) RunRun(f factory.Factory, args []string) error {
158159 }
159160
160161 ctx = ctx .AsDependency (dep )
161- return ExecuteConfigCommand (ctx .Context , ctx .Config , args [0 ], args [1 :], ctx .WorkingDir , cmd .Stdout , cmd .Stderr , os .Stdin )
162+ commandConfig , err := findCommand (ctx .Config , args [0 ])
163+ if err != nil {
164+ return err
165+ }
166+
167+ return executeCommandWithAfter (ctx .Context , commandConfig , args [1 :], ctx .Config .Variables (), ctx .WorkingDir , cmd .Stdout , cmd .Stderr , os .Stdin , ctx .Log )
162168 }
163169
164- // Execute command
165- return ExecuteConfigCommand (ctx .Context , ctx .Config , args [0 ], args [1 :], ctx .WorkingDir , cmd .Stdout , cmd .Stderr , os .Stdin )
170+ commandConfig , err := findCommand (ctx .Config , args [0 ])
171+ if err != nil {
172+ return err
173+ }
174+
175+ return executeCommandWithAfter (ctx .Context , commandConfig , args [1 :], ctx .Config .Variables (), ctx .WorkingDir , cmd .Stdout , cmd .Stderr , os .Stdin , ctx .Log )
176+ }
177+
178+ func findCommand (config config.Config , name string ) (* latest.CommandConfig , error ) {
179+ // Find command
180+ if config .Config ().Commands == nil || config .Config ().Commands [name ] == nil {
181+ return nil , errors .Errorf ("couldn't find command '%s' in devspace config" , name )
182+ }
183+
184+ return config .Config ().Commands [name ], nil
185+ }
186+
187+ func executeCommandWithAfter (ctx context.Context , command * latest.CommandConfig , args []string , variables map [string ]interface {}, dir string , stdout io.Writer , stderr io.Writer , stdin io.Reader , log log.Logger ) (err error ) {
188+ err = interrupt .Global .Run (func () error {
189+ return ExecuteCommand (ctx , command , variables , args , dir , stdout , stderr , stdin )
190+ }, func () {
191+ if command .After != "" {
192+ vars := variables
193+ vars ["COMMAND_INTERRUPT" ] = "true"
194+ err = executeShellCommand (ctx , command .After , vars , args , dir , stdout , stderr , stdin )
195+ if err != nil {
196+ log .Errorf ("error executing after command: %v" , err )
197+ }
198+ }
199+ })
200+ if command .After != "" {
201+ vars := variables
202+ if err != nil {
203+ vars ["COMMAND_ERROR" ] = err .Error ()
204+ log .Error (err )
205+ }
206+ err = executeShellCommand (ctx , command .After , vars , args , dir , stdout , stderr , stdin )
207+ if err != nil {
208+ return errors .Wrap (err , "error executing after command" )
209+ }
210+ return nil
211+ }
212+ return err
166213}
167214
168215func ParseArgs (cobraCmd * cobra.Command , globalFlags * flags.GlobalFlags , log log.Logger ) ([]string , error ) {
@@ -221,14 +268,25 @@ func LoadCommandsConfig(configLoader loader.ConfigLoader, configOptions *loader.
221268 WithConfig (commandsInterface ), nil
222269}
223270
224- // ExecuteConfigCommand executes a command from the config
225- func ExecuteConfigCommand (ctx context.Context , config config.Config , name string , args []string , dir string , stdout io.Writer , stderr io.Writer , stdin io.Reader ) error {
226- if config .Config ().Commands == nil || config .Config ().Commands [name ] == nil {
227- return errors .Errorf ("couldn't find command '%s' in devspace config" , name )
271+ func executeShellCommand (ctx context.Context , shellCommand string , variables map [string ]interface {}, args []string , dir string , stdout io.Writer , stderr io.Writer , stdin io.Reader ) error {
272+ extraEnv := map [string ]string {}
273+ for k , v := range variables {
274+ extraEnv [k ] = fmt .Sprintf ("%v" , v )
275+ }
276+
277+ // execute the command in a shell
278+ err := engine .ExecuteSimpleShellCommand (ctx , dir , stdout , stderr , stdin , extraEnv , shellCommand , args ... )
279+ if err != nil {
280+ if status , ok := interp .IsExitStatus (err ); ok {
281+ return & exit.ReturnCodeError {
282+ ExitCode : int (status ),
283+ }
284+ }
285+
286+ return errors .Wrap (err , "execute command" )
228287 }
229288
230- cmd := config .Config ().Commands [name ]
231- return ExecuteCommand (ctx , cmd , config .Variables (), args , dir , stdout , stderr , stdin )
289+ return nil
232290}
233291
234292// ExecuteCommand executes a command from the config
0 commit comments