gopkg

package module
v0.0.0-...-852df71 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2023 License: MIT Imports: 18 Imported by: 0

README

gopkg

A toolkit for writing code generators in Golang.

Overview

gopkg provides a simple, AST-like structure for representing code declarations - FileContents.

It provides two main methods for interacting with this structure:

  • Parse takes a path to a package and returns the contents of each .go file as a slice of FileContents objects.

  • Generate takes a slice of FileContents objects and writes each object to .go file.

E.g.

  // pckContents has type `[]gopkg.FileContents`
  pkgContents, err := gopkg.Parse("./path/to/my/package")
  // check err

  err = gopkg.Generate(pkgContents)
  // check err
FileContents structure

Contains all package level declaration contained within a .go file, as well as information about the path to the file and it's Golang import path.

type FileContents struct {
	Filepath string
	PackageName string
	PackageImportPath string
	Imports []ImportAndAlias
	Consts []DeclVar
	Vars []DeclVar
	Types []DeclType
	Functions []DeclFunc
}

Examples:

The example_generators folder contains several toy examples of generator implementations.

See also:

servicegen - A generator for creating service interfaces and tests. resourcegen - For generating interfaces required for dependency injection.

TODO:

  • Make linting method to sort FileContents

  • Add DeclFunc.AdditionalImports field, which can be used to add imports at the function level

  • Add DeclFunc.DocString field

  • Add error checks for generation, e.g:

    • Return error when generating a func if:
      • Func name not set
      • Func args unnamed
        • Note; TypeFunc args may be unnamed... should also allow unnamed types on DeclFunc in interfaces
      • Func arg or ret arg is missing a type
    • Return error when generation a file if:
      • Filepath not set
      • PackageName not set
    • Error for TypeDecl when:
      • Name not set
      • Type not set
    • etc...
  • Add linter to sanatize literals which will strip leading and trailing whitespace from all literals:

    • Remove leading whitespace from DeclFunc.BodyTmpl
    • Remove leading and trailing whitespace from all strings in FileContents
    • Maybe remove newlines from things that shouldnt have new lines? (e.g. Decl names?)
  • Consider removing Import field from declaration types - it doesn't seem that this is used at all for generating; It seems like a convenience field but I'm not sure there is a scenario where this is useful

Documentation

Index

Constants

View Source
const CURRENT_PKG = "current_pkg_import"

Variables

This section is empty.

Functions

func AddAliasToAllImports

func AddAliasToAllImports(pkg []FileContents) error

func AddRequiredImports

func AddRequiredImports(pkg []FileContents) error

func CreatePathAndOpen

func CreatePathAndOpen(
	filepath string,
) (*os.File, error)

CreatePathAndOpen creats all contains directors in filepath if they do not exist and opens a file for writing at filepath.

If filepath already exists and is a file then the file will be overwritten. If filepath already exists and is a directory then an error will be returned.

func Generate

func Generate(files []FileContents) error

func GroupModuleImportsLast

func GroupModuleImportsLast(modulePath string) func([]FileContents) error

func GroupStdImportsFirst

func GroupStdImportsFirst(pkg []FileContents) error

GroupStdImportsFirst will move all std imports in all files to their own group at the start of the import list.

The ordeing of the std imports within a file will remain unchanged. Any existing grouping on std imports within a file will be removed. The ordering + grouping of all other imports within a file remains unchanged

func Lint

func Lint(
	pkg []FileContents,
	extraLintRules ...func([]FileContents) error,
) error

func LintAndGenerate

func LintAndGenerate(
	files []FileContents,
	extraLintRules ...func([]FileContents) error,
) error

func LintCustom

func LintCustom(
	pkg []FileContents,
	lintRules ...func([]FileContents) error,
) error

func PackageImportPath

func PackageImportPath(path string) (string, error)

PackageImportPath returns the import path of a package given its path in the filesystem

`path` may be either a relative or absoute path to the package directory or a file withing the package directory.

**Note 1:** it assumes that the package is within a go module - if it is not it will return an error.

**Note 2:** there are no checks that the given package does contain `.go` files (i.e. is a go package)

**Note 3:** only tested on Unix... Windows users tread carefully.

Deets: This method traverses up the directory tree from `path`, looking for a `go.mod` file in each directory. Upon finding one, it will return the module path within `go.mod` appended with the relative path of the given `path`.

func SortFuncs

func SortFuncs(f []DeclFunc)

func WriteDeclFunc

func WriteDeclFunc(
	w io.Writer,
	decl DeclFunc,
	importAliases map[string]string,
) error

func WriteDeclType

func WriteDeclType(
	w io.Writer,
	decl DeclType,
	importAliases map[string]string,
) error

func WriteDeclVars

func WriteDeclVars(
	w io.Writer,
	keyword string,
	decls []DeclVar,
	importAliases map[string]string,
) error

func WriteFileContents

func WriteFileContents(
	w io.Writer,
	c FileContents,
) error

func WriteImports

