cue get go

CUE v0.18.0

add Go dependencies to the current module

Usage

cue get go [flags] [packages]

go converts Go types into CUE definitions

The command "cue get go" is like "go get", but converts the retrieved Go packages to CUE. The retrieved packages are put in the CUE module's pkg directory at the import path of the corresponding Go package. The converted definitions are available to any CUE file within the CUE module by using this import path.

The Go type definitions are converted to CUE based on how they would be interpreted by Go's encoding/json package. Definitions for a Go file foo.go are written to a CUE file named foo_go_gen.cue.

It is safe for users to add additional files to the generated directories, as long as their name does not end with _gen.*.

Rules of Converting Go types to CUE

Go structs are converted to cue structs adhering to the following conventions:

	- field names are translated based on the definition of a "json" or "yaml"
	  tag, in that order. A --codec flag can be used to change the priority of
	  the tag search.
	- the tag found for a field also decides how it is encoded: the field
	  is optional if the tag has an "omitempty" or "omitzero" option, and
	  a pointer field is not nullable if it is a "toml" tag, as TOML has no
	  null. Fields without any such tag follow the first codec.
	- embedded structs marked with a json inline tag unify with struct
	  definition. For instance, the Go struct
	    struct MyStruct {
			Common  json:",inline"
			Field string
		 }
	  translates to the CUE struct
		 #MyStruct: Common & {
			 Field: string
		 }
	- a type that implements MarshalJSON, UnmarshalJSON, MarshalYAML, or
	  UnmarshalYAML is translated to top (_) to indicate it may be any
	  value. For some Go core types for which the implementation of these
	  methods is known, like time.Time, the type may be more specific.
	- a type implementing MarshalText or UnmarshalText is represented as
	  the CUE type string
	- slices and arrays convert to CUE lists, except when the element type is
	  byte, in which case it translates to the CUE bytes type.
	  In the case of arrays, the length of the CUE value is constrained
	  accordingly, when possible.
	- Maps translate to a CUE struct, where all elements are constrained to
	  be of Go map element type. Like for JSON, map keys must be strings,
	  integers, or types implementing MarshalText or UnmarshalText, and are
	  all translated to string labels.
	- Pointers translate to a sum type with the default value of null and
	  the Go type as an alternative value.
	- Field tags are translated to CUE's field attributes. In some cases,
	  the contents are rewritten to reflect the corresponding types in CUE.
	  The @go attribute is added if the field name or type definition differs
	  between the generated CUE and the original Go.

Native CUE Constraints

Native CUE constraints may be defined in separate cue files alongside the generated files either in the original Go directory or in the generated directory. These files can impose additional constraints on types and values that are not otherwise expressible in Go. The package name for these CUE files must be the same as that of the Go package.

For instance, for the type

	package foo
	type IP4String string

defined in the Go package, one could add a cue file foo.cue with the following contents to allow IP4String to assume only valid IP4 addresses:

	package foo
	// IP4String defines a valid IP4 address.
	#IP4String: =~#"^\#(byte)\.\#(byte)\.\#(byte)\.\#(byte)$"#
	// byte defines string allowing integer values of 0-255.
	byte = #"([01]?\d?\d|2[0-4]\d|25[0-5])"#

The "cue get go" command copies any cue files in the original Go package directory that has a package clause with the same name as the Go package to the destination directory, replacing its .cue ending with _gen.cue.

Alternatively, the additional native constraints can be added to the generated package, as long as the file name does not end with _gen.cue. Running cue get go again to regenerate the package will never overwrite any files not ending with _gen.*.

Constants and Enums

Go does not have an enum or sum type. Conventionally, a type that is supposed to be an enum is followed by a const block with the allowed values for that type. However, as that is only a guideline and not a hard rule, these cases cannot be translated to CUE disjunctions automatically.

Constant values, however, are generated in a way that makes it easy to convert a type to a proper enum using native CUE constraints. For instance, the Go type

	package foo
	type Switch int
	const (
		Off Switch = iota
		On
	)

translates into the following CUE definitions:

	package foo
	#Switch: int // #enumSwitch
	#enumSwitch: Off | On
	Off: 0
	On:  1

This definition allows any integer value for #Switch, while the #enumSwitch value defines all defined constants for Switch and thus all valid values if #Switch were to be interpreted as an enum type. To turn #Switch into an enum, include the following constraint in, say, enum.cue, in either the original source directory or the generated directory:

	package foo
	// limit the valid values for Switch to those existing as constants with
	// the same type.
	#Switch: #enumSwitch

This tells CUE that only the values enumerated by #enumSwitch are valid values for #Switch. Note that there are now two definitions of #Switch. CUE handles this in the usual way by unifying the two definitions, in which case the more restrictive enum interpretation of #Switch remains.

Flags

--codec string                     comma-separated priority list of struct tags to use for field names
-e, --exclude string               comma-separated list of regexps of identifiers to omit
--local                            generates files in the main module locally
--outfile string                   generate one CUE file for a single Go package
-p, --package string               package name for generated CUE files
-v, --verbose                      print information about progress

Global flags

-E, --all-errors                   print all available errors
-C, --chdir string                 change working directory before running command (must be the first flag)
-i, --ignore                       proceed in the presence of errors
-s, --simplify                     simplify output
Install CUE