Skip to content

Commit 0e738c0

Browse files
committed
Improve handling of templates
- Template mode: Use empty string if env var is empty - Template mode: --search and --replace are optional - Introduced better error handling with fatal errrors
1 parent 7d74d1b commit 0e738c0

File tree

3 files changed

+73
-27
lines changed

3 files changed

+73
-27
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Application Options:
5959
## Installation
6060

6161
```bash
62-
GOREPLACE_VERSION=0.5.0 \
62+
GOREPLACE_VERSION=0.5.1 \
6363
&& wget -O /usr/local/bin/go-replace https://github.com/webdevops/goreplace/releases/download/$GOREPLACE_VERSION/gr-64-linux \
6464
&& chmod +x /usr/local/bin/go-replace
6565
```

goreplace.go

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
const (
1919
Author = "webdevops.io"
20-
Version = "0.5.0"
20+
Version = "0.5.1"
2121
)
2222

2323
type changeset struct {
@@ -48,8 +48,8 @@ var opts struct {
4848
ModeIsReplaceLine bool
4949
ModeIsLineInFile bool
5050
ModeIsTemplate bool
51-
Search []string `short:"s" long:"search" required:"true" description:"search term"`
52-
Replace []string `short:"r" long:"replace" required:"true" description:"replacement term" `
51+
Search []string `short:"s" long:"search" description:"search term"`
52+
Replace []string `short:"r" long:"replace" description:"replacement term" `
5353
CaseInsensitive bool `short:"i" long:"case-insensitive" description:"ignore case of pattern to match upper and lowercase characters"`
5454
Stdin bool ` long:"stdin" description:"process stdin as input"`
5555
Once bool ` long:"once" description:"replace search term only one in a file"`
@@ -244,6 +244,15 @@ func logError(err error) {
244244
fmt.Fprintln(os.Stderr, "Error: %s\n", err)
245245
}
246246

247+
248+
// Log error object as message
249+
func logFatalErrorAndExit(err error, exitCode int) {
250+
fmt.Fprintln(os.Stderr, "Error: %s\n", err)
251+
fmt.Fprintln(os.Stderr, "")
252+
argparser.WriteHelp(os.Stdout)
253+
os.Exit(exitCode)
254+
}
255+
247256
// Build search term
248257
// Compiles regexp if regexp is used
249258
func buildSearchTerm(term string) (*regexp.Regexp) {
@@ -338,7 +347,7 @@ func searchFilesInPath(path string, callback func(os.FileInfo, string)) {
338347
// --path
339348
// --mode=...
340349
// --once-without-match
341-
func handleSpecialCliOptions(argparser *flags.Parser, args []string) ([]string) {
350+
func handleSpecialCliOptions(args []string) ([]string) {
342351
// --version
343352
if (opts.ShowVersion) {
344353
fmt.Printf("goreplace version %s\n", Version)
@@ -434,11 +443,12 @@ func parseContentAsTemplate(templateContent string, changesets []changeset) byte
434443

435444
tmpl, err := template.New("template").Parse(templateContent)
436445
if err != nil {
437-
logError(err)
446+
logFatalErrorAndExit(err, 1)
438447
}
448+
tmpl.Option("missingkey=zero")
439449
err = tmpl.Execute(&content, &data)
440450
if err != nil {
441-
logError(err)
451+
logFatalErrorAndExit(err, 1)
442452
}
443453

444454
return content
@@ -458,7 +468,7 @@ func actionProcessStdinTemplate(changesets []changeset) (int) {
458468
return 0
459469
}
460470

461-
func actionProcessFiles(changesets []changeset, args []string, argparser *flags.Parser) (int) {
471+
func actionProcessFiles(changesets []changeset, args []string) (int) {
462472
// check if there is at least one file to process
463473
if (len(args) == 0) {
464474
if (opts.IgnoreEmpty) {
@@ -467,11 +477,7 @@ func actionProcessFiles(changesets []changeset, args []string, argparser *flags.
467477
os.Exit(0)
468478
} else {
469479
// no files found, print error and exit with error code
470-
err := errors.New("No files specified")
471-
logError(err)
472-
fmt.Fprintln(os.Stderr, "")
473-
argparser.WriteHelp(os.Stdout)
474-
return 1
480+
logFatalErrorAndExit(errors.New("No files specified"), 1)
475481
}
476482
}
477483

@@ -533,17 +539,20 @@ func actionProcessFiles(changesets []changeset, args []string, argparser *flags.
533539
return 0
534540
}
535541

536-
func buildChangesets(argparser *flags.Parser) ([]changeset){
542+
func buildChangesets() ([]changeset){
537543
var changesets []changeset
538544

545+
if !opts.ModeIsTemplate {
546+
if len(opts.Search) == 0 || len(opts.Replace) == 0 {
547+
// error: unequal numbers of search and replace options
548+
logFatalErrorAndExit(errors.New("Missing either --search or --replace for this mode"), 1)
549+
}
550+
}
551+
539552
// check if search and replace options have equal lenght (equal number of options)
540553
if len(opts.Search) != len(opts.Replace) {
541554
// error: unequal numbers of search and replace options
542-
err := errors.New("Unequal numbers of search or replace options")
543-
logError(err)
544-
fmt.Fprintln(os.Stderr, "")
545-
argparser.WriteHelp(os.Stdout)
546-
os.Exit(1)
555+
logFatalErrorAndExit(errors.New("Unequal numbers of search or replace options"), 1)
547556
}
548557

549558
// build changesets
@@ -558,21 +567,19 @@ func buildChangesets(argparser *flags.Parser) ([]changeset){
558567
return changesets
559568
}
560569

570+
var argparser *flags.Parser
561571
func main() {
562-
var argparser = flags.NewParser(&opts, flags.PassDoubleDash)
572+
argparser = flags.NewParser(&opts, flags.PassDoubleDash)
563573
args, err := argparser.Parse()
564574

565-
args = handleSpecialCliOptions(argparser, args)
575+
args = handleSpecialCliOptions(args)
566576

567577
// check if there is an parse error
568578
if err != nil {
569-
logError(err)
570-
fmt.Fprintln(os.Stderr, "")
571-
argparser.WriteHelp(os.Stdout)
572-
os.Exit(1)
579+
logFatalErrorAndExit(err, 1)
573580
}
574581

575-
changesets := buildChangesets(argparser)
582+
changesets := buildChangesets()
576583

577584
exitMode := 0
578585
if opts.Stdin {
@@ -585,7 +592,7 @@ func main() {
585592
}
586593
} else {
587594
// use and process files (see args)
588-
exitMode = actionProcessFiles(changesets, args, argparser)
595+
exitMode = actionProcessFiles(changesets, args)
589596
}
590597

591598
os.Exit(exitMode)

tests/main.t

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,45 @@ Testing template mode:
366366
this is the third foobar line
367367
this is the last line
368368

369+
Testing template mode with only env:
370+
371+
$ cat > test.txt <<EOF
372+
> {{23 -}} < {{- 45}}
373+
> {{.Env.Foobar}}
374+
> this is a testline
375+
> this is the second line
376+
> this is the third foobar line
377+
> this is the last line
378+
> EOF
379+
$ Foobar=barfoo goreplace --mode=template test.txt
380+
$ cat test.txt
381+
23<45
382+
barfoo
383+
this is a testline
384+
this is the second line
385+
this is the third foobar line
386+
this is the last line
387+
388+
Testing template mode with only env and empty var:
389+
390+
$ cat > test.txt <<EOF
391+
> {{23 -}} < {{- 45}}
392+
> begin{{.Env.Foobar}}end
393+
> this is a testline
394+
> this is the second line
395+
> this is the third foobar line
396+
> this is the last line
397+
> EOF
398+
$ Foobar= goreplace --mode=template test.txt
399+
$ cat test.txt
400+
23<45
401+
beginend
402+
this is a testline
403+
this is the second line
404+
this is the third foobar line
405+
this is the last line
406+
407+
369408
Testing template mode:
370409

371410
$ cat > test.txt <<EOF

0 commit comments

Comments
 (0)