github.com/BarDweller/libpak@v0.0.0-20230630201634-8dd5cfc15ec9/effect/executor_unix.go (about) 1 //go:build !windows 2 // +build !windows 3 4 /* 5 * Copyright 2018-2020 the original author or authors. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * https://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package effect 21 22 import ( 23 "fmt" 24 "io" 25 "os" 26 "os/exec" 27 "syscall" 28 29 "github.com/creack/pty" 30 ) 31 32 // TTYExecutor is an implementation of Executor that uses exec.Command and runs the command with a TTY. 33 type TTYExecutor struct{} 34 35 func (t TTYExecutor) Execute(execution Execution) error { 36 cmd := exec.Command(execution.Command, execution.Args...) 37 38 if execution.Dir != "" { 39 cmd.Dir = execution.Dir 40 } 41 42 if len(execution.Env) > 0 { 43 cmd.Env = execution.Env 44 } 45 46 cmd.Stdin = execution.Stdin 47 48 f, err := pty.Start(cmd) 49 if err != nil { 50 return fmt.Errorf("unable to start PTY\n%w", err) 51 } 52 defer f.Close() 53 54 if _, err := io.Copy(execution.Stdout, f); err != nil { 55 if !t.isEIO(err) { 56 return fmt.Errorf("unable to write output\n%w", err) 57 } 58 } 59 60 return cmd.Wait() 61 } 62 63 func (TTYExecutor) isEIO(err error) bool { 64 pe, ok := err.(*os.PathError) 65 if !ok { 66 return false 67 } 68 69 return pe.Err == syscall.EIO 70 } 71 72 // NewExecutor creates a new Executor. If the buildpack is currently running in a TTY, returns a TTY-aware Executor. 73 func NewExecutor() Executor { 74 // TODO: Remove once TTY support is in place 75 return TTYExecutor{} 76 // if isatty.IsTerminal(os.Stdout.Fd()) { 77 // return TTYExecutor{} 78 // } else { 79 // return CommandExecutor{} 80 // } 81 }