@@ -18,7 +18,6 @@ package internal
18
18
import (
19
19
"bufio"
20
20
"bytes"
21
- "fmt"
22
21
"io"
23
22
"io/ioutil"
24
23
"os"
@@ -29,51 +28,48 @@ import (
29
28
)
30
29
31
30
// insertStrings reads content from given reader and insert string below the
32
- // line line containing marker string. So for ex. in insertStrings(r, m1, v1, m2, v2)
31
+ // line containing marker string. So for ex. in insertStrings(r, {'m1':
32
+ // [v1], 'm2': [v2]})
33
33
// v1 will be inserted below the lines containing m1 string and v2 will be inserted
34
34
// below line containing m2 string.
35
- func insertStrings (r io.Reader , markerAndValues ... string ) (io.Reader , error ) {
36
- if len ( markerAndValues ) % 2 != 0 {
37
- return nil , fmt . Errorf ( "invalid marker and value pairs" )
38
- }
35
+ func insertStrings (r io.Reader , markerAndValues map [ string ][] string ) (io.Reader , error ) {
36
+ // reader clone is needed since we will be reading twice from the given reader
37
+ buf := new (bytes. Buffer )
38
+ rClone := io . TeeReader ( r , buf )
39
39
40
- mvPairs := map [string ]string {}
41
- for i , s := range markerAndValues {
42
- if i % 2 == 0 {
43
- mvPairs [s ] = markerAndValues [i + 1 ]
44
- }
40
+ err := filterExistingValues (rClone , markerAndValues )
41
+ if err != nil {
42
+ return nil , err
45
43
}
46
44
47
- buf := new (bytes.Buffer )
45
+ out := new (bytes.Buffer )
48
46
49
- scanner := bufio .NewScanner (r )
47
+ scanner := bufio .NewScanner (buf )
50
48
for scanner .Scan () {
51
49
line := scanner .Text ()
52
50
53
- for m , v := range mvPairs {
54
- if strings .TrimSpace (line ) == strings .TrimSpace (v ) {
55
- // since value already exist, so avoid duplication
56
- delete (mvPairs , m )
57
- }
58
- if strings .Contains (line , m ) {
59
- _ , err := buf .WriteString (v )
60
- if err != nil {
61
- return nil , err
51
+ for marker , vals := range markerAndValues {
52
+ if strings .TrimSpace (line ) == strings .TrimSpace (marker ) {
53
+ for _ , val := range vals {
54
+ _ , err := out .WriteString (val )
55
+ if err != nil {
56
+ return nil , err
57
+ }
62
58
}
63
59
}
64
60
}
65
- _ , err := buf .WriteString (line + "\n " )
61
+ _ , err := out .WriteString (line + "\n " )
66
62
if err != nil {
67
63
return nil , err
68
64
}
69
65
}
70
66
if err := scanner .Err (); err != nil {
71
67
return nil , err
72
68
}
73
- return buf , nil
69
+ return out , nil
74
70
}
75
71
76
- func InsertStringsInFile (path string , markerAndValues ... string ) error {
72
+ func InsertStringsInFile (path string , markerAndValues map [ string ][] string ) error {
77
73
isGoFile := false
78
74
if ext := filepath .Ext (path ); ext == ".go" {
79
75
isGoFile = true
@@ -84,7 +80,7 @@ func InsertStringsInFile(path string, markerAndValues ...string) error {
84
80
return err
85
81
}
86
82
87
- r , err := insertStrings (f , markerAndValues ... )
83
+ r , err := insertStrings (f , markerAndValues )
88
84
if err != nil {
89
85
return err
90
86
}
@@ -115,3 +111,24 @@ func InsertStringsInFile(path string, markerAndValues ...string) error {
115
111
116
112
return err
117
113
}
114
+
115
+ // filterExistingValues removes the single-line values that already exists in
116
+ // the given reader. Multi-line values are ignore currently simply because we
117
+ // don't have a use-case for it.
118
+ func filterExistingValues (r io.Reader , markerAndValues map [string ][]string ) error {
119
+ scanner := bufio .NewScanner (r )
120
+ for scanner .Scan () {
121
+ line := scanner .Text ()
122
+ for marker , vals := range markerAndValues {
123
+ for i , val := range vals {
124
+ if strings .TrimSpace (line ) == strings .TrimSpace (val ) {
125
+ markerAndValues [marker ] = append (vals [:i ], vals [i + 1 :]... )
126
+ }
127
+ }
128
+ }
129
+ }
130
+ if err := scanner .Err (); err != nil {
131
+ return err
132
+ }
133
+ return nil
134
+ }
0 commit comments