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

Initial refactor #1

Merged
merged 1 commit into from
Mar 19, 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
46 changes: 36 additions & 10 deletions EnvLangFile.g4
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
grammar EnvLangFile;

envFile: NL* (entry NL*)+ ;
envFile
: CRLF* (entry CRLF*)+
;

entry : identifier (ASSIGN value | ASSIGN)? (NL* | EOF) ;
entry
: identifier (ASSIGN value | ASSIGN)? (SPACE* CRLF* | EOF)
;

identifier : TEXT;
identifier
: TEXT
;

value : op=(DQSTRING | SQSTRING | TEXT) ;
value
: str=(DQSTRING | SQSTRING | TEXT)
;

ASSIGN : '=';
NL : '\r'? '\n';
TEXT : ~[=,\r\n"' ]~[=,\r\n"']* ;
DQSTRING : '"' ('""'|~'"')* '"' ;
SQSTRING : '\'' ('\'\''|~'\'')* '\'' ;
ASSIGN
: '='
;

SPACE : ' ' -> skip;
CRLF
: '\r'? '\n'
| '\r'
;

TEXT
: ~[=,\r\n"' ]~[=,\r\n"']*
;

DQSTRING
: '"' ('""' | ~'"')* '"'
;

SQSTRING
: '\'' ('\'\'' | ~'\'')* '\''
;

SPACE
:
' ' -> skip
;
72 changes: 47 additions & 25 deletions EnvLangValue.g4
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
grammar EnvLangValue;

dqstring : content* (CRLF* | EOF) ;
dqstring
: content* (SPACE* | CRLF* | EOF)
;

strictVar : '${' TEXT_NO_SPACE+ '}';
simpleVar : '$' TEXT_NO_SPACE+ ;
variable
: var=(STRICT_VAR | SIMPLE_VAR)
;

variable : strictVar | simpleVar ;
content
: variable
| STR
| SPACE
| CRLF
;

TEXT_NO_SPACE : [a-zA-Z0-9_] ;
TEXT_ANY : [a-zA-Z0-9_\n] ;
STRICT_VAR
: '${' SPACE* VAR_ID SPACE* '}'
;

text : TEXT_NO_SPACE TEXT_ANY* ;
SIMPLE_VAR
: '$' VAR_ID
;

space : ' ';
STR
: FIRST_CHAR REST_OF_STRING*
;

dQEscape : '""' ;
SPACE
: ' '
| '\t'
;

special
: '{'
| '}'
| '$'
;
CRLF
: '\r'? '\n'
| '\r'
;

content
: dQEscape
| variable
| space
| special
| text
;
fragment FIRST_CHAR
: ~[,\\."'\r\n ]
;

fragment REST_OF_STRING
: ~[\\'"$\r\n ]
;

fragment VAR_ID
: [0-9]+ // Only numbers
| [a-zA-Z_][a-zA-Z_0-9]* // Start with letters, then letters, numbers and underscores
;

// Catch all rule.
// This is used to avoid the error message "no viable alternative at input '<EOF>'". Just for debugging.
ANY
: .
;

CRLF
: '\r'? '\n'
| '\r'
;
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ all: clean gen test
@echo "All done!"

test:
@gotestsum --format testname ./...
@gotestsum --format testname -- -failfast ./...

gen:
@antlr -Dlanguage=Go -o gen/fileparser -package fileparser EnvLangFile.g4
@antlr -Dlanguage=Go -o gen/valueparser -package valueparser EnvLangValue.g4
@antlr4 -Dlanguage=Go -o gen/fileparser -package fileparser EnvLangFile.g4
@antlr4 -Dlanguage=Go -o gen/valueparser -package valueparser EnvLangValue.g4

clean:
@rm -rf gen

setup:
go install gotest.tools/[email protected]

grun:
antlr4 EnvLangValue.g4
javac -cp "/usr/share/java/antlr-4.13.1-complete.jar:$CLASSPATH" EnvLangValue*.java
java -Xmx500M -cp "/usr/share/java/antlr-4.13.1-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig EnvLangValue dqstrings -tokens
32 changes: 30 additions & 2 deletions dao/default_dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,37 @@ var _ EnvLangDao = &DefaultDao{}
type DefaultDao struct {
sync.RWMutex

m map[string]*string
env map[string]*string
m map[string]*string
}

func NewDefaultDao() EnvLangDao {
return &DefaultDao{
m: make(map[string]*string),
m: make(map[string]*string),
env: make(map[string]*string),
}
}

func NewDefaultDaoFromEnv(env []string) EnvLangDao {
d := &DefaultDao{
m: make(map[string]*string),
env: make(map[string]*string),
}
for _, e := range env {
splitEnv := strings.SplitN(e, "=", 2)
v := splitEnv[1]
d.env[splitEnv[0]] = &v
}
return d
}

func NewDefaultDaoFromMap(env map[string]*string) EnvLangDao {
if env == nil {
env = make(map[string]*string)
}
return &DefaultDao{
m: make(map[string]*string),
env: env,
}
}

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

v, ok := d.m[k]
if !ok {
v, ok = d.env[k]
}
return v, ok
}

Expand Down
175 changes: 174 additions & 1 deletion facade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,179 @@ import (
"github.com/ulyssessouza/envlang/dao"
)

func init() {
log.SetLevel(log.DebugLevel)
}

func TestGetValue(t *testing.T) {
tests := []struct {
name string
input string
expected map[string]*string
envState map[string]*string
}{
{
"Simple",
`A=aaa`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithSpaceBeforeAssign",
`A =aaa`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithSpaceAfterAssign",
`A= aaa`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithDoubleQuotes",
`A="aaa"`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithSingleQuotes",
`A='aaa'`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithDoubleQuotesAndSpaces",
`A=aaa bbb ccc`,
map[string]*string{"A": strPtr("aaa bbb ccc")},
nil,
},
{
"SimpleWithSingleQuotesAndSpaces",
`A='aaa bbb ccc'`,
map[string]*string{"A": strPtr("aaa bbb ccc")},
nil,
},
{
"SimpleWithDoubleQuotesAndSpaces",
`A="aaa bbb ccc"`,
map[string]*string{"A": strPtr("aaa bbb ccc")},
nil,
},
{
"MultiLine",
`
A="my
multi
line
entry"
`,
map[string]*string{"A": strPtr("my\nmulti\nline\nentry")},
nil,
},
{
"VariableWithEquals",
`A=`,
map[string]*string{"A": strPtr("")},
nil,
},
{
"VariableOnly",
`A`,
map[string]*string{"A": nil},
nil,
},
{
"SimpleWithSpaces",
`
A = aaa
`,
map[string]*string{"A": strPtr("aaa")},
nil,
},
{
"SimpleWithSimpleVariable",
`
A=$VAR_FROM_DAO
`,
map[string]*string{
"A": strPtr("aaa"),
},
map[string]*string{
"VAR_FROM_DAO": strPtr("aaa"),
},
},
{
"SimpleWithSimpleVariableWithSpaces",
`
A = $VAR_FROM_DAO
`,
map[string]*string{
"A": strPtr("aaa"),
},
map[string]*string{
"VAR_FROM_DAO": strPtr("aaa"),
},
},
{
"SimpleWithStrictVariable",
`
A=${VAR_FROM_DAO}
`,
map[string]*string{
"A": strPtr("aaa"),
},
map[string]*string{
"VAR_FROM_DAO": strPtr("aaa"),
},
},
{
"SimpleWithStrictVariableWithSpaces",
`
A = ${VAR_FROM_DAO}
`,
map[string]*string{
"A": strPtr("aaa"),
},
map[string]*string{
"VAR_FROM_DAO": strPtr("aaa"),
},
},
{
"SimpleWithStrictVariableWithSpacesAndInternalSpaces",
`
A = ${ VAR_FROM_DAO }
`,
map[string]*string{
"A": strPtr("aaa"),
},
map[string]*string{
"VAR_FROM_DAO": strPtr("aaa"),
},
},

{
"DoubleQuotedWithMixedValue",
`
A = "aaa ${B} ccc "
`,
map[string]*string{
"A": strPtr("aaa bbb ccc "),
},
map[string]*string{
"B": strPtr("bbb "),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := dao.NewDefaultDaoFromMap(tt.envState)
assert.DeepEqual(t, tt.expected, GetVariables(d, tt.input))
})

}
}

func TestFull(t *testing.T) {
log.SetLevel(log.DebugLevel)
is := `
Expand Down Expand Up @@ -62,7 +235,7 @@ SPECIAL6 = "{{{ $$$ }}}"
"B": strPtr("bbb"),
"C": strPtr("ccc"),
"D": strPtr("ddd"),
"E": strPtr("'eee'"),
"E": strPtr("eee"),
"F": strPtr(""),
"G": nil,
"H": strPtr("my_value"),
Expand Down
Loading
Loading