Skip to content

cmd/cue: Add --skip-imports, --keep-empty, --out to get go #4108

@fionera

Description

@fionera

Is your feature request related to a problem? Please describe.
As an advanced User relying on Bazel, I want to generate schemas for each packages separately. As Bazel requires to know which files will be created I want to generate a .cue file for every input file even when it would be empty. Additionally I do have to explicity tell the command where to write the output to, since everything would run in a sandbox with very tight permissions.

Describe the solution you'd like
A --skip-imports, --keep-empty and --out flag would be the easiest solution.

Describe alternatives you've considered
Numerous things. Generating empty files to overwrite, trying to guess which files will be generated, deleting unused files. Sadly the --out support is requires as I can't find a way to control it in another way.

Additional context
This is the patch I am currently using

diff --git a/cmd/cue/cmd/get_go.go b/cmd/cue/cmd/get_go.go
index 2a81dbdd..9e0c8250 100644
--- a/cmd/cue/cmd/get_go.go
+++ b/cmd/cue/cmd/get_go.go
@@ -45,6 +45,16 @@ import (
 	"cuelang.org/go/internal"
 )
 
+func init() {
+	// Add `go` to PATH for x/go/packages.
+	if goRoot, ok := os.LookupEnv("GOROOT"); ok {
+		goRoot, _ = filepath.Abs(goRoot)
+		goBin := filepath.Join(goRoot, "bin")
+		os.Setenv("GOROOT", goRoot)
+		os.Setenv("PATH", goBin)
+	}
+}
+
 // TODO:
 // Document:
 // - Use ast package.
@@ -216,14 +226,25 @@ restrictive enum interpretation of #Switch remains.
 	cmd.Flags().Bool(string(flagLocal), false,
 		"generates files in the main module locally")
 
+	cmd.Flags().Bool(string(flagSkipImports), false,
+		"generates files without generating recursive through imports")
+
+	cmd.Flags().Bool(string(flagKeepEmpty), false,
+		"generates all files even if they would be empty")
+
+	cmd.Flags().String(string(flagOut), "",
+		"The directory to write the generated files to")
+
 	cmd.Flags().StringP(string(flagPackage), "p", "", "package name for generated CUE files")
 
 	return cmd
 }
 
 const (
-	flagExclude flagName = "exclude"
-	flagLocal   flagName = "local"
+	flagExclude     flagName = "exclude"
+	flagLocal       flagName = "local"
+	flagSkipImports flagName = "skip-imports"
+	flagKeepEmpty   flagName = "keep-empty"
 )
 
 func (e *extractor) initExclusions(str string) {
@@ -247,8 +268,9 @@ func (e *extractor) filter(name string) bool {
 type extractor struct {
 	cmd *Command
 
-	allPkgs map[string]*packages.Package
-	done    map[string]bool
+	allPkgs  map[string]*packages.Package
+	done     map[string]bool
+	rootPkgs map[string]bool
 
 	// per package
 	pkg      *packages.Package
@@ -406,9 +428,11 @@ func extract(cmd *Command, args []string) error {
 	e.initExclusions(flagExclude.String(cmd))
 
 	e.done = map[string]bool{}
+	e.rootPkgs = map[string]bool{}
 
 	for _, p := range pkgs {
 		e.done[p.PkgPath] = true
+		e.rootPkgs[p.PkgPath] = true
 		e.addPackage(p)
 	}
 
@@ -463,6 +487,9 @@ func (e *extractor) extractPkg(root string, p *packages.Package) error {
 
 	pkg := p.PkgPath
 	dir := filepath.Join(load.GenPath(root), filepath.FromSlash(pkg))
+	if out := flagOut.String(e.cmd); out != "" {
+		dir = out
+	}
 
 	isMain := flagLocal.Bool(e.cmd) && p.Module != nil && p.Module.Main
 	if isMain {
@@ -513,7 +540,11 @@ func (e *extractor) extractPkg(root string, p *packages.Package) error {
 			}
 		}
 
-		if len(decls) == 0 && f.Doc == nil {
+		if !e.rootPkgs[p.PkgPath] && flagSkipImports.Bool(e.cmd) {
+			continue
+		}
+
+		if len(decls) == 0 && f.Doc == nil && !flagKeepEmpty.Bool(e.cmd) {
 			continue
 		}
 

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions