Skip to content

go-optioner is a tool for generating functional options pattern in Go code. This tool can automatically generate corresponding options code based on the given struct definition.

License

Notifications You must be signed in to change notification settings

chenmingyong0423/go-optioner

Repository files navigation

go-optioner

GitHub Repo stars GitHub issues GitHub License GitHub release (with filter) Go Report Card All Contributors

go-optioner is a tool for generating functional options pattern in Go code. This tool can automatically generate corresponding options code based on the given struct definition.


English | 中文简体

Installation

  • 1、go install github.com/chenmingyong0423/go-optioner/cmd/optioner@latest
  • 2、Run the optioner command to check if the installation is successful.
> optioner
optioner is a tool for generating functional options pattern.
Usage:
         optioner [flags]
Flags:
         -type <struct name>
         -output <output path>, default: srcDir/opt_xxx_gen.go
         -with_prefix <the prefix of the With{filed_name} function>, default is With{filed_name}.If specified, such as User, it will generate WithUser{filed_name}
         -mode <the file writing mode>, default: write
         there are two available modes:
                 - write(Write/Overwrite): Overwrites or creates a new file.
                 - append (Append): Adds to the end of the file.

If you install it successfully and the optioner command is not found, make sure to add $GOPATH/bin to your environment variables.

Arguments

When using Optioner, you can customize its behavior with the following parameters:

  • -type: Specifies the name of the target struct. This is a required parameter.
  • -output: Sets the output file path for the generated code. This is an optional parameter, with the default file name format being opt_{StructName}_gen.go, where {StructName} is the name of the struct. The file is placed in the current directory by default.
  • -with_prefix: Sets the prefix for the With{field_name} function. This is an optional parameter with a default value of With{field_name}. If a prefix is specified, such as User, the generated function name will become WithUser{field_name}.
  • -mode: Determines the file writing mode, with two available options:
    • write (Write/Overwrite): Overwrites the file if it exists or creates a new one if it does not.
    • append (Append): Adds content to the end of an existing file.

Usage

You can directly use the optioner command to generate functional options code for the corresponding struct, or you can use go generate for bulk generation.

Optioner Command

    1. First, assume you have prepared a Go file containing the struct for which you want to generate functional option pattern code. You can use the opt tag on the struct's fields to indicate which fields should be required parameters for the New{FieldName} function.
     package example
     
     type User[T any, R any] struct {
     	Name            string `opt:"-"`
     	NecGenericFiled T      `opt:"-"`
     	Age             int
     	Gender          string
     	GenericFiled    R
     }
     

    If a struct field is tagged with opt and its value is set to -, the field becomes a required parameter for the New{FieldName} function, and a With{FieldName} function will not be generated for that field.

    Note: A package declaration is required.

    1. In the directory containing the struct definition file, execute the optioner -type {StructName} command, replacing {StructName} with the actual name of your struct, for example, optioner -type User. After running this command, the optioner tool automatically creates a default opt_user_gen.go file and generates the functional options pattern code within it. The generated code structure is as follows:
     // Generated by [optioner] command-line tool; DO NOT EDIT
     // If you have any questions, please create issues and submit contributions at:
     // https://github.com/chenmingyong0423/go-optioner
     
     package example
     
     type UserOption[T any, R any] func(*User[T, R])
     
     func NewUser[T any, R any](name string, necGenericFiled T, opts ...UserOption[T, R]) *User[T, R] {
     	user := &User[T, R]{
     		Name:            name,
     		NecGenericFiled: necGenericFiled,
     	}
     
     	for _, opt := range opts {
     		opt(user)
     	}
     
     	return user
     }
     
     func WithAge[T any, R any](age int) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.Age = age
     	}
     }
     
     func WithGender[T any, R any](gender string) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.Gender = gender
     	}
     }
     
     func WithGenericFiled[T any, R any](genericFiled R) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.GenericFiled = genericFiled
     	}
     }
     

    To customize the output file path for the generated code, you can specify the output and mode parameters.

go generate Command

Please ensure your project has been initialized with Go Modules or is correctly set up with GOPATH, and that your project structure complies with the requirements of Go Modules or GOPATH before running the go generate command.

    1. First, assume you have prepared a Go file containing the struct for which you want to generate functional option pattern code. Add the comment //go:generate optioner -type {StructName} above the struct definition, replacing {StructName} with the actual name of your struct, e.g., use //go:generate optioner -type User for generating code for the User struct. You can use the opt tag on the struct's fields to indicate which fields should be required parameters for the New{FieldName} function.
     package example
     
     //go:generate optioner -type User
     type User[T any, R any] struct {
     	Name            string `opt:"-"`
     	NecGenericFiled T      `opt:"-"`
     	Age             int
     	Gender          string
     	GenericFiled    R
     }
     

    If a struct field is tagged with opt and its value is set to -, the field becomes a required parameter for the New{FieldName} function, and a With{FieldName} function will not be generated for that field.

    Note: A package declaration is required.

    1. Run the go generate command in the directory containing the struct definition file. This command triggers the optioner tool and automatically creates a default opt_user_gen.go file, generating functional options pattern code within it. The generated code structure is as follows:
     // Generated by [optioner] command-line tool; DO NOT EDIT
     // If you have any questions, please create issues and submit contributions at:
     // https://github.com/chenmingyong0423/go-optioner
     
     package example
     
     type UserOption[T any, R any] func(*User[T, R])
     
     func NewUser[T any, R any](name string, necGenericFiled T, opts ...UserOption[T, R]) *User[T, R
     
     ] {
     	user := &User[T, R]{
     		Name:            name,
     		NecGenericFiled: necGenericFiled,
     	}
     
     	for _, opt := range opts {
     		opt(user)
     	}
     
     	return user
     }
     
     func WithAge[T any, R any](age int) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.Age = age
     	}
     }
     
     func WithGender[T any, R any](gender string) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.Gender = gender
     	}
     }
     
     func WithGenericFiled[T any, R any](genericFiled R) UserOption[T, R] {
     	return func(user *User[T, R]) {
     		user.GenericFiled = genericFiled
     	}
     }
     

    To customize the output file path for the generated code, you can modify the content of //go:generate optioner -type User by specifying the output and mode parameters.

How to Contribute

We welcome contributions from others! If you have any questions, suggestions for improvement, or have found a bug, please create an issue to discuss it with us. If you want to contribute code changes, please follow these steps:

1、Fork this repository and clone it to your local machine.

2、Create a new branch: git checkout -b feature/your-feature.

3、Make your modifications or add new features on your branch.

4、Commit your changes: git commit -m "Describe your changes".

5、Push to your Fork repository: 1git push origin feature/your-feature1.

6、Create a Pull Request to merge your changes into the main repository.

Please ensure that your code follows the project's coding style and passes the tests.

License

This project is licensed under the Apache License.

Contact Us

If you have any questions or suggestions, you can contact us through the following methods:

About

go-optioner is a tool for generating functional options pattern in Go code. This tool can automatically generate corresponding options code based on the given struct definition.

Resources

License

Stars

Watchers

Forks

Packages