Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support globs in replacements path #716

Merged
merged 2 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/unreleased/added-20240911-234212.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: added
body: Support filepath globs in replacements
time: 2024-09-11T23:42:12.277856663-04:00
custom:
Issue: "713"
32 changes: 27 additions & 5 deletions core/replacement.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package core

import (
"bytes"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"text/template"
)

var ErrNoReplacementFilesFound = errors.New("glob pattern did not match any files")

// Template data used for replacing version values.
type ReplaceData struct {
// Version of the release, will include "v" prefix if used
Expand Down Expand Up @@ -39,6 +43,13 @@ type ReplaceData struct {
// replace: ' "version": "{{.VersionNoPrefix}}",'
type Replacement struct {
// Path of the file to find and replace in.
// Also supports Go filepath globs.
// example: yaml
// # Will match any .json file in the current directory
// replacements:
// - path: *.json
// find: ' "version": ".*",'
// replace: ' "version": "{{.VersionNoPrefix}}",'
miniscruff marked this conversation as resolved.
Show resolved Hide resolved
Path string `yaml:"path" required:"true"`
// Regular expression to search for in the file.
// Capture groups are supported and can be used in the replace value.
Expand Down Expand Up @@ -67,11 +78,15 @@ func (r Replacement) Execute(data ReplaceData) error {
return err
}

fileData, err := os.ReadFile(r.Path)
globs, err := filepath.Glob(r.Path)
if err != nil {
return err
}

if len(globs) == 0 {
return fmt.Errorf("%w: %s", ErrNoReplacementFilesFound, r.Path)
}

flags := r.Flags
if flags == "" {
flags = "m"
Expand All @@ -82,11 +97,18 @@ func (r Replacement) Execute(data ReplaceData) error {
return err
}

newData := regex.ReplaceAll(fileData, buf.Bytes())
for _, path := range globs {
fileData, err := os.ReadFile(path)
if err != nil {
return err
}

err = os.WriteFile(r.Path, newData, CreateFileMode)
if err != nil {
return err
newData := regex.ReplaceAll(fileData, buf.Bytes())

err = os.WriteFile(path, newData, CreateFileMode)
if err != nil {
return err
}
}

return nil
Expand Down
66 changes: 56 additions & 10 deletions core/replacement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,6 @@ level1:
then.FileContents(t, endData, filepath)
}

func TestErrorBadFileRead(t *testing.T) {
miniscruff marked this conversation as resolved.
Show resolved Hide resolved
then.WithTempDir(t)

rep := Replacement{
Path: "does not exist",
}
err := rep.Execute(ReplaceData{})
then.NotNil(t, err)
}

func TestErrorBadTemplateParse(t *testing.T) {
then.WithTempDir(t)

Expand Down Expand Up @@ -180,3 +170,59 @@ func TestErrorBadTemplateExec(t *testing.T) {
err := rep.Execute(ReplaceData{})
then.NotNil(t, err)
}

func TestErrorBadFileRead(t *testing.T) {
then.WithTempDir(t)

rep := Replacement{
Path: "does not exist",
}
err := rep.Execute(ReplaceData{})
then.Err(t, ErrNoReplacementFilesFound, err)
}

func TestGlobs(t *testing.T) {
miniscruff marked this conversation as resolved.
Show resolved Hide resolved
then.WithTempDir(t)

toReplace := []byte(`{
"version": "1.0.0"
}`)
then.WriteFile(t, toReplace, "a", "b", "c.json")
then.WriteFile(t, toReplace, "a", "b", "d.xml")
then.WriteFile(t, toReplace, "a", "b", "e.jsonl")
then.WriteFile(t, toReplace, "a", "b", "f.png")
then.WriteFile(t, toReplace, "a", "c", "g.json")

rep := Replacement{
Path: "a/*/*.json",
Find: ` "version": ".*"`,
Replace: ` "version": "{{.VersionNoPrefix}}"`,
}

err := rep.Execute(ReplaceData{
VersionNoPrefix: "1.1.0",
})
then.Nil(t, err)

changedFile := `{
"version": "1.1.0"
}`
unchangedFile := `{
"version": "1.0.0"
}`

then.FileContents(t, changedFile, "a", "b", "c.json")
then.FileContents(t, unchangedFile, "a", "b", "d.xml")
then.FileContents(t, unchangedFile, "a", "b", "e.jsonl")
then.FileContents(t, unchangedFile, "a", "b", "f.png")
then.FileContents(t, changedFile, "a", "c", "g.json")
}

func TestBadGlob(t *testing.T) {
rep := Replacement{
Path: `[]`,
}

err := rep.Execute(ReplaceData{})
then.NotNil(t, err)
}
Loading