Skip to content

Commit 7d39832

Browse files
committed
test: v3 syntax
Signed-off-by: Joseph Kato <joseph@jdkato.io>
1 parent c7fc3a1 commit 7d39832

File tree

4 files changed

+79
-58
lines changed

4 files changed

+79
-58
lines changed

internal/core/view.go

Lines changed: 71 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,18 @@ func NewView(path string) (*View, error) {
7474
return &view, nil
7575
}
7676

77-
func (b *View) ApplyV2(f *File) ([]ScopedValues, error) {
78-
found := []ScopedValues{}
79-
77+
func (b *View) Apply(f *File) ([]ScopedValues, error) {
8078
value, err := fileToValue(f)
8179
if err != nil {
8280
return nil, err
8381
}
8482

83+
found := make([]ScopedValues, 0, len(b.Scopes))
8584
for _, s := range b.Scopes {
86-
selected, verr := v2dasel.Select(value, s.Expr)
87-
if verr != nil {
88-
return found, verr
89-
}
90-
91-
values := []string{}
92-
for _, v := range selected {
93-
values = append(values, v.String())
85+
values, err := selectStrings(value, s.Expr)
86+
if err != nil {
87+
return nil, fmt.Errorf("processing scope %q: %w", s.Name, err)
9488
}
95-
9689
found = append(found, ScopedValues{
9790
Scope: s.Name,
9891
Values: values,
@@ -103,55 +96,75 @@ func (b *View) ApplyV2(f *File) ([]ScopedValues, error) {
10396
return found, nil
10497
}
10598

106-
func (b *View) Apply(f *File) ([]ScopedValues, error) {
107-
found := []ScopedValues{}
108-
109-
value, err := fileToValue(f)
99+
func selectStrings(value DaselValue, expr string) ([]string, error) {
100+
selected, _, err := dasel.Select(context.Background(), value, expr)
110101
if err != nil {
111-
return nil, err
102+
return selectStringsV2(value, expr)
112103
}
113104

114-
for _, s := range b.Scopes {
115-
selected, _, verr := dasel.Select(context.Background(), value, s.Expr)
116-
if verr != nil {
117-
// We failed; try to see if the old version of dasel can handle it.
118-
v2found, v2err := b.ApplyV2(f)
119-
if v2err != nil {
120-
// If the old version also fails, return the original error.
121-
return nil, verr
122-
}
123-
return v2found, nil
105+
outer, ok := selected.([]any)
106+
if !ok {
107+
return nil, fmt.Errorf("expected []any, got %T", selected)
108+
}
109+
110+
// Unwrap single-element wrapper if present.
111+
if len(outer) == 1 {
112+
if inner, ok := outer[0].([]any); ok {
113+
outer = inner
124114
}
115+
}
125116

126-
if selectResults, ok := selected.([]any); ok {
127-
if len(selectResults) == 1 {
128-
if inner, iok := selectResults[0].([]any); iok {
129-
selectResults = inner
130-
}
131-
} else {
132-
return nil, fmt.Errorf("unexpected result type for scope %s: expected array, got %T", s.Name, selected)
133-
}
134-
135-
values := []string{}
136-
for _, v := range selectResults {
137-
if str, sok := v.(string); sok {
138-
values = append(values, str)
139-
}
140-
}
141-
142-
found = append(found, ScopedValues{
143-
Scope: s.Name,
144-
Values: values,
145-
Format: s.Type,
146-
})
117+
results := make([]string, 0, len(outer))
118+
for _, v := range outer {
119+
if str, ok := v.(string); ok {
120+
results = append(results, str)
147121
}
148122
}
123+
return results, nil
124+
}
149125

150-
return found, nil
126+
func selectStringsV2(value DaselValue, expr string) ([]string, error) {
127+
selected, err := v2dasel.Select(value, expr)
128+
if err != nil {
129+
return nil, err
130+
}
131+
results := make([]string, 0, len(selected))
132+
for _, v := range selected {
133+
results = append(results, v.String())
134+
}
135+
return results, nil
136+
}
137+
138+
// normalize recursively converts map[interface{}]interface{} (produced by
139+
// gopkg.in/yaml.v2) to map[string]any so that Dasel v3 can traverse the
140+
// document without choking on interface{} map keys.
141+
func normalize(v any) any {
142+
switch v := v.(type) {
143+
case map[interface{}]interface{}:
144+
out := make(map[string]any, len(v))
145+
for k, val := range v {
146+
out[fmt.Sprintf("%v", k)] = normalize(val)
147+
}
148+
return out
149+
case map[string]any:
150+
out := make(map[string]any, len(v))
151+
for k, val := range v {
152+
out[k] = normalize(val)
153+
}
154+
return out
155+
case []any:
156+
out := make([]any, len(v))
157+
for i, val := range v {
158+
out[i] = normalize(val)
159+
}
160+
return out
161+
default:
162+
return v
163+
}
151164
}
152165

153166
func fileToValue(f *File) (DaselValue, error) {
154-
var value DaselValue
167+
var raw any
155168

156169
// We replace block chomping indicators with a pipe to ensure that
157170
// newlines are preserved.
@@ -164,23 +177,28 @@ func fileToValue(f *File) (DaselValue, error) {
164177
contents := []byte(text)
165178
switch f.RealExt {
166179
case ".json":
167-
err := json.Unmarshal(contents, &value)
180+
err := json.Unmarshal(contents, &raw)
168181
if err != nil {
169182
return nil, err
170183
}
171184
case ".yml", ".yaml":
172-
err := yaml.Unmarshal(contents, &value)
185+
err := yaml.Unmarshal(contents, &raw)
173186
if err != nil {
174187
return nil, err
175188
}
176189
case ".toml":
177-
err := toml.Unmarshal(contents, &value)
190+
err := toml.Unmarshal(contents, &raw)
178191
if err != nil {
179192
return nil, err
180193
}
181194
default:
182195
return nil, errors.New("unsupported file type")
183196
}
184197

198+
value, ok := normalize(raw).(map[string]any)
199+
if !ok {
200+
return nil, errors.New("document root is not an object")
201+
}
202+
185203
return value, nil
186204
}

testdata/features/views.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Feature: Views
99
API.yml:9:70:Vale.Spelling:Did you really mean 'serrver'?
1010
API.yml:13:24:Vale.Spelling:Did you really mean 'serrver'?
1111
API.yml:15:70:Vale.Spelling:Did you really mean 'serrver'?
12+
API.yml:20:48:Vale.Spelling:Did you really mean 'servver'?
1213
Petstore.yaml:15:18:Vale.Spelling:Did you really mean 'Petstore'?
1314
Petstore.yaml:29:28:Vale.Spelling:Did you really mean 'Petstore'?
1415
Petstore.yaml:407:17:Vale.Spelling:Did you really mean 'nonintegers'?

testdata/fixtures/views/API.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ servers:
1717
paths:
1818
/users:
1919
get:
20-
summary: Returns a list of users.
20+
summary: Returns a list of users for the servver.
2121
description: Optional extended description in CommonMark or HTML.
2222
responses:
2323
"200": # status code
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
engine: dasel
22
scopes:
3-
- name: title
4-
expr: info.title
3+
- expr: info.title
4+
name: title
55

6-
- expr: info.description
6+
- expr: 'search(has("description")).map(description)'
7+
name: description
78
type: md
89

9-
- expr: servers.all().description
10+
- expr: 'search(has("summary")).map(summary)'
11+
name: summary
1012
type: md

0 commit comments

Comments
 (0)