mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-02 02:11:39 +00:00
fix: preserve original filename when using --front-matter (#2613)
When using --front-matter, yq creates a temporary file for the extracted YAML content but replaces the original filename in args with the temp file path. This caused the 'filename' operator to return the temp file path instead of the original filename. Added a filename alias mechanism: when front matter processing replaces the file path, it registers the original filename as an alias. The readDocuments and stream evaluator functions resolve aliases before setting candidateNode.filename. Fixes #2538 Co-authored-by: cobyfrombrooklyn-bot <cobyfrombrooklyn@gmail.com>
This commit is contained in:
parent
c5cbf9760b
commit
b151522485
@ -101,12 +101,15 @@ func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) {
|
||||
}
|
||||
|
||||
if frontMatter != "" {
|
||||
originalFilename := args[0]
|
||||
frontMatterHandler := yqlib.NewFrontMatterHandler(args[0])
|
||||
err = frontMatterHandler.Split()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args[0] = frontMatterHandler.GetYamlFrontMatterFilename()
|
||||
yqlib.SetFilenameAlias(args[0], originalFilename)
|
||||
defer yqlib.ClearFilenameAliases()
|
||||
|
||||
if frontMatter == "process" {
|
||||
reader := frontMatterHandler.GetContentReader()
|
||||
|
||||
@ -122,12 +122,15 @@ func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) {
|
||||
|
||||
if frontMatter != "" {
|
||||
yqlib.GetLogger().Debug("using front matter handler")
|
||||
originalFilename := args[0]
|
||||
frontMatterHandler := yqlib.NewFrontMatterHandler(args[0])
|
||||
err = frontMatterHandler.Split()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
args[0] = frontMatterHandler.GetYamlFrontMatterFilename()
|
||||
yqlib.SetFilenameAlias(args[0], originalFilename)
|
||||
defer yqlib.ClearFilenameAliases()
|
||||
|
||||
if frontMatter == "process" {
|
||||
reader := frontMatterHandler.GetContentReader()
|
||||
|
||||
@ -108,6 +108,55 @@ yaml: doc
|
||||
fmHandler.CleanUp()
|
||||
}
|
||||
|
||||
func TestFrontMatterFilenamePreserved(t *testing.T) {
|
||||
// Regression test for https://github.com/mikefarah/yq/issues/2538
|
||||
// When using --front-matter, the filename operator should return
|
||||
// the original filename, not the path to the temporary file.
|
||||
file := createTestFile(`---
|
||||
name: john
|
||||
---
|
||||
Some content
|
||||
`)
|
||||
originalFilename := "/path/to/original/file.md"
|
||||
|
||||
fmHandler := NewFrontMatterHandler(file)
|
||||
err := fmHandler.Split()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tempFilename := fmHandler.GetYamlFrontMatterFilename()
|
||||
|
||||
// Register the alias (as the command code does)
|
||||
SetFilenameAlias(tempFilename, originalFilename)
|
||||
defer ClearFilenameAliases()
|
||||
|
||||
// Verify resolveFilename returns the original name
|
||||
resolved := resolveFilename(tempFilename)
|
||||
test.AssertResult(t, originalFilename, resolved)
|
||||
|
||||
// Read documents using the temp file, verify they get the original filename
|
||||
reader, err := readStream(tempFilename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decoder := NewYamlDecoder(ConfiguredYamlPreferences)
|
||||
docs, err := readDocuments(reader, tempFilename, 0, decoder)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if docs.Len() == 0 {
|
||||
t.Fatal("expected at least one document")
|
||||
}
|
||||
|
||||
firstDoc := docs.Front().Value.(*CandidateNode)
|
||||
test.AssertResult(t, originalFilename, firstDoc.filename)
|
||||
|
||||
tryRemoveTempFile(file)
|
||||
fmHandler.CleanUp()
|
||||
}
|
||||
|
||||
func TestFrontMatterSplitWithArray(t *testing.T) {
|
||||
file := createTestFile(`[1,2,3]
|
||||
---
|
||||
|
||||
@ -76,6 +76,7 @@ func (s *streamEvaluator) EvaluateFiles(expression string, filenames []string, p
|
||||
}
|
||||
|
||||
func (s *streamEvaluator) Evaluate(filename string, reader io.Reader, node *ExpressionNode, printer Printer, decoder Decoder) (uint, error) {
|
||||
filename = resolveFilename(filename)
|
||||
|
||||
var currentIndex uint
|
||||
err := decoder.Init(reader)
|
||||
|
||||
@ -9,6 +9,29 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// filenameAliases maps real file paths to display names.
|
||||
// Used by front matter handling to preserve original filenames
|
||||
// when the actual content is read from temporary files.
|
||||
var filenameAliases = map[string]string{}
|
||||
|
||||
// SetFilenameAlias registers a display name for a file path so that
|
||||
// the filename operator returns the original name instead of a temp path.
|
||||
func SetFilenameAlias(realPath string, displayName string) {
|
||||
filenameAliases[realPath] = displayName
|
||||
}
|
||||
|
||||
// ClearFilenameAliases removes all filename aliases.
|
||||
func ClearFilenameAliases() {
|
||||
filenameAliases = map[string]string{}
|
||||
}
|
||||
|
||||
func resolveFilename(filename string) string {
|
||||
if alias, ok := filenameAliases[filename]; ok {
|
||||
return alias
|
||||
}
|
||||
return filename
|
||||
}
|
||||
|
||||
func readStream(filename string) (io.Reader, error) {
|
||||
var reader *bufio.Reader
|
||||
if filename == "-" {
|
||||
@ -36,6 +59,7 @@ func ReadDocuments(reader io.Reader, decoder Decoder) (*list.List, error) {
|
||||
}
|
||||
|
||||
func readDocuments(reader io.Reader, filename string, fileIndex int, decoder Decoder) (*list.List, error) {
|
||||
filename = resolveFilename(filename)
|
||||
err := decoder.Init(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Loading…
Reference in New Issue
Block a user