Skip to content

Commit 62b3cfa

Browse files
committed
internal/cmd/cue-ast: add "join" command
When reducing CUE bug reproducers, I often begin from the evaluation of a CUE package instance. It is easier to reduce a single CUE file rather than multiple files, as one can load it into an editor and quickly delete chunks of it or search through it. While this is not hard to do, it's tedious for a human; the package declarations need to be removed, and the imports joined at the top of the new file. This is, however, easy to do in Go. Signed-off-by: Daniel Martí <[email protected]> Change-Id: Ibf89de45ae6ec5d88037f7417d00aa2129cd73e0 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1200356 Reviewed-by: Roger Peppe <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent ae5dfea commit 62b3cfa

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

internal/cmd/cue-ast/main.go

+45
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ import (
2222
"fmt"
2323
"log"
2424
"os"
25+
"slices"
2526

27+
"cuelang.org/go/cue/ast"
28+
"cuelang.org/go/cue/ast/astutil"
2629
"cuelang.org/go/cue/errors"
30+
"cuelang.org/go/cue/format"
2731
"cuelang.org/go/cue/load"
2832
"cuelang.org/go/internal/astinternal"
2933
)
@@ -39,6 +43,11 @@ usage of cue-ast:
3943
4044
-omitempty omit empty and invalid values
4145
46+
cue-ast join [flags] [inputs]
47+
48+
Join the input package instance as a single file.
49+
Joining multiple package instances is not supported yet.
50+
4251
See 'cue help inputs' as well.
4352
`[1:])
4453
}
@@ -71,6 +80,42 @@ See 'cue help inputs' as well.
7180
os.Stdout.Write(out)
7281
}
7382
}
83+
case "join":
84+
// TODO: add a flag drop comments, which is useful when reducing bug reproducers.
85+
flag.CommandLine.Parse(args)
86+
87+
var jointImports []*ast.ImportSpec
88+
var jointFields []ast.Decl
89+
insts := load.Instances(flag.Args(), &load.Config{})
90+
if len(insts) != 1 {
91+
log.Fatal("joining multiple instances is not possible yet")
92+
}
93+
inst := insts[0]
94+
if err := inst.Err; err != nil {
95+
log.Fatal(errors.Details(err, nil))
96+
}
97+
for _, file := range inst.Files {
98+
jointImports = slices.Concat(jointImports, file.Imports)
99+
100+
fields := file.Decls[len(file.Preamble()):]
101+
jointFields = slices.Concat(jointFields, fields)
102+
}
103+
// TODO: we should sort and deduplicate imports.
104+
joint := &ast.File{Decls: slices.Concat([]ast.Decl{
105+
&ast.ImportDecl{Specs: jointImports},
106+
}, jointFields)}
107+
108+
// Sanitize the resulting file so that, for example,
109+
// multiple packages imported as the same name avoid collisions.
110+
if err := astutil.Sanitize(joint); err != nil {
111+
log.Fatal(err)
112+
}
113+
114+
out, err := format.Node(joint)
115+
if err != nil {
116+
log.Fatal(err)
117+
}
118+
os.Stdout.Write(out)
74119
default:
75120
flag.Usage()
76121
}

0 commit comments

Comments
 (0)