Skip to content

Commit

Permalink
internal/cmd/cue-ast: add "join" command
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
mvdan committed Sep 9, 2024
1 parent ae5dfea commit 62b3cfa
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions internal/cmd/cue-ast/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ import (
"fmt"
"log"
"os"
"slices"

"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/format"
"cuelang.org/go/cue/load"
"cuelang.org/go/internal/astinternal"
)
Expand All @@ -39,6 +43,11 @@ usage of cue-ast:
-omitempty omit empty and invalid values
cue-ast join [flags] [inputs]
Join the input package instance as a single file.
Joining multiple package instances is not supported yet.
See 'cue help inputs' as well.
`[1:])
}
Expand Down Expand Up @@ -71,6 +80,42 @@ See 'cue help inputs' as well.
os.Stdout.Write(out)
}
}
case "join":
// TODO: add a flag drop comments, which is useful when reducing bug reproducers.
flag.CommandLine.Parse(args)

var jointImports []*ast.ImportSpec
var jointFields []ast.Decl
insts := load.Instances(flag.Args(), &load.Config{})
if len(insts) != 1 {
log.Fatal("joining multiple instances is not possible yet")
}
inst := insts[0]
if err := inst.Err; err != nil {
log.Fatal(errors.Details(err, nil))
}
for _, file := range inst.Files {
jointImports = slices.Concat(jointImports, file.Imports)

fields := file.Decls[len(file.Preamble()):]
jointFields = slices.Concat(jointFields, fields)
}
// TODO: we should sort and deduplicate imports.
joint := &ast.File{Decls: slices.Concat([]ast.Decl{
&ast.ImportDecl{Specs: jointImports},
}, jointFields)}

// Sanitize the resulting file so that, for example,
// multiple packages imported as the same name avoid collisions.
if err := astutil.Sanitize(joint); err != nil {
log.Fatal(err)
}

out, err := format.Node(joint)
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(out)
default:
flag.Usage()
}
Expand Down

0 comments on commit 62b3cfa

Please sign in to comment.