MCPcopy Index your code
hub / github.com/dave/jennifer

github.com/dave/jennifer @v1.7.1 sqlite

repository ↗ · DeepWiki ↗ · release v1.7.1 ↗
583 symbols 2,808 edges 29 files 393 documented · 67%
README

docs stability-stable

Jennifer

Jennifer is a code generator for 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:

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 for an index. Here's some examples of jennifer being used in the real-world:

Rendering

For testing, a File or Statement can be rendered with the fmt package using the %#v verb.

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 or File.Save are preferred.

Identifiers

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

Id

Id renders an identifier.

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.

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.

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.

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 or File.ImportAlias.

List

List renders a comma separated list. Use for multiple return functions.

c := List(Id("a"), Err()).Op(":=").Id("b").Call()
fmt.Printf("%#v", c)
// Output:
// a, err := b()

Keywords

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc 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, Clear, Close, Complex, Copy, Delete, Imag, Len, Make, Max, Min, 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:

c := Id("a").Op("=").Append(Id("a"), Id("b").Op("..."))
fmt.Printf("%#v", c)
// Output:
// a = append(a, b...)

Special cases for If, For, Interface, Struct, Switch, Case, Return and Map are explained below.

Operators

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

Op renders the provided operator / token.

c := Id("a").Op(":=").Id("b").Call()
fmt.Printf("%#v", c)
// Output:
// a := b()
c := Id("a").Op("=").Op("*").Id("b")
fmt.Printf("%#v", c)
// Output:
// a = *b
c := Id("a").Call(Id("b").Op("..."))
fmt.Printf("%#v", c)
// Output:
// a(b...)
c := If(Parens(Id("a").Op("||").Id("b")).Op("&&").Id("c")).Block()
fmt.Printf("%#v", c)
// Output:
// if (a || b) && c {
// }

Braces

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

Several methods render curly braces, summarized below:

Name Prefix Separator Example
Block \n func a() { ... } or if a { ... }
Interface interface \n interface { ... }
Struct struct \n struct { ... }
Values , []int{1, 2} or A{B: "c"}

Block

Block renders a statement list enclosed by curly braces. Use for code blocks.

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
// }
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.

Interface, Struct

Interface and Struct render the keyword followed by a statement list enclosed by curly braces.

c := Var().Id("a").Interface()
fmt.Printf("%#v", c)
// Output:
// var a interface{}
c := Type().Id("a").Interface(
    Id("b").Params().String(),
)
fmt.Printf("%#v", c)
// Output:
// type a interface {
//  b() string
// }
c := Id("c").Op(":=").Make(Chan().Struct())
fmt.Printf("%#v", c)
// Output:
// c := make(chan struct{})
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 Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

Several methods output parenthesis, summarized below:

Name Prefix Separator Example
Call , fmt.Println(b, c)
Params , func (a *A) Foo(i int) { ... }
Defs \n const ( ... )
Parens []byte(s) or a / (b + c)
Assert . s, ok := i.(string)

Call

Call renders a comma separated list enclosed by parenthesis. Use for function calls.

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.

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.

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.

c := Id("b").Op(":=").Index().Byte().Parens(Id("s"))
fmt.Printf("%#v", c)
// Output:
// b := []byte(s)
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.

c := List(Id("b"), Id("ok")).Op(":=").Id("a").Assert(Bool())
fmt.Printf("%#v", c)
// Output:
// b, ok := a.(bool)

Control flow

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

If, For

If and For render the keyword followed by a semicolon separated list.

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
// }
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:

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.

c := Return(Id("a"), Id("b"))
fmt.Printf("%#v", c)
// Output:
// return a, b

Collections

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Generics Helpers Misc File

Map

Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.

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.

c := Var().Id("a").Index().String()
fmt.Printf("%#v", c)
// Output:
// var a []string
c := Id("a").Op(":=").Id("b").Index(Lit(0), Lit(1))
fmt.Printf("%#v", c)
// Output:
// a := b[0:1]
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.

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.

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",
// }
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", //

Extension points exported contracts — how you extend this code

Code (Interface)
Code represents an item of code that can be rendered. [4 implementers]
jen/jen.go

Core symbols most depended-on inside this repo

Id
called by 323
jen/tokens.go
Id
called by 193
jen/tokens.go
Lit
called by 137
jen/lit.go
Op
called by 131
jen/tokens.go
newStatement
called by 120
jen/statement.go
Lit
called by 56
jen/lit.go
Qual
called by 50
jen/tokens.go
NewFile
called by 27
jen/file.go

Shape

Function 290
Method 279
Struct 10
TypeAlias 3
Interface 1

Languages

Go100%

Modules by API surface

jen/generated.go300 symbols
jen/examples_test.go143 symbols
jen/tokens.go25 symbols
jen/lit.go18 symbols
jen/file.go18 symbols
jen/statement.go9 symbols
jen/comments.go9 symbols
jen/group.go8 symbols
jen/custom.go7 symbols
jen/tag.go6 symbols
jen/jen_test.go6 symbols
jen/jen.go6 symbols

For agents

$ claude mcp add jennifer \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact