github.com/hairyhenderson/gomplate/v4@v4.0.0-pre-2.0.20240520121557-362f058f0c93/CONTRIBUTING.md (about)

     1  # Contributing to gomplate
     2  
     3  Thanks for considering a contribution! All contributions are welcome, including
     4  bug reports, bug fixes, new features or even just questions.
     5  
     6  ## Features
     7  
     8  For PRs, please:
     9  - Consider filing an [issue](https://github.com/hairyhenderson/gomplate/issues/new) first, especially if you're not sure if your idea will be accepted.
    10  - [Link to any relevant issues](https://help.github.com/articles/autolinked-references-and-urls/) in the PR
    11  - Add new tests to cover the new code, and make sure all of the tests pass (`make lint test integration`)
    12  - Please try to conform to the existing code style, and see [Style Guide](#style-guide) for more details
    13  
    14  ## Bugs
    15  
    16  Submit issues to [issue tracker](https://github.com/hairyhenderson/gomplate/issues/).
    17  
    18  Any bug fix PRs must also include unit tests and/or integration tests to prevent regression.
    19  
    20  If you think you've found a sensitive security issue, please e-mail me before opening an issue: dhenderson@gmail.com. My PGP key is available on Keybase: https://keybase.io/dhenderson/.
    21  
    22  ## Versioning, API and Deprecation
    23  
    24  I try to follow [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) as much as possible, and as such the version numbers attached to gomplate releases have _semantic meaning_. That is, patch-level releases (e.g. when going from 2.3.0 to 2.3.1) will only contain bug fixes and will not otherwise add or remove features, while minor-level releses (e.g. 2.3.0 to 2.4.0) will only contain new features and will not remove or make breaking changes to features, and major-level releases (e.g. 2.3.0 to 3.0.0) will contain breaking changes (either feature removals, renames, or significant behaviour changes).
    25  
    26  When making a change that'll require either a _minor_ or _major_ version bump upon release, the PR should be labeled with the `api/minor` or `api/major` labels.
    27  
    28  Note also that _only_ the "Public API" is subject to the semver guarantees. Here's what I consider as "Public API":
    29  1. exported code
    30    - this includes the behaviour of that code as documented
    31    - excluding function definitions (in the `funcs/` sub-directory)
    32    - excluding unit and integration tests
    33  2. template functions
    34    - the namespaced function names and aliases, as used inside templates (e.g. `math.Add`)
    35    - the Go functions that implement these functions _may_ change:
    36      - the function signature may change in compatible ways (i.e. a parameter type widening from `string` to `interface{}`)
    37  3. the `gomplate` command and its command-line arguments
    38  
    39  Any semver guarantees only apply between released versions of gomplate. I reserve the right to make breaking changes to new features before these features are delivered in a release.
    40  
    41  Sometimes, a deprecation is necessary. I will mark these deprecations in the documentation as soon as possible, and the deprecations may turn into removals (or renames, behaviour changes, etc...) as early as the next major version. However, features may stay deprecated for many major versions without being removed.
    42  
    43  ## Style Guide
    44  
    45  Code style is enforced by [`golangci-lint`](https://github.com/golangci/golangci-lint) during CI builds.
    46  
    47  ### Template Function Style
    48  
    49  Gomplate's code base has grown organically, and so it's full of quirks and inconsistencies. However, there are a few style points that have emerged over the years:
    50  
    51  1. Generally, all template functions should take `interface{}` as an input type, and do type conversions where necessary. As an example, see https://github.com/hairyhenderson/gomplate/blob/af961ebe30041acb4e7f94ddd5f7c92372f97111/funcs/math.go#L96..L111
    52      - In cases where a function takes a slice as input, use `interface{}` as the input, and convert it to a `[]interface{}` if needed
    53  2. Where defaults can be inferred, I prefer allowing a relaxed polymorphic style - see https://github.com/hairyhenderson/gomplate/blob/af961ebe30041acb4e7f94ddd5f7c92372f97111/funcs/crypto.go#L118..L133 as an example
    54      - tl;dr: I take `...interface{}` as a single input type, and do type conversion and argument inference based on the number of arguments provided
    55      - this only works when certain args can be considered "optional"
    56  3. Pipelining (i.e. `{{ "result of some action" | some.Function }}`) is powerful and it's good to make sure that functions with multiple arguments specify them in a sane order for pipelining.
    57      - When you're unsure about argument order, prefer the order that will make pipelining easier:
    58        ```
    59        {{ "one,two,three" | strings.Split "," }} <- this is far more natural
    60        ```
    61      - Don't depend too much on existing functions as a guide - there's already a lot of inconsistency there!