@@ -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,56 @@ 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 )
168+ }
169+
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 ) error {
188+ originalErr := 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 originalErr != nil {
203+ vars ["COMMAND_ERROR" ] = originalErr .Error ()
204+ }
205+ err := executeShellCommand (ctx , command .After , vars , args , dir , stdout , stderr , stdin )
206+ if err != nil {
207+ return errors .Wrap (err , "error executing after command" )
208+ }
162209 }
163210
164- // Execute command
165- return ExecuteConfigCommand (ctx .Context , ctx .Config , args [0 ], args [1 :], ctx .WorkingDir , cmd .Stdout , cmd .Stderr , os .Stdin )
211+ return originalErr
166212}
167213
168214func ParseArgs (cobraCmd * cobra.Command , globalFlags * flags.GlobalFlags , log log.Logger ) ([]string , error ) {
@@ -221,14 +267,25 @@ func LoadCommandsConfig(configLoader loader.ConfigLoader, configOptions *loader.
221267 WithConfig (commandsInterface ), nil
222268}
223269
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 )
270+ 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 {
271+ extraEnv := map [string ]string {}
272+ for k , v := range variables {
273+ extraEnv [k ] = fmt .Sprintf ("%v" , v )
274+ }
275+
276+ // execute the command in a shell
277+ err := engine .ExecuteSimpleShellCommand (ctx , dir , stdout , stderr , stdin , extraEnv , shellCommand , args ... )
278+ if err != nil {
279+ if status , ok := interp .IsExitStatus (err ); ok {
280+ return & exit.ReturnCodeError {
281+ ExitCode : int (status ),
282+ }
283+ }
284+
285+ return errors .Wrap (err , "execute command" )
228286 }
229287
230- cmd := config .Config ().Commands [name ]
231- return ExecuteCommand (ctx , cmd , config .Variables (), args , dir , stdout , stderr , stdin )
288+ return nil
232289}
233290
234291// ExecuteCommand executes a command from the config
0 commit comments