[![Build Status](https://travis-ci.org/dave/jennifer.svg?branch=master)](https://travis-ci.org/dave/jennifer) [![Go Report Card](https://goreportcard.com/badge/github.com/dave/jennifer)](https://goreportcard.com/report/github.com/dave/jennifer) [![codecov](https://img.shields.io/badge/codecov-100%25-brightgreen.svg)](https://codecov.io/gh/dave/jennifer) ![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg) [![Sourcegraph](https://sourcegraph.com/github.com/dave/jennifer/jen/-/badge.svg)](https://sourcegraph.com/github.com/dave/jennifer?badge) # Jennifer Jennifer is a code generator for Go. ```go package main import ( "fmt" . "github.com/dave/jennifer/jen" ) func main() { f := NewFile("main") f.Func().Id("main").Params().Block( Qual("fmt", "Println").Call(Lit("Hello, world")), ) fmt.Printf("%#v", f) } ``` Output: ```go package main import "fmt" func main() { fmt.Println("Hello, world") } ``` ### Install ``` go get -u github.com/dave/jennifer/jen ``` ### Need help? If you get stuck, have a question, would like a code review, or just want a chat: I'm happy to help! Feel free to open an issue, email me or mention @dave in your PR. ### Examples Jennifer has a comprehensive suite of examples - see [godoc](https://godoc.org/github.com/dave/jennifer/jen#pkg-examples) for an index. Here's some examples of jennifer being used in the real-world: * [genjen](genjen/render.go) (which generates much of jennifer, using data in [data.go](genjen/data.go)) * [zerogen](https://github.com/mrsinham/zerogen/blob/master/generator.go) * [go-contentful-generator](https://github.com/nicolai86/go-contentful-generator) ### Rendering For testing, a File or Statement can be rendered with the fmt package using the %#v verb. ```go c := Id("a").Call(Lit("b")) fmt.Printf("%#v", c) // Output: // a("b") ``` This is not recommended for use in production because any error will cause a panic. For production use, [File.Render](#render) or [File.Save](#save) are preferred. # Identifiers **Identifiers** [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) ### Id Id renders an identifier. ```go c := If(Id("i").Op("==").Id("j")).Block( Return(Id("i")), ) fmt.Printf("%#v", c) // Output: // if i == j { // return i // } ``` ### Dot Dot renders a period followed by an identifier. Use for fields and selectors. ```go c := Qual("a.b/c", "Foo").Call().Dot("Bar").Index(Lit(0)).Dot("Baz") fmt.Printf("%#v", c) // Output: // c.Foo().Bar[0].Baz ``` ### Qual Qual renders a qualified identifier. ```go c := Qual("encoding/gob", "NewEncoder").Call() fmt.Printf("%#v", c) // Output: // gob.NewEncoder() ``` Imports are automatically added when used with a File. If the path matches the local path, the package name is omitted. If package names conflict they are automatically renamed. ```go f := NewFilePath("a.b/c") f.Func().Id("init").Params().Block( Qual("a.b/c", "Foo").Call().Comment("Local package - name is omitted."), Qual("d.e/f", "Bar").Call().Comment("Import is automatically added."), Qual("g.h/f", "Baz").Call().Comment("Colliding package name is renamed."), ) fmt.Printf("%#v", f) // Output: // package c // // import ( // f "d.e/f" // f1 "g.h/f" // ) // // func init() { // Foo() // Local package - name is omitted. // f.Bar() // Import is automatically added. // f1.Baz() // Colliding package name is renamed. // } ``` Note that it is not possible to reliably determine the package name given an arbitrary package path, so a sensible name is guessed from the path and added as an alias. The names of all standard library packages are known so these do not need to be aliased. If more control is needed of the aliases, see [File.ImportName](#importname) or [File.ImportAlias](#importalias). ### List List renders a comma separated list. Use for multiple return functions. ```go c := List(Id("a"), Err()).Op(":=").Id("b").Call() fmt.Printf("%#v", c) // Output: // a, err := b() ``` # Keywords [Identifiers](#identifiers) **Keywords** [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) Simple keywords, predeclared identifiers and built-in functions are self explanatory: | Construct | Name | | ---------------- | ---- | | Keywords | Break, Chan, Const, Continue, Default, Defer, Else, Fallthrough, Func, Go, Goto, Range, Select, Type, Var | | Functions | Append, Cap, Close, Complex, Copy, Delete, Imag, Len, Make, New, Panic, Print, Println, Real, Recover | | Types | Bool, Byte, Complex64, Complex128, Error, Float32, Float64, Int, Int8, Int16, Int32, Int64, Rune, String, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr | | Constants | True, False, Iota, Nil | | Helpers | Err | Built-in functions take a list of parameters and render them appropriately: ```go c := Id("a").Op("=").Append(Id("a"), Id("b").Op("...")) fmt.Printf("%#v", c) // Output: // a = append(a, b...) ``` Special cases for [If, For](#if-for), [Interface, Struct](#interface-struct), [Switch, Case](#switch-select), [Return](#return) and [Map](#map) are explained below. # Operators [Identifiers](#identifiers) [Keywords](#keywords) **Operators** [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) Op renders the provided operator / token. ```go c := Id("a").Op(":=").Id("b").Call() fmt.Printf("%#v", c) // Output: // a := b() ``` ```go c := Id("a").Op("=").Op("*").Id("b") fmt.Printf("%#v", c) // Output: // a = *b ``` ```go c := Id("a").Call(Id("b").Op("...")) fmt.Printf("%#v", c) // Output: // a(b...) ``` ```go c := If(Parens(Id("a").Op("||").Id("b")).Op("&&").Id("c")).Block() fmt.Printf("%#v", c) // Output: // if (a || b) && c { // } ``` # Braces [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) **Braces** [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) Several methods render curly braces, summarized below: | Name | Prefix | Separator | Example | | ------------------------------ | ------------ | --------- | -------------------------------------| | [Block](#block) | | `\n` | `func a() { ... }` or `if a { ... }` | | [Interface](#interface-struct) | `interface` | `\n` | `interface { ... }` | | [Struct](#interface-struct) | `struct` | `\n` | `struct { ... }` | | [Values](#values) | | `,` | `[]int{1, 2}` or `A{B: "c"}` | ### Block Block renders a statement list enclosed by curly braces. Use for code blocks. ```go c := Func().Id("foo").Params().String().Block( Id("a").Op("=").Id("b"), Id("b").Op("++"), Return(Id("b")), ) fmt.Printf("%#v", c) // Output: // func foo() string { // a = b // b++ // return b // } ``` ```go c := If(Id("a").Op(">").Lit(10)).Block( Id("a").Op("=").Id("a").Op("/").Lit(2), ) fmt.Printf("%#v", c) // Output: // if a > 10 { // a = a / 2 // } ``` A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. [See example](#switch-select). ### Interface, Struct Interface and Struct render the keyword followed by a statement list enclosed by curly braces. ```go c := Var().Id("a").Interface() fmt.Printf("%#v", c) // Output: // var a interface{} ``` ```go c := Type().Id("a").Interface( Id("b").Params().String(), ) fmt.Printf("%#v", c) // Output: // type a interface { // b() string // } ``` ```go c := Id("c").Op(":=").Make(Chan().Struct()) fmt.Printf("%#v", c) // Output: // c := make(chan struct{}) ``` ```go c := Type().Id("foo").Struct( List(Id("x"), Id("y")).Int(), Id("u").Float32(), ) fmt.Printf("%#v", c) // Output: // type foo struct { // x, y int // u float32 // } ``` # Parentheses [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) **Parentheses** [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) Several methods output parenthesis, summarized below: | Name | Prefix | Separator | Example | | ----------------- | ------ | --------- | --------------------------------- | | [Call](#call) | | `,` | `fmt.Println(b, c)` | | [Params](#params) | | `,` | `func (a *A) Foo(i int) { ... }` | | [Defs](#defs) | | `\n` | `const ( ... )` | | [Parens](#parens) | | | `[]byte(s)` or `a / (b + c)` | | [Assert](#assert) | `.` | | `s, ok := i.(string)` | ### Call Call renders a comma separated list enclosed by parenthesis. Use for function calls. ```go c := Qual("fmt", "Printf").Call( Lit("%#v: %T\n"), Id("a"), Id("b"), ) fmt.Printf("%#v", c) // Output: // fmt.Printf("%#v: %T\n", a, b) ``` ### Params Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers. ```go c := Func().Params( Id("a").Id("A"), ).Id("foo").Params( Id("b"), Id("c").String(), ).String().Block( Return(Id("b").Op("+").Id("c")), ) fmt.Printf("%#v", c) // Output: // func (a A) foo(b, c string) string { // return b + c // } ``` ### Defs Defs renders a statement list enclosed in parenthesis. Use for definition lists. ```go c := Const().Defs( Id("a").Op("=").Lit("a"), Id("b").Op("=").Lit("b"), ) fmt.Printf("%#v", c) // Output: // const ( // a = "a" // b = "b" // ) ``` ### Parens Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order. ```go c := Id("b").Op(":=").Index().Byte().Parens(Id("s")) fmt.Printf("%#v", c) // Output: // b := []byte(s) ``` ```go c := Id("a").Op("/").Parens(Id("b").Op("+").Id("c")) fmt.Printf("%#v", c) // Output: // a / (b + c) ``` ### Assert Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions. ```go c := List(Id("b"), Id("ok")).Op(":=").Id("a").Assert(Bool()) fmt.Printf("%#v", c) // Output: // b, ok := a.(bool) ``` # Control flow [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) **Control flow** [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) ### If, For If and For render the keyword followed by a semicolon separated list. ```go c := If( Err().Op(":=").Id("a").Call(), Err().Op("!=").Nil(), ).Block( Return(Err()), ) fmt.Printf("%#v", c) // Output: // if err := a(); err != nil { // return err // } ``` ```go c := For( Id("i").Op(":=").Lit(0), Id("i").Op("<").Lit(10), Id("i").Op("++"), ).Block( Qual("fmt", "Println").Call(Id("i")), ) fmt.Printf("%#v", c) // Output: // for i := 0; i < 10; i++ { // fmt.Println(i) // } ``` ### Switch, Select Switch, Select, Case and Block are used to build switch or select statements: ```go c := Switch(Id("value").Dot("Kind").Call()).Block( Case(Qual("reflect", "Float32"), Qual("reflect", "Float64")).Block( Return(Lit("float")), ), Case(Qual("reflect", "Bool")).Block( Return(Lit("bool")), ), Case(Qual("reflect", "Uintptr")).Block( Fallthrough(), ), Default().Block( Return(Lit("none")), ), ) fmt.Printf("%#v", c) // Output: // switch value.Kind() { // case reflect.Float32, reflect.Float64: // return "float" // case reflect.Bool: // return "bool" // case reflect.Uintptr: // fallthrough // default: // return "none" // } ``` ### Return Return renders the keyword followed by a comma separated list. ```go c := Return(Id("a"), Id("b")) fmt.Printf("%#v", c) // Output: // return a, b ``` # Collections [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) **Collections** [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) ### Map Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions. ```go c := Id("a").Op(":=").Map(String()).String().Values() fmt.Printf("%#v", c) // Output: // a := map[string]string{} ``` ### Index Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions. ```go c := Var().Id("a").Index().String() fmt.Printf("%#v", c) // Output: // var a []string ``` ```go c := Id("a").Op(":=").Id("b").Index(Lit(0), Lit(1)) fmt.Printf("%#v", c) // Output: // a := b[0:1] ``` ```go c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty()) fmt.Printf("%#v", c) // Output: // a := b[1:] ``` ### Values Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals. ```go c := Index().String().Values(Lit("a"), Lit("b")) fmt.Printf("%#v", c) // Output: // []string{"a", "b"} ``` Dict renders as key/value pairs. Use with Values for map or composite literals. ```go c := Map(String()).String().Values(Dict{ Lit("a"): Lit("b"), Lit("c"): Lit("d"), }) fmt.Printf("%#v", c) // Output: // map[string]string{ // "a": "b", // "c": "d", // } ``` ```go c := Op("&").Id("Person").Values(Dict{ Id("Age"): Lit(1), Id("Name"): Lit("a"), }) fmt.Printf("%#v", c) // Output: // &Person{ // Age: 1, // Name: "a", // } ``` DictFunc executes a func(Dict) to generate the value. ```go c := Id("a").Op(":=").Map(String()).String().Values(DictFunc(func(d Dict) { d[Lit("a")] = Lit("b") d[Lit("c")] = Lit("d") })) fmt.Printf("%#v", c) // Output: // a := map[string]string{ // "a": "b", // "c": "d", // } ``` Note: the items are ordered by key when rendered to ensure repeatable code. # Literals [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) **Literals** [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file) ### Lit Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64, float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64). Passing any other type will panic. ```go c := Id("a").Op(":=").Lit("a") fmt.Printf("%#v", c) // Output: // a := "a" ``` ```go c := Id("a").Op(":=").Lit(1.5) fmt.Printf("%#v", c) // Output: // a := 1.5 ``` LitFunc generates the value to render by executing the provided function. ```go c := Id("a").Op(":=").LitFunc(func() interface{} { return 1 + 1 }) fmt.Printf("%#v", c) // Output: // a := 2 ``` For the default constant types (bool, int, float64, string, complex128), Lit will render the untyped constant. | Code | Output | | ------------- | ---------- | | `Lit(true)` | `true` | | `Lit(1)` | `1` | | `Lit(1.0)` | `1.0` | | `Lit("foo")` | `"foo"` | | `Lit(0 + 1i)` | `(0 + 1i)` | For all other built-in types (float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, complex64), Lit will also render the type. | Code | Output | | ------------------------ | ------------------- | | `Lit(float32(1))` | `float32(1)` | | `Lit(int16(1))` | `int16(1)` | | `Lit(uint8(0x1))` | `uint8(0x1)` | | `Lit(complex64(0 + 1i))` | `complex64(0 + 1i)` | The built-in alias types byte and rune need a special case. LitRune and LitByte render rune and byte literals. | Code | Output | | ------------------------ | ----------- | | `LitRune('x')` | `'x'` | | `LitByte(byte(0x1))` | `byte(0x1)` | # Comments [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) **Comments** [Helpers](#helpers) [Misc](#misc) [File](#file) ### Comment Comment adds a comment. If the provided string contains a newline, the comment is formatted in multiline style. ```go f := NewFile("a") f.Comment("Foo returns the string \"foo\"") f.Func().Id("Foo").Params().String().Block( Return(Lit("foo")).Comment("return the string foo"), ) fmt.Printf("%#v", f) // Output: // package a // // // Foo returns the string "foo" // func Foo() string { // return "foo" // return the string foo // } ``` ```go c := Comment("a\nb") fmt.Printf("%#v", c) // Output: // /* // a // b // */ ``` If the comment string starts with "//" or "/*", the automatic formatting is disabled and the string is rendered directly. ```go c := Id("foo").Call(Comment("/* inline */")).Comment("//no-space") fmt.Printf("%#v", c) // Output: // foo( /* inline */ ) //no-space ``` ### Commentf Commentf adds a comment, using a format string and a list of parameters. ```go name := "foo" val := "bar" c := Id(name).Op(":=").Lit(val).Commentf("%s is the string \"%s\"", name, val) fmt.Printf("%#v", c) // Output: // foo := "bar" // foo is the string "bar" ``` # Helpers [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) **Helpers** [Misc](#misc) [File](#file) ### Func methods All constructs that accept a variadic list of items are paired with GroupFunc functions that accept a func(*Group). Use for embedding logic. ```go c := Id("numbers").Op(":=").Index().Int().ValuesFunc(func(g *Group) { for i := 0; i <= 5; i++ { g.Lit(i) } }) fmt.Printf("%#v", c) // Output: // numbers := []int{0, 1, 2, 3, 4, 5} ``` ```go increment := true name := "a" c := Func().Id("a").Params().BlockFunc(func(g *Group) { g.Id(name).Op("=").Lit(1) if increment { g.Id(name).Op("++") } else { g.Id(name).Op("--") } }) fmt.Printf("%#v", c) // Output: // func a() { // a = 1 // a++ // } ``` ### Add Add appends the provided items to the statement. ```go ptr := Op("*") c := Id("a").Op("=").Add(ptr).Id("b") fmt.Printf("%#v", c) // Output: // a = *b ``` ```go a := Id("a") i := Int() c := Var().Add(a, i) fmt.Printf("%#v", c) // Output: // var a int ``` ### Do Do calls the provided function with the statement as a parameter. Use for embedding logic. ```go f := func(name string, isMap bool) *Statement { return Id(name).Op(":=").Do(func(s *Statement) { if isMap { s.Map(String()).String() } else { s.Index().String() } }).Values() } fmt.Printf("%#v\n%#v", f("a", true), f("b", false)) // Output: // a := map[string]string{} // b := []string{} ``` # Misc [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) **Misc** [File](#file) ### Tag Tag renders a struct tag ```go c := Type().Id("foo").Struct( Id("A").String().Tag(map[string]string{"json": "a"}), Id("B").Int().Tag(map[string]string{"json": "b", "bar": "baz"}), ) fmt.Printf("%#v", c) // Output: // type foo struct { // A string `json:"a"` // B int `bar:"baz" json:"b"` // } ``` Note: the items are ordered by key when rendered to ensure repeatable code. ### Null Null adds a null item. Null items render nothing and are not followed by a separator in lists. In lists, nil will produce the same effect. ```go c := Func().Id("foo").Params( nil, Id("s").String(), Null(), Id("i").Int(), ).Block() fmt.Printf("%#v", c) // Output: // func foo(s string, i int) {} ``` ### Empty Empty adds an empty item. Empty items render nothing but are followed by a separator in lists. ```go c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty()) fmt.Printf("%#v", c) // Output: // a := b[1:] ``` ### Line Line inserts a blank line. ### Clone Be careful when passing *Statement. Consider the following... ```go a := Id("a") c := Block( a.Call(), a.Call(), ) fmt.Printf("%#v", c) // Output: // { // a()() // a()() // } ``` Id("a") returns a *Statement, which the Call() method appends to twice. To avoid this, use Clone. Clone makes a copy of the Statement, so further tokens can be appended without affecting the original. ```go a := Id("a") c := Block( a.Clone().Call(), a.Clone().Call(), ) fmt.Printf("%#v", c) // Output: // { // a() // a() // } ``` ### Cgo The cgo "C" pseudo-package is a special case, and always renders without a package alias. The import can be added with `Qual`, `Anon` or by supplying a preamble. The preamble is added with `File.CgoPreamble` which has the same semantics as [Comment](#comments). If a preamble is provided, the import is separated, and preceded by the preamble. ```go f := NewFile("a") f.CgoPreamble(`#include #include void myprint(char* s) { printf("%s\n", s); } `) f.Func().Id("init").Params().Block( Id("cs").Op(":=").Qual("C", "CString").Call(Lit("Hello from stdio\n")), Qual("C", "myprint").Call(Id("cs")), Qual("C", "free").Call(Qual("unsafe", "Pointer").Parens(Id("cs"))), ) fmt.Printf("%#v", f) // Output: // package a // // import "unsafe" // // /* // #include // #include // // void myprint(char* s) { // printf("%s\n", s); // } // */ // import "C" // // func init() { // cs := C.CString("Hello from stdio\n") // C.myprint(cs) // C.free(unsafe.Pointer(cs)) // } ``` # File [Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) **File** File represents a single source file. Package imports are managed automaticaly by File. ### NewFile NewFile Creates a new file, with the specified package name. ### NewFilePath NewFilePath creates a new file while specifying the package path - the package name is inferred from the path. ### NewFilePathName NewFilePathName creates a new file with the specified package path and name. ```go f := NewFilePathName("a.b/c", "main") f.Func().Id("main").Params().Block( Qual("a.b/c", "Foo").Call(), ) fmt.Printf("%#v", f) // Output: // package main // // func main() { // Foo() // } ``` ### Save Save renders the file and saves to the filename provided. ### Render Render renders the file to the provided writer. ```go f := NewFile("a") f.Func().Id("main").Params().Block() buf := &bytes.Buffer{} err := f.Render(buf) if err != nil { fmt.Println(err.Error()) } else { fmt.Println(buf.String()) } // Output: // package a // // func main() {} ``` ### Anon Anon adds an anonymous import. ```go f := NewFile("c") f.Anon("a") f.Func().Id("init").Params().Block() fmt.Printf("%#v", f) // Output: // package c // // import _ "a" // // func init() {} ``` ### ImportName ImportName provides the package name for a path. If specified, the alias will be omitted from the import block. This is optional. If not specified, a sensible package name is used based on the path and this is added as an alias in the import block. ```go f := NewFile("main") // package a should use name "a" f.ImportName("github.com/foo/a", "a") // package b is not used in the code so will not be included f.ImportName("github.com/foo/b", "b") f.Func().Id("main").Params().Block( Qual("github.com/foo/a", "A").Call(), ) fmt.Printf("%#v", f) // Output: // package main // // import "github.com/foo/a" // // func main() { // a.A() // } ``` ### ImportNames ImportNames allows multiple names to be imported as a map. Use the [gennames](gennames) command to automatically generate a go file containing a map of a selection of package names. ### ImportAlias ImportAlias provides the alias for a package path that should be used in the import block. A period can be used to force a dot-import. ```go f := NewFile("main") // package a should be aliased to "b" f.ImportAlias("github.com/foo/a", "b") // package c is not used in the code so will not be included f.ImportAlias("github.com/foo/c", "c") f.Func().Id("main").Params().Block( Qual("github.com/foo/a", "A").Call(), ) fmt.Printf("%#v", f) // Output: // package main // // import b "github.com/foo/a" // // func main() { // b.A() // } ``` ### Comments PackageComment adds a comment to the top of the file, above the package keyword. HeaderComment adds a comment to the top of the file, above any package comments. A blank line is rendered below the header comments, ensuring header comments are not included in the package doc. CanonicalPath adds a canonical import path annotation to the package clause. ```go f := NewFile("c") f.CanonicalPath = "d.e/f" f.HeaderComment("Code generated by...") f.PackageComment("Package c implements...") f.Func().Id("init").Params().Block() fmt.Printf("%#v", f) // Output: // // Code generated by... // // // Package c implements... // package c // import "d.e/f" // // func init() {} ``` CgoPreamble adds a cgo preamble comment that is rendered directly before the "C" pseudo-package import. ### PackagePrefix If you're worried about generated package aliases conflicting with local variable names, you can set a prefix here. Package foo becomes {prefix}_foo. ```go f := NewFile("a") f.PackagePrefix = "pkg" f.Func().Id("main").Params().Block( Qual("b.c/d", "E").Call(), ) fmt.Printf("%#v", f) // Output: // package a // // import pkg_d "b.c/d" // // func main() { // pkg_d.E() // } ```