Skip to content

Commit 933b609

Browse files
authored
fix injected filepath comments (#26)
* fix injected filepath comments fixes #23
1 parent 4c4037b commit 933b609

File tree

13 files changed

+226
-70
lines changed

13 files changed

+226
-70
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.PHONY: testdata
22
testdata:
33
go run . \
4+
-v \
45
-f testdata/input-parent.hujson \
56
-d testdata/departments/ \
67
-o testdata/output-file-to-compare-to.hujson \

main.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -138,23 +138,17 @@ func handleArray() SectionHandler {
138138
if childSection == nil {
139139
return
140140
}
141-
parentProps := parent.FindKey(ast.TextEqual(sectionKey))
142-
if parentProps != nil && len(parentProps.Value.(*jwcc.Array).Values) > 0 {
143-
pathComment(parentProps.Value.(*jwcc.Array).Values[0], parentPath)
144-
}
145141

146142
newArr := existingOrNewArray(*parent, sectionKey)
147-
childArrValues := childSection.Value.(*jwcc.Array).Values
148143

149144
pathCommentAlreadyAdded := false
150-
for i := range childArrValues {
151-
newArr.Values = append(newArr.Values, childArrValues[i])
145+
for _, v := range childSection.Value.(*jwcc.Array).Values {
146+
newArr.Values = append(newArr.Values, v)
152147

153148
if !pathCommentAlreadyAdded {
154-
pathComment(childArrValues[i], childPath)
149+
pathComment(v, childPath)
155150
pathCommentAlreadyAdded = true
156151
}
157-
158152
}
159153

160154
upsertMember(parent, sectionKey, newArr)
@@ -166,10 +160,6 @@ func handleObject() SectionHandler {
166160
if childSection == nil {
167161
return
168162
}
169-
parentProps := parent.FindKey(ast.TextEqual(sectionKey))
170-
if parentProps != nil {
171-
pathComment(parentProps.Value.(*jwcc.Object).Members[0], parentPath)
172-
}
173163

174164
newObj := existingOrNewObject(*parent, sectionKey)
175165

@@ -222,13 +212,31 @@ func upsertMember[V *jwcc.Object | *jwcc.Array](doc *jwcc.Object, key string, va
222212
}
223213

224214
func pathComment(val jwcc.Value, path string) {
215+
// TODO: preserve existing comments
225216
val.Comments().Before = []string{fmt.Sprintf("from `%s`", path)}
226217
}
227218

228-
func mergeDocs(sections map[string]SectionHandler, parentDoc *ParsedDocument, childDocs []*ParsedDocument) error {
219+
func addParentPathComments(parentDoc *ParsedDocument) error {
229220
for _, parentSection := range parentDoc.Object.Members {
230-
pathComment(parentSection, parentDoc.Path)
221+
logVerbose("adding parent path comment to [%s]\n", parentSection.Key)
222+
switch parentSection.Value.(type) {
223+
default:
224+
pathComment(parentSection, parentDoc.Path)
225+
case *jwcc.Array:
226+
pathComment(parentSection.Value.(*jwcc.Array).Values[0], parentDoc.Path)
227+
case *jwcc.Object:
228+
pathComment(parentSection.Value.(*jwcc.Object).Members[0], parentDoc.Path)
229+
}
231230
}
231+
return nil
232+
}
233+
234+
func mergeDocs(sections map[string]SectionHandler, parentDoc *ParsedDocument, childDocs []*ParsedDocument) error {
235+
err := addParentPathComments(parentDoc)
236+
if err != nil {
237+
log.Fatal(err)
238+
}
239+
232240
for _, child := range childDocs {
233241
if child.Path == parentDoc.Path {
234242
logVerbose("skipping [%s], same doc as parent\n", child.Path)

main_test.go

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"os"
45
"strings"
56
"testing"
67

@@ -163,6 +164,141 @@ func TestMergeDocsParentWithSameMember(t *testing.T) {
163164
}
164165
}
165166

167+
func TestPathCommentsForObject(t *testing.T) {
168+
parent, err := jwcc.Parse(strings.NewReader(`{
169+
"goodpath": {"bar":"foo"}
170+
}`))
171+
if err != nil {
172+
t.Fatalf("expected no error, got [%v]", err)
173+
}
174+
parentDoc := &ParsedDocument{
175+
Object: parent.Value.(*jwcc.Object),
176+
Path: "parent",
177+
}
178+
179+
child, err := jwcc.Parse(strings.NewReader(`{
180+
"goodpath": {"foo":"bar"}
181+
}`))
182+
if err != nil {
183+
t.Fatalf("expected no error, got [%v]", err)
184+
}
185+
childDoc := &ParsedDocument{
186+
Object: child.Value.(*jwcc.Object),
187+
Path: "child",
188+
}
189+
190+
sections := map[string]SectionHandler{
191+
"goodpath": handleObject(),
192+
}
193+
194+
err = mergeDocs(sections, parentDoc, []*ParsedDocument{childDoc})
195+
if err != nil {
196+
t.Fatalf("expected no error, got [%v]", err)
197+
}
198+
199+
if len(parentDoc.Object.Members) != 1 {
200+
t.Fatalf("parent members length should be [1], got [%v]", len(parentDoc.Object.Members))
201+
}
202+
203+
memberIndexKey := parentDoc.Object.IndexKey(ast.TextEqual("goodpath"))
204+
if memberIndexKey != 0 {
205+
t.Fatalf("section index key length should be [0], got [%v]", memberIndexKey)
206+
}
207+
208+
member := parentDoc.Object.Members[memberIndexKey]
209+
memberObjectMembers := member.Value.(*jwcc.Object).Members
210+
if len(memberObjectMembers) != 2 {
211+
t.Fatalf("member object keys length should be [2], got [%v]", len(memberObjectMembers))
212+
}
213+
214+
barMember := member.Value.(*jwcc.Object).Find("bar")
215+
if barMember.Value.String() != "foo" {
216+
t.Fatalf("member value should be [foo], got [%v]", barMember.Value.String())
217+
}
218+
barMemberComments := barMember.Comments().Before
219+
if barMemberComments[0] != "from `parent`" {
220+
t.Fatalf("member comment should be [from `parent`], got [%v]", barMemberComments[0])
221+
}
222+
223+
fooMember := member.Value.(*jwcc.Object).Find("foo")
224+
if fooMember.Value.String() != "bar" {
225+
t.Fatalf("member value should be [bar], got [%v]", fooMember.Value.String())
226+
}
227+
fooMemberComments := fooMember.Comments().Before
228+
if fooMemberComments[0] != "from `child`" {
229+
t.Fatalf("member comment should be [from `child`], got [%v]", fooMemberComments[0])
230+
}
231+
}
232+
233+
func TestPathCommentsForArray(t *testing.T) {
234+
parent, err := jwcc.Parse(strings.NewReader(`{
235+
"things": [{"thing1":"foo"}],
236+
}`))
237+
if err != nil {
238+
t.Fatalf("expected no error, got [%v]", err)
239+
}
240+
parentDoc := &ParsedDocument{
241+
Object: parent.Value.(*jwcc.Object),
242+
Path: "parent",
243+
}
244+
245+
child, err := jwcc.Parse(strings.NewReader(`{
246+
"things": [{"thing2":"bar"}],
247+
}`))
248+
if err != nil {
249+
t.Fatalf("expected no error, got [%v]", err)
250+
}
251+
childDoc := &ParsedDocument{
252+
Object: child.Value.(*jwcc.Object),
253+
Path: "child",
254+
}
255+
256+
sections := map[string]SectionHandler{
257+
"things": handleArray(),
258+
}
259+
260+
err = mergeDocs(sections, parentDoc, []*ParsedDocument{childDoc})
261+
if err != nil {
262+
t.Fatalf("expected no error, got [%v]", err)
263+
}
264+
265+
if len(parentDoc.Object.Members) != 1 {
266+
t.Fatalf("parent members length should be [1], got [%v]", len(parentDoc.Object.Members))
267+
}
268+
269+
thingsMember := parentDoc.Object.Find("things")
270+
if thingsMember == nil {
271+
t.Fatalf("section index key length should be not nil, got [%v]", thingsMember)
272+
}
273+
274+
thingsMemberValues := thingsMember.Value.(*jwcc.Array).Values
275+
if len(thingsMemberValues) != 2 {
276+
t.Fatalf("members length should be [2], got [%v]", len(thingsMemberValues))
277+
}
278+
279+
barMember := thingsMemberValues[0].(*jwcc.Object)
280+
if barMember.Members[0].Key.String() != "thing1" {
281+
t.Fatalf("member key should be [thing1], got [%v]", barMember.Members[0].Key.String())
282+
}
283+
if barMember.Members[0].Value.String() != "foo" {
284+
t.Fatalf("member value should be [foo], got [%v]", barMember.Members[0].Value.String())
285+
}
286+
if barMember.Comments().Before[0] != "from `parent`" {
287+
t.Fatalf("member comment should be [from `parent`], got [%v]", barMember.Comments().Before[0])
288+
}
289+
290+
fooMember := thingsMemberValues[1].(*jwcc.Object)
291+
if fooMember.Members[0].Key.String() != "thing2" {
292+
t.Fatalf("member key should be [thing2], got [%v]", fooMember.Members[0].Key.String())
293+
}
294+
if fooMember.Members[0].Value.String() != "bar" {
295+
t.Fatalf("member value should be [bar], got [%v]", fooMember.Members[0].Value.String())
296+
}
297+
if fooMember.Comments().Before[0] != "from `child`" {
298+
t.Fatalf("member comment should be [from `parent`], got [%v]", fooMember.Comments().Before[0])
299+
}
300+
}
301+
166302
func TestExistingOrNewObject(t *testing.T) {
167303
child, err := jwcc.Parse(strings.NewReader(`{
168304
"goodpath": {"foo":"bar"}
@@ -423,3 +559,10 @@ func TestSort(t *testing.T) {
423559
}
424560
}
425561
}
562+
563+
func printDocument(doc *ParsedDocument) {
564+
err := jwcc.Format(os.Stdout, doc.Object)
565+
if err != nil {
566+
panic(err)
567+
}
568+
}

testdata/departments/engineering/acls.hujson

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{ // engineering1
1111
"action": "accept",
1212
"src": [
13-
"engineering1@tsjustworks.net",
13+
"engineering1@example.com",
1414
],
1515
"dst": [
1616
"tag:demo-infra:22",
@@ -22,7 +22,7 @@
2222
{ // engineering2
2323
"action": "accept",
2424
"src": [
25-
"engineering2@tsjustworks.net",
25+
"engineering2@example.com",
2626
],
2727
"dst": [
2828
"tag:demo-infra:22",
@@ -34,7 +34,7 @@
3434
{ // engineering3
3535
"action": "accept",
3636
"src": [
37-
"engineering3@tsjustworks.net",
37+
"engineering3@example.com",
3838
],
3939
"dst": [
4040
"tag:demo-infra:22",
@@ -46,14 +46,14 @@
4646
],
4747
"tests": [
4848
{
49-
"src": "cameron@example.com",
50-
"accept": ["tag:cameron:22"],
49+
"src": "engineering@example.com",
50+
"accept": ["tag:dev:22"],
5151
},
5252
],
5353
"ssh": [
5454
{
5555
"action": "accept",
56-
"src": ["group:finance"],
56+
"src": ["group:engineering"],
5757
"dst": ["autogroup:self"],
5858
"users": ["root", "autogroup:nonroot"],
5959
},

testdata/departments/engineering/acls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"action": "accept",
55
"src": [
6-
6+
77
],
88
"dst": [
99
"tag:json-rule:22"

testdata/departments/engineering/autoApprovers.hujson

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
"autoApprovers": {
33
"routes": {
44
"10.0.0.0/32": [
5-
"tag:example"
5+
"tag:engineering"
66
]
77
},
8-
"exitNode": ["tag:example"],
8+
"exitNode": ["tag:engineering"],
99
},
1010
}

testdata/departments/engineering/grants.hujson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"grants": [
33
{
44
//"src": ["group:prod"],
5-
"src": ["[email protected]"],
5+
"src": ["[email protected]"],
66
"dst": ["tag:k8s-operator"],
77
"app": {
88
"tailscale.com/cap/kubernetes": [{
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"groups": {
3-
"group:group1": [
4-
3+
"group:engineering": [
4+
55
],
66
},
77
}

testdata/departments/finance/acls.hujson

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{ // finance1
44
"action": "accept",
55
"src": [
6-
"finance1@tsjustworks.net",
6+
"finance1@example.com",
77
],
88
"dst": [
99
"tag:demo-infra:22",
@@ -12,21 +12,21 @@
1212
{ // finance2
1313
"action": "accept",
1414
"src": [
15-
"finance2@tsjustworks.net",
15+
"finance2@example.com",
1616
],
1717
"dst": [
1818
"tag:demo-infra:22",
1919
],
2020
},
2121
],
2222
"groups": {
23-
"group:group2": [
24-
23+
"group:finance": [
24+
2525
],
2626
},
2727
"tests": [
2828
{
29-
"src": "dave@example.com",
29+
"src": "finance@example.com",
3030
"srcPostureAttrs": {
3131
"node:os": "windows",
3232
},

testdata/departments/finance/autoApprovers.hujson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"autoApprovers": {
33
"routes": {
44
"10.0.10.0/32": [
5-
"tag:example"
5+
"tag:finance"
66
]
77
}
88
}

0 commit comments

Comments
 (0)