Added write-inlplace flag

This commit is contained in:
Mike Farah 2020-11-30 16:05:07 +11:00
parent 8de10e550d
commit 9bc66c80b6
6 changed files with 33 additions and 9 deletions

View File

@ -14,3 +14,5 @@ var noDocSeparators = false
var nullInput = false var nullInput = false
var verbose = false var verbose = false
var version = false var version = false
var completedSuccessfully = false

View File

@ -45,15 +45,17 @@ func evaluateAll(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Write inplace flag only applicable when giving an expression and at least one file") return fmt.Errorf("Write inplace flag only applicable when giving an expression and at least one file")
} }
completedSuccessfully := false
if writeInplace { if writeInplace {
// only use colors if its forced
colorsEnabled = forceColor
writeInPlaceHandler := yqlib.NewWriteInPlaceHandler(args[1]) writeInPlaceHandler := yqlib.NewWriteInPlaceHandler(args[1])
out, err = writeInPlaceHandler.CreateTempFile() out, err = writeInPlaceHandler.CreateTempFile()
if err != nil { if err != nil {
return err return err
} }
defer writeInPlaceHandler.FinishWriteInPlace(completedSuccessfully) // need to indirectly call the function so that completedSuccessfully is
// passed when we finish execution as opposed to now
defer func() { writeInPlaceHandler.FinishWriteInPlace(completedSuccessfully) }()
} }
printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators) printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators)

View File

@ -1,6 +1,7 @@
package cmd package cmd
import ( import (
"fmt"
"os" "os"
"github.com/mikefarah/yq/v4/pkg/yqlib" "github.com/mikefarah/yq/v4/pkg/yqlib"
@ -39,6 +40,24 @@ func evaluateSequence(cmd *cobra.Command, args []string) error {
if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) { if forceColor || (!forceNoColor && (fileInfo.Mode()&os.ModeCharDevice) != 0) {
colorsEnabled = true colorsEnabled = true
} }
if writeInplace && len(args) < 2 {
return fmt.Errorf("Write inplace flag only applicable when giving an expression and at least one file")
}
if writeInplace {
// only use colors if its forced
colorsEnabled = forceColor
writeInPlaceHandler := yqlib.NewWriteInPlaceHandler(args[1])
out, err = writeInPlaceHandler.CreateTempFile()
if err != nil {
return err
}
// need to indirectly call the function so that completedSuccessfully is
// passed when we finish execution as opposed to now
defer func() { writeInPlaceHandler.FinishWriteInPlace(completedSuccessfully) }()
}
printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators) printer := yqlib.NewPrinter(out, outputToJSON, unwrapScalar, colorsEnabled, indent, !noDocSeparators)
streamEvaluator := yqlib.NewStreamEvaluator() streamEvaluator := yqlib.NewStreamEvaluator()
@ -61,7 +80,7 @@ func evaluateSequence(cmd *cobra.Command, args []string) error {
default: default:
err = streamEvaluator.EvaluateFiles(args[0], args[1:], printer) err = streamEvaluator.EvaluateFiles(args[0], args[1:], printer)
} }
completedSuccessfully = err == nil
cmd.SilenceUsage = true cmd.SilenceUsage = true
return err return err
} }

View File

@ -1,5 +0,0 @@
package yqlib
import "gopkg.in/op/go-logging.v1"
var log = logging.MustGetLogger("yq-lib")

View File

@ -9,6 +9,8 @@ import (
yaml "gopkg.in/yaml.v3" yaml "gopkg.in/yaml.v3"
) )
var log = logging.MustGetLogger("yq-lib")
type OperationType struct { type OperationType struct {
Type string Type string
NumArgs uint // number of arguments to the op NumArgs uint // number of arguments to the op

View File

@ -41,15 +41,19 @@ func (w *writeInPlaceHandler) CreateTempFile() (*os.File, error) {
} }
err = os.Chmod(file.Name(), info.Mode()) err = os.Chmod(file.Name(), info.Mode())
log.Debug("writing to tempfile: %v", file.Name())
w.tempFile = file w.tempFile = file
return file, err return file, err
} }
func (w *writeInPlaceHandler) FinishWriteInPlace(evaluatedSuccessfully bool) { func (w *writeInPlaceHandler) FinishWriteInPlace(evaluatedSuccessfully bool) {
log.Debug("Going to write-inplace, evaluatedSuccessfully=%v, target=%v", evaluatedSuccessfully, w.inputFilename)
safelyCloseFile(w.tempFile) safelyCloseFile(w.tempFile)
if evaluatedSuccessfully { if evaluatedSuccessfully {
log.Debug("moved temp file to target")
safelyRenameFile(w.tempFile.Name(), w.inputFilename) safelyRenameFile(w.tempFile.Name(), w.inputFilename)
} else { } else {
log.Debug("removed temp file")
os.Remove(w.tempFile.Name()) os.Remove(w.tempFile.Name())
} }
} }