package yqlib import ( "io/ioutil" "os" ) type WriteInPlaceHandler interface { CreateTempFile() (*os.File, error) FinishWriteInPlace(evaluatedSuccessfully bool) } type writeInPlaceHandler struct { inputFilename string tempFile *os.File } func NewWriteInPlaceHandler(inputFile string) WriteInPlaceHandler { return &writeInPlaceHandler{inputFile, nil} } func (w *writeInPlaceHandler) CreateTempFile() (*os.File, error) { info, err := os.Stat(w.inputFilename) if err != nil { return nil, err } _, err = os.Stat(os.TempDir()) if os.IsNotExist(err) { err = os.Mkdir(os.TempDir(), 0700) if err != nil { return nil, err } } else if err != nil { return nil, err } file, err := ioutil.TempFile("", "temp") if err != nil { return nil, err } err = os.Chmod(file.Name(), info.Mode()) log.Debug("writing to tempfile: %v", file.Name()) w.tempFile = file return file, err } func (w *writeInPlaceHandler) FinishWriteInPlace(evaluatedSuccessfully bool) { log.Debug("Going to write-inplace, evaluatedSuccessfully=%v, target=%v", evaluatedSuccessfully, w.inputFilename) safelyCloseFile(w.tempFile) if evaluatedSuccessfully { log.Debug("moved temp file to target") safelyRenameFile(w.tempFile.Name(), w.inputFilename) } else { log.Debug("removed temp file") os.Remove(w.tempFile.Name()) } }