Skip to content

Commit 794dd48

Browse files
committed
Initial refactor
Signed-off-by: Ulysses Souza <[email protected]>
1 parent ef5d373 commit 794dd48

24 files changed

+800
-1315
lines changed

EnvLangFile.g4

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,43 @@
11
grammar EnvLangFile;
22

3-
envFile: NL* (entry NL*)+ ;
3+
envFile
4+
: CRLF* (entry CRLF*)+
5+
;
46

5-
entry : identifier (ASSIGN value | ASSIGN)? (NL* | EOF) ;
7+
entry
8+
: identifier (ASSIGN value | ASSIGN)? (SPACE* CRLF* | EOF)
9+
;
610

7-
identifier : TEXT;
11+
identifier
12+
: TEXT
13+
;
814

9-
value : op=(DQSTRING | SQSTRING | TEXT) ;
15+
value
16+
: str=(DQSTRING | SQSTRING | TEXT)
17+
;
1018

11-
ASSIGN : '=';
12-
NL : '\r'? '\n';
13-
TEXT : ~[=,\r\n"' ]~[=,\r\n"']* ;
14-
DQSTRING : '"' ('""'|~'"')* '"' ;
15-
SQSTRING : '\'' ('\'\''|~'\'')* '\'' ;
19+
ASSIGN
20+
: '='
21+
;
1622

17-
SPACE : ' ' -> skip;
23+
CRLF
24+
: '\r'? '\n'
25+
| '\r'
26+
;
27+
28+
TEXT
29+
: ~[=,\r\n"' ]~[=,\r\n"']*
30+
;
31+
32+
DQSTRING
33+
: '"' ('""' | ~'"')* '"'
34+
;
35+
36+
SQSTRING
37+
: '\'' ('\'\'' | ~'\'')* '\''
38+
;
39+
40+
SPACE
41+
:
42+
' ' -> skip
43+
;

EnvLangValue.g4

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,58 @@
11
grammar EnvLangValue;
22

3-
dqstring : content* (CRLF* | EOF) ;
3+
dqstring
4+
: content* (SPACE* | CRLF* | EOF)
5+
;
46

5-
strictVar : '${' TEXT_NO_SPACE+ '}';
6-
simpleVar : '$' TEXT_NO_SPACE+ ;
7+
variable
8+
: var=(STRICT_VAR | SIMPLE_VAR)
9+
;
710

8-
variable : strictVar | simpleVar ;
11+
content
12+
: variable
13+
| STR
14+
| SPACE
15+
| CRLF
16+
;
917

10-
TEXT_NO_SPACE : [a-zA-Z0-9_] ;
11-
TEXT_ANY : [a-zA-Z0-9_\n] ;
18+
STRICT_VAR
19+
: '${' SPACE* VAR_ID SPACE* '}'
20+
;
1221

13-
text : TEXT_NO_SPACE TEXT_ANY* ;
22+
SIMPLE_VAR
23+
: '$' VAR_ID
24+
;
1425

15-
space : ' ';
26+
STR
27+
: FIRST_CHAR REST_OF_STRING*
28+
;
1629

17-
dQEscape : '""' ;
30+
SPACE
31+
: ' '
32+
| '\t'
33+
;
1834

19-
special
20-
: '{'
21-
| '}'
22-
| '$'
23-
;
35+
CRLF
36+
: '\r'? '\n'
37+
| '\r'
38+
;
2439

25-
content
26-
: dQEscape
27-
| variable
28-
| space
29-
| special
30-
| text
31-
;
40+
fragment FIRST_CHAR
41+
: ~[,\\."'\r\n ]
42+
;
43+
44+
fragment REST_OF_STRING
45+
: ~[\\'"$\r\n ]
46+
;
47+
48+
fragment VAR_ID
49+
: [0-9]+ // Only numbers
50+
| [a-zA-Z_][a-zA-Z_0-9]* // Start with letters, then letters, numbers and underscores
51+
;
52+
53+
// Catch all rule.
54+
// This is used to avoid the error message "no viable alternative at input '<EOF>'". Just for debugging.
55+
ANY
56+
: .
57+
;
3258

33-
CRLF
34-
: '\r'? '\n'
35-
| '\r'
36-
;

Makefile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ all: clean gen test
22
@echo "All done!"
33

44
test:
5-
@gotestsum --format testname ./...
5+
@gotestsum --format testname -- -failfast ./...
66

77
gen:
8-
@antlr -Dlanguage=Go -o gen/fileparser -package fileparser EnvLangFile.g4
9-
@antlr -Dlanguage=Go -o gen/valueparser -package valueparser EnvLangValue.g4
8+
@antlr4 -Dlanguage=Go -o gen/fileparser -package fileparser EnvLangFile.g4
9+
@antlr4 -Dlanguage=Go -o gen/valueparser -package valueparser EnvLangValue.g4
1010

1111
clean:
1212
@rm -rf gen
1313

1414
setup:
1515
go install gotest.tools/[email protected]
16+
17+
grun:
18+
antlr4 EnvLangValue.g4
19+
javac -cp "/usr/share/java/antlr-4.13.1-complete.jar:$CLASSPATH" EnvLangValue*.java
20+
java -Xmx500M -cp "/usr/share/java/antlr-4.13.1-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig EnvLangValue dqstrings -tokens

dao/default_dao.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,37 @@ var _ EnvLangDao = &DefaultDao{}
1010
type DefaultDao struct {
1111
sync.RWMutex
1212

13-
m map[string]*string
13+
env map[string]*string
14+
m map[string]*string
1415
}
1516

1617
func NewDefaultDao() EnvLangDao {
1718
return &DefaultDao{
18-
m: make(map[string]*string),
19+
m: make(map[string]*string),
20+
env: make(map[string]*string),
21+
}
22+
}
23+
24+
func NewDefaultDaoFromEnv(env []string) EnvLangDao {
25+
d := &DefaultDao{
26+
m: make(map[string]*string),
27+
env: make(map[string]*string),
28+
}
29+
for _, e := range env {
30+
splitEnv := strings.SplitN(e, "=", 2)
31+
v := splitEnv[1]
32+
d.env[splitEnv[0]] = &v
33+
}
34+
return d
35+
}
36+
37+
func NewDefaultDaoFromMap(env map[string]*string) EnvLangDao {
38+
if env == nil {
39+
env = make(map[string]*string)
40+
}
41+
return &DefaultDao{
42+
m: make(map[string]*string),
43+
env: env,
1944
}
2045
}
2146

@@ -48,6 +73,9 @@ func (d *DefaultDao) Get(k string) (*string, bool) {
4873
defer d.RUnlock()
4974

5075
v, ok := d.m[k]
76+
if !ok {
77+
v, ok = d.env[k]
78+
}
5179
return v, ok
5280
}
5381

facade_test.go

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,179 @@ import (
99
"github.com/ulyssessouza/envlang/dao"
1010
)
1111

12+
func init() {
13+
log.SetLevel(log.DebugLevel)
14+
}
15+
16+
func TestGetValue(t *testing.T) {
17+
tests := []struct {
18+
name string
19+
input string
20+
expected map[string]*string
21+
envState map[string]*string
22+
}{
23+
{
24+
"Simple",
25+
`A=aaa`,
26+
map[string]*string{"A": strPtr("aaa")},
27+
nil,
28+
},
29+
{
30+
"SimpleWithSpaceBeforeAssign",
31+
`A =aaa`,
32+
map[string]*string{"A": strPtr("aaa")},
33+
nil,
34+
},
35+
{
36+
"SimpleWithSpaceAfterAssign",
37+
`A= aaa`,
38+
map[string]*string{"A": strPtr("aaa")},
39+
nil,
40+
},
41+
{
42+
"SimpleWithDoubleQuotes",
43+
`A="aaa"`,
44+
map[string]*string{"A": strPtr("aaa")},
45+
nil,
46+
},
47+
{
48+
"SimpleWithSingleQuotes",
49+
`A='aaa'`,
50+
map[string]*string{"A": strPtr("aaa")},
51+
nil,
52+
},
53+
{
54+
"SimpleWithDoubleQuotesAndSpaces",
55+
`A=aaa bbb ccc`,
56+
map[string]*string{"A": strPtr("aaa bbb ccc")},
57+
nil,
58+
},
59+
{
60+
"SimpleWithSingleQuotesAndSpaces",
61+
`A='aaa bbb ccc'`,
62+
map[string]*string{"A": strPtr("aaa bbb ccc")},
63+
nil,
64+
},
65+
{
66+
"SimpleWithDoubleQuotesAndSpaces",
67+
`A="aaa bbb ccc"`,
68+
map[string]*string{"A": strPtr("aaa bbb ccc")},
69+
nil,
70+
},
71+
{
72+
"MultiLine",
73+
`
74+
A="my
75+
multi
76+
line
77+
entry"
78+
`,
79+
map[string]*string{"A": strPtr("my\nmulti\nline\nentry")},
80+
nil,
81+
},
82+
{
83+
"VariableWithEquals",
84+
`A=`,
85+
map[string]*string{"A": strPtr("")},
86+
nil,
87+
},
88+
{
89+
"VariableOnly",
90+
`A`,
91+
map[string]*string{"A": nil},
92+
nil,
93+
},
94+
{
95+
"SimpleWithSpaces",
96+
`
97+
A = aaa
98+
`,
99+
map[string]*string{"A": strPtr("aaa")},
100+
nil,
101+
},
102+
{
103+
"SimpleWithSimpleVariable",
104+
`
105+
A=$VAR_FROM_DAO
106+
`,
107+
map[string]*string{
108+
"A": strPtr("aaa"),
109+
},
110+
map[string]*string{
111+
"VAR_FROM_DAO": strPtr("aaa"),
112+
},
113+
},
114+
{
115+
"SimpleWithSimpleVariableWithSpaces",
116+
`
117+
A = $VAR_FROM_DAO
118+
`,
119+
map[string]*string{
120+
"A": strPtr("aaa"),
121+
},
122+
map[string]*string{
123+
"VAR_FROM_DAO": strPtr("aaa"),
124+
},
125+
},
126+
{
127+
"SimpleWithStrictVariable",
128+
`
129+
A=${VAR_FROM_DAO}
130+
`,
131+
map[string]*string{
132+
"A": strPtr("aaa"),
133+
},
134+
map[string]*string{
135+
"VAR_FROM_DAO": strPtr("aaa"),
136+
},
137+
},
138+
{
139+
"SimpleWithStrictVariableWithSpaces",
140+
`
141+
A = ${VAR_FROM_DAO}
142+
`,
143+
map[string]*string{
144+
"A": strPtr("aaa"),
145+
},
146+
map[string]*string{
147+
"VAR_FROM_DAO": strPtr("aaa"),
148+
},
149+
},
150+
{
151+
"SimpleWithStrictVariableWithSpacesAndInternalSpaces",
152+
`
153+
A = ${ VAR_FROM_DAO }
154+
`,
155+
map[string]*string{
156+
"A": strPtr("aaa"),
157+
},
158+
map[string]*string{
159+
"VAR_FROM_DAO": strPtr("aaa"),
160+
},
161+
},
162+
163+
{
164+
"DoubleQuotedWithMixedValue",
165+
`
166+
A = "aaa ${B} ccc "
167+
`,
168+
map[string]*string{
169+
"A": strPtr("aaa bbb ccc "),
170+
},
171+
map[string]*string{
172+
"B": strPtr("bbb "),
173+
},
174+
},
175+
}
176+
for _, tt := range tests {
177+
t.Run(tt.name, func(t *testing.T) {
178+
d := dao.NewDefaultDaoFromMap(tt.envState)
179+
assert.DeepEqual(t, tt.expected, GetVariables(d, tt.input))
180+
})
181+
182+
}
183+
}
184+
12185
func TestFull(t *testing.T) {
13186
log.SetLevel(log.DebugLevel)
14187
is := `
@@ -62,7 +235,7 @@ SPECIAL6 = "{{{ $$$ }}}"
62235
"B": strPtr("bbb"),
63236
"C": strPtr("ccc"),
64237
"D": strPtr("ddd"),
65-
"E": strPtr("'eee'"),
238+
"E": strPtr("eee"),
66239
"F": strPtr(""),
67240
"G": nil,
68241
"H": strPtr("my_value"),

0 commit comments

Comments
 (0)