Welcome and thank you for making it this far and considering contributing to go/template
.
We always appreciate any contributions by raising issues, improving the documentation, fixing bugs in the CLI or adding new features/ extensions.
Before opening a PR please read through this document. If you want to contribute but don't know how to start or have any questions feel free to reach out to us on Github Discussions. Answering any questions or discussions there is also a great way to contribute to the community.
Please keep in mind to open an issue whenever you plan to make an addition to extensions or features to discuss it before implementing it.
To contribute any code to this repository just do the following:
- Make sure you have Go's latest version installed
- Fork this repository
- Run
make all
to make sure everything's setup correctly - Make your changes
Please follow the seven rules of greate Git commit messages and make sure to keep your commits clean and atomic. Your PR won't be squashed before merging so the commits should tell a story.
Sign-off on all Git commits by running
git commit -s
. Take a look at the Gihub Docs for further information.Add documentation and tests for your addition if needed.
- Run
make lint test
to ensure your code is ready to be mergedIf any linting issues occur please fix them. Using a nolint directive should only be used as a last resort.
- Open a PR and make sure the CI pipelines succeed.
- Wait for one of the maintainers to review your code and react to the comments.
- After approval merge the PR
- Thank you for your contribution! :)
go/template
uses extensions to allow optional additions to the base template. An example for an extension would be the gRPC
extension which adds a protobuf definition file to the base template as well as further make targets like make generate
and tools like buf
.
All extensions are defined in the options defintion file. There you will see that all extensions are divided into different categories. Please make sure that there's no fitting category already available before creating a new one.
Now add your option to the definitions as a new Option
struct.
A minimal defintion would look like:
Option{
name: "someOption",
defaultValue: StaticValue("some default value"),
description: StringValue("some description"),
},
defaultValue
and description
use custom types here since the Option
struct also allows to set dynamic values that are evaluated during runtime.
An example for that would be the following:
Option{
name: "projectSlug",
defaultValue: DynamicValue(func(ov *OptionValues) interface{} {
projectName := ov.Base["projectName"].(string)
return strings.ReplaceAll(strings.ToLower(projectName), " ", "-")
}),
description: StringValue("Technical name of the project for folders and names. This will also be used as output directory."),
validator: RegexValidator(`^[a-z1-9]+(-[a-z1-9]+)*$`, "only lowercase etters and dashes"),
},
In this case first the value of projectName
is evaluated to then return the default value of projectSlug
depending on projectName
's value.
Further options for the Option
struct are a validator
(some predefined validators are already provided), as well as shouldDisplay
to optionally hide a option in the CLI and postHook
to define custom logic after the new project folder has been generated.
This can be used to optionally remove files from the template depending on some option's value.
An option's value can be used in both file names and the files' content.
After getting all the values the template will be generated by passing in a OptionValues
struct to the template engine.
Values can then be accessed with template expressions like for example {{ .Extensions.<category>.<optionName> }}
.
In general you should use template expressions to optionally add things to existing files (like another Make target) and use the
postHook
property to optionally delete/ add a whole file.
We use for the release of the go-template
project GoReleaser. GoReleaser
is a tool that
helps you to release your projects in a fast and easy way.
Important is the .goreleaser.yaml
file which is used to configure the release process.
We can start locale builds with adding the --snapshot
flag to the goreleaser
command. The --snapshot
flag will
disable some of the phases, like creating a release tag and pushing to the remote.
goreleaser build --rm-dist --snapshot
or even a release with:
goreleaser release --snapshot --rm-dist
Check the great documentation of GoReleaser here for further information.