func WriteImports(
	w io.Writer,
	imports []ImportAndAlias,
) error

Types

type DeclFunc

type DeclFunc struct {
	Name            string
	Import          string
	Receiver        FuncReceiver
	Args            []DeclVar
	VariadicLastArg bool
	ReturnArgs      []DeclVar
	BodyTmpl        string
	BodyData        any
	DocString       string
}

func (DeclFunc) RequiredImports

func (d DeclFunc) RequiredImports() map[string]bool

type DeclType

type DeclType struct {
	Name      string
	Import    string
	Type      Type
	DocString string
}

type DeclVar

type DeclVar struct {
	Type
	Name   string
	Import string

	// LiteralValue is the value of the literal assigned to this variable declaration
	// (if one was assigned - otherwise it will be empty)
	//
	// e.g. for `var MyVar int = 123`, LiteralValue will be `123`
	LiteralValue string

	// StructTag holds the tags for a struct field if this DeclVar represents a
	// field within a struct.
	// If this DeclVar is not within a struct then it is not used.
	StructTag reflect.StructTag

	DocString string
}

type FileContents

type FileContents struct {
	Filepath string

	PackageName string

	PackageImportPath string

	Imports []ImportAndAlias

	Consts    []DeclVar
	Vars      []DeclVar
	Types     []DeclType
	Functions []DeclFunc

	DocString string
}

func Parse

func Parse(inputPath string, opts ...ParseOption) ([]FileContents, error)

Parse parses the file or package at `inputPath` and returns its `FileContents` representation

`inputPath` may either be a single golang source file or a directory of golang source files (i.e. a package)

type FuncReceiver

type FuncReceiver struct {
	VarName   string
	TypeName  string
	IsPointer bool
}

type ImportAndAlias

type ImportAndAlias struct {
	Import string
	Alias  string

	// Group defines the _group_ which this import will sit within:
	//  * Groups are seperated by a single, empty newline in the imports list
	//	* Groups are ordered by the value of this `Group` property
	//	* Group numbers do not need to be monotonically increasing (they are only compared with `<`)
	// e.g:
	// “`
	// import (
	//   "import1" <----- Group 0
	//
	//   "import2" <--\
	//   "import3" <--|
	//   "import4" <--+-- Group 1
	// )
	Group int64
}

type ParseOption

type ParseOption func(parseOptions) parseOptions

func ParseDependentTypes

func ParseDependentTypes() ParseOption

func ParseWithPkgImportPath

func ParseWithPkgImportPath(importPath string) ParseOption

type Type

type Type interface {
	DefaultInit(importAliases map[string]string) (string, error)
	FullType(importAliases map[string]string) (string, error)
	RequiredImports() map[string]bool
}

type TypeAny

type TypeAny struct {
}

func (TypeAny) DefaultInit

func (t TypeAny) DefaultInit(importAliases map[string]string) (string, error)

func (TypeAny) FullType

func (t TypeAny) FullType(importAliases map[string]string) (string, error)

func (TypeAny) RequiredImports

func (t TypeAny) RequiredImports() map[string]bool

type TypeArray

type TypeArray struct {
	ValueType Type
}

func (TypeArray) DefaultInit

func (t TypeArray) DefaultInit(importAliases map[string]string) (string, error)

func (TypeArray) FullType

func (t TypeArray) FullType(importAliases map[string]string) (string, error)

func (TypeArray) RequiredImports

func (t TypeArray) RequiredImports() map[string]bool

type TypeBool

type TypeBool struct{}

func (TypeBool) DefaultInit

func (t TypeBool) DefaultInit(importAliases map[string]string) (string, error)

func (TypeBool) FullType

func (t TypeBool) FullType(importAliases map[string]string) (string, error)

func (TypeBool) RequiredImports

func (t TypeBool) RequiredImports() map[string]bool

type TypeByte

type TypeByte struct{}

func (TypeByte) DefaultInit

func (t TypeByte) DefaultInit(importAliases map[string]string) (string, error)

func (TypeByte) FullType

func (t TypeByte) FullType(importAliases map[string]string) (string, error)

func (TypeByte) RequiredImports

func (t TypeByte) RequiredImports() map[string]bool

type TypeError

type TypeError struct{}

func (TypeError) DefaultInit

func (t TypeError) DefaultInit(importAliases map[string]string) (string, error)

func (TypeError) FullType

func (t TypeError) FullType(importAliases map[string]string) (string, error)

func (TypeError) RequiredImports

func (t TypeError) RequiredImports() map[string]bool

type TypeFloat32

type TypeFloat32 struct{}

func (TypeFloat32) DefaultInit

func (t TypeFloat32) DefaultInit(importAliases map[string]string) (string, error)

func (TypeFloat32) FullType

func (t TypeFloat32) FullType(importAliases map[string]string) (string, error)

func (TypeFloat32) RequiredImports

func (t TypeFloat32) RequiredImports() map[string]bool

type TypeFloat64

type TypeFloat64 struct{}

