Skip to content

Commit 4e0f64a

Browse files
authored
[issue #9] moving restriction validation to VariableNode fixes issue (#11)
* [issue #9] moving restriction validation to VariableNode fixes issue; removed empty comment
1 parent 9163442 commit 4e0f64a

File tree

3 files changed

+38
-36
lines changed

3 files changed

+38
-36
lines changed

parse/node.go

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,49 @@ func (t *TextNode) String() (string, error) {
3939

4040
type VariableNode struct {
4141
NodeType
42-
Ident string
43-
Env Env
42+
Ident string
43+
Env Env
44+
Restrict *Restrictions
4445
}
4546

46-
func NewVariable(ident string, env Env) *VariableNode {
47-
return &VariableNode{NodeVariable, ident, env}
47+
func NewVariable(ident string, env Env, restrict *Restrictions) *VariableNode {
48+
return &VariableNode{NodeVariable, ident, env, restrict}
4849
}
4950

5051
func (t *VariableNode) String() (string, error) {
51-
return t.Env.Get(t.Ident), nil
52+
if err := t.validateNoUnset(); err != nil {
53+
return "", err
54+
}
55+
value := t.Env.Get(t.Ident)
56+
if err := t.validateNoEmpty(value); err != nil {
57+
return "", err
58+
}
59+
return value, nil
5260
}
5361

5462
func (t *VariableNode) isSet() bool {
5563
return t.Env.Has(t.Ident)
5664
}
5765

66+
func (t *VariableNode) validateNoUnset() error {
67+
if t.Restrict.NoUnset && !t.isSet() {
68+
return fmt.Errorf("variable ${%s} not set", t.Ident)
69+
}
70+
return nil
71+
}
72+
73+
func (t *VariableNode) validateNoEmpty(value string) error {
74+
if t.Restrict.NoEmpty && value == "" && t.isSet() {
75+
return fmt.Errorf("variable ${%s} set but empty", t.Ident)
76+
}
77+
return nil
78+
}
79+
5880
type SubstitutionNode struct {
5981
NodeType
6082
ExpType itemType
6183
Variable *VariableNode
6284
Default Node // Default could be variable or text
63-
Restrict *Restrictions
6485
}
6586

6687
func (t *SubstitutionNode) String() (string, error) {
@@ -70,39 +91,17 @@ func (t *SubstitutionNode) String() (string, error) {
7091
if s, _ := t.Variable.String(); s != "" {
7192
return s, nil
7293
}
73-
return t.validate(t.Default)
94+
return t.Default.String()
7495
case itemPlus, itemColonPlus:
7596
if t.Variable.isSet() {
76-
return t.validate(t.Default)
97+
return t.Default.String()
7798
}
7899
return "", nil
79100
default:
80101
if !t.Variable.isSet() {
81-
return t.validate(t.Default)
102+
return t.Default.String()
82103
}
83104
}
84105
}
85-
return t.validate(t.Variable)
86-
}
87-
88-
func (t *SubstitutionNode) validate(node Node) (string, error) {
89-
if err := t.validateNoUnset(node); err != nil {
90-
return "", err
91-
}
92-
return t.validateNoEmpty(node)
93-
}
94-
95-
func (t *SubstitutionNode) validateNoUnset(node Node) error {
96-
if t.Restrict.NoUnset && node.Type() == NodeVariable && !node.(*VariableNode).isSet() {
97-
return fmt.Errorf("variable ${%s} not set", t.Variable.Ident)
98-
}
99-
return nil
100-
}
101-
102-
func (t *SubstitutionNode) validateNoEmpty(node Node) (string, error) {
103-
value, _ := node.String()
104-
if t.Restrict.NoEmpty && value == "" && (node.Type() != NodeVariable || node.(*VariableNode).isSet()) {
105-
return "", fmt.Errorf("variable ${%s} set but empty", t.Variable.Ident)
106-
}
107-
return value, nil
106+
return t.Variable.String()
108107
}

parse/parse.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Loop:
6767
case itemError:
6868
return p.errorf(t.val)
6969
case itemVariable:
70-
varNode := NewVariable(strings.TrimPrefix(t.val, "$"), p.Env)
70+
varNode := NewVariable(strings.TrimPrefix(t.val, "$"), p.Env, p.Restrict)
7171
p.nodes = append(p.nodes, varNode)
7272
case itemLeftDelim:
7373
if p.peek().typ == itemVariable {
@@ -91,7 +91,7 @@ Loop:
9191
func (p *Parser) action() (Node, error) {
9292
var expType itemType
9393
var defaultNode Node
94-
varNode := NewVariable(p.next().val, p.Env)
94+
varNode := NewVariable(p.next().val, p.Env, p.Restrict)
9595
Loop:
9696
for {
9797
switch t := p.next(); t.typ {
@@ -100,7 +100,7 @@ Loop:
100100
case itemError:
101101
return nil, p.errorf(t.val)
102102
case itemVariable:
103-
defaultNode = NewVariable(strings.TrimPrefix(t.val, "$"), p.Env)
103+
defaultNode = NewVariable(strings.TrimPrefix(t.val, "$"), p.Env, p.Restrict)
104104
case itemText:
105105
n := NewText(t.val)
106106
Text:
@@ -118,7 +118,7 @@ Loop:
118118
expType = t.typ
119119
}
120120
}
121-
return &SubstitutionNode{NodeSubstitution, expType, varNode, defaultNode, p.Restrict}, nil
121+
return &SubstitutionNode{NodeSubstitution, expType, varNode, defaultNode}, nil
122122
}
123123

124124
func (p *Parser) errorf(s string) error {

parse/parse_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ var parseTests = []parseTest{
6868
// test specifically for failure modes
6969
{"$var not set", "${NOTSET}", "", errUnset},
7070
{"$var set to empty", "${EMPTY}", "", errEmpty},
71+
// restrictions for plain variables without braces
72+
{"gh-issue-9", "$NOTSET", "", errUnset},
73+
{"gh-issue-9", "$EMPTY", "", errEmpty},
7174

7275
{"$var and $DEFAULT not set -", "${NOTSET-$ALSO_NOTSET}", "", errUnset},
7376
{"$var and $DEFAULT not set :-", "${NOTSET:-$ALSO_NOTSET}", "", errUnset},

0 commit comments

Comments
 (0)