func (TypeFloat64) DefaultInit

func (t TypeFloat64) DefaultInit(importAliases map[string]string) (string, error)

func (TypeFloat64) FullType

func (t TypeFloat64) FullType(importAliases map[string]string) (string, error)

func (TypeFloat64) RequiredImports

func (t TypeFloat64) RequiredImports() map[string]bool

type TypeFunc

type TypeFunc struct {
	Args            []DeclVar
	VariadicLastArg bool
	ReturnArgs      []DeclVar
}

func (TypeFunc) DefaultInit

func (t TypeFunc) DefaultInit(importAliases map[string]string) (string, error)

func (TypeFunc) FullType

func (t TypeFunc) FullType(importAliases map[string]string) (string, error)

func (TypeFunc) RequiredImports

func (t TypeFunc) RequiredImports() map[string]bool

type TypeInt

type TypeInt struct{}

func (TypeInt) DefaultInit

func (t TypeInt) DefaultInit(importAliases map[string]string) (string, error)

func (TypeInt) FullType

func (t TypeInt) FullType(importAliases map[string]string) (string, error)

func (TypeInt) RequiredImports

func (t TypeInt) RequiredImports() map[string]bool

type TypeInt32

type TypeInt32 struct{}

func (TypeInt32) DefaultInit

func (t TypeInt32) DefaultInit(importAliases map[string]string) (string, error)

func (TypeInt32) FullType

func (t TypeInt32) FullType(importAliases map[string]string) (string, error)

func (TypeInt32) RequiredImports

func (t TypeInt32) RequiredImports() map[string]bool

type TypeInt64

type TypeInt64 struct{}

func (TypeInt64) DefaultInit

func (t TypeInt64) DefaultInit(importAliases map[string]string) (string, error)

func (TypeInt64) FullType

func (t TypeInt64) FullType(importAliases map[string]string) (string, error)

func (TypeInt64) RequiredImports

func (t TypeInt64) RequiredImports() map[string]bool

type TypeInterface

type TypeInterface struct {
	Embeds []Type
	Funcs  []DeclFunc
}

func (TypeInterface) DefaultInit

func (t TypeInterface) DefaultInit(importAliases map[string]string) (string, error)

func (TypeInterface) FullType

func (t TypeInterface) FullType(importAliases map[string]string) (string, error)

func (TypeInterface) RequiredImports

func (t TypeInterface) RequiredImports() map[string]bool

type TypeMap

type TypeMap struct {
	KeyType   Type
	ValueType Type
}

func (TypeMap) DefaultInit

func (t TypeMap) DefaultInit(importAliases map[string]string) (string, error)

func (TypeMap) FullType

func (t TypeMap) FullType(importAliases map[string]string) (string, error)

func (TypeMap) RequiredImports

func (t TypeMap) RequiredImports() map[string]bool

type TypeNamed

type TypeNamed struct {
	Name      string
	Import    string
	ValueType Type
}

TODO rename to something more approriate - maybe TypeNamed (or TypeAlias)

func (TypeNamed) DefaultInit

func (t TypeNamed) DefaultInit(importAliases map[string]string) (string, error)

func (TypeNamed) FullType

func (t TypeNamed) FullType(importAliases map[string]string) (string, error)

func (TypeNamed) RequiredImports

func (t TypeNamed) RequiredImports() map[string]bool

type TypePointer

type TypePointer struct {
	ValueType Type
}

func (TypePointer) DefaultInit

func (t TypePointer) DefaultInit(importAliases map[string]string) (string, error)

func (TypePointer) FullType

func (t TypePointer) FullType(importAliases map[string]string) (string, error)

func (TypePointer) RequiredImports

func (t TypePointer) RequiredImports() map[string]bool

type TypeString

type TypeString struct{}

func (TypeString) DefaultInit

func (t TypeString) DefaultInit(importAliases map[string]string) (string, error)

func (TypeString) FullType

func (t TypeString) FullType(importAliases map[string]string) (string, error)

func (TypeString) RequiredImports

func (t TypeString) RequiredImports() map[string]bool

type TypeStruct

type TypeStruct struct {
	Embeds []Type
	Fields []DeclVar
}

func (TypeStruct) DefaultInit

func (t TypeStruct) DefaultInit(importAliases map[string]string) (string, error)

func (TypeStruct) FullType

func (t TypeStruct) FullType(importAliases map[string]string) (string, error)

func (TypeStruct) RequiredImports

func (t TypeStruct) RequiredImports() map[string]bool

type TypeUnnamedLiteral

type TypeUnnamedLiteral struct{}

func (TypeUnnamedLiteral) DefaultInit

func (t TypeUnnamedLiteral) DefaultInit(importAliases map[string]string) (string, error)

func (TypeUnnamedLiteral) FullType

func (t TypeUnnamedLiteral) FullType(importAliases map[string]string) (string, error)

func (TypeUnnamedLiteral) RequiredImports

func (t TypeUnnamedLiteral) RequiredImports() map[string]bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL