# boilerplate-gen

[![Build Status](https://jenkins.internal.justin.tv/buildStatus/icon?job=video-chukwa-boilerplategen)](https://jenkins.internal.justin.tv/job/video-chukwa-boilerplategen/) [![GoDoc](https://godoc.internal.justin.tv/code.justin.tv/video/chukwa-boilerplategen?status.svg)](https://godoc.internal.justin.tv/code.justin.tv/video/chukwa-boilerplategen)

**Warning**: This project and its documentation are a work in progress.

## Documentation for users

All binaries in your project (e.g. `package main`s) must use [`code.justin.tv/common/golibs/bininfo`](https://git-aws.internal.justin.tv/common/golibs/tree/master/bininfo).

We maintain a [Changelog](./changelog.md) that is updated immediately prior to each release.

## Version support policy

One of the core goals of `boilerplate-gen` is to let maintainers upgrade projects quickly and confidently.  If you have
any trouble, or run into any obstacles that you are concerned may prevent you from upgrading within the window described
by this policy, *please* reach out to us!  We are here to help.

We will support new stable releases of Go as soon as they are available.  We believe that `boilerplate-gen` should work
with `go1.5` and later, but we only officially support the latest stable release of Go and any versions of Go that have
been the latest stable release within the past thirty calendar days, excluding any releases (such as `go1.7.2`) that are
rescinded by the Go team.

We will maintain support for older versions of `boilerplate-gen` and the `boilerplate-gen` configuration file format for
the same period (thirty calendar days).

We may ask you to update your vendored tools or libraries if they are outdated and they appear to be related to a
problem that your project is having.  We will consider a tool or library "outdated" if a new stable release (or, for
projects that do not tag releases, a new upstream commit on the default branch) has been available for more than thirty
calendar days.

## Requirements

`boilerplate-gen` expects to be able to fork and execute the `git` binary, and expects to have access to
`git-aws.internal.justin.tv`.  This is how it performs update checks.

## Getting started

This release of `boilerplate-gen` removes explicit boilerplate versioning; instead, it is intended to be used with
`retool` so that you can update the `boilerplate-gen` tool itself in a deliberate, controlled manner.

If you have not used `retool` before, begin by installing it.

    go get -u code.justin.tv/common/retool/...

Make sure that your project's repository is clean.  Then:

    cd /path/to/project
    retool add code.justin.tv/kdkly/boilerplate-gen/cmd/boilerplate-gen origin/master
    echo '/.manta-output.d' >> .gitignore

Create a `.boilerplate.yaml` file; see the examples in the `_examples` and the configuration documentation below.  The
most important decision you'll need to make is whether your project is a "library" or a "daemon".  The boilerplate
generated for a "library"-type project will omit things specific to deployment.

In general, you should start from a minimal configuration and add only those non-default settings required to make
`boilerplate-gen` generate output that you're happy with.  The definitive reference for the configuration file format is
the [Godoc describing the `ConfigFile` struct](https://godoc.internal.justin.tv/code.justin.tv/kdkly/boilerplate-gen).

Try generating boilerplate.

    retool do boilerplate-gen

Remove any stray files (e.g. `.manta.json` and any scripts that it called).  Give everything a test run...

    make

Or, if you'd like to build, test, and lint a single configuration variant, and see additional output, try the following.

    MANTA_FLAGS="-v" make go1.7.3

If everything works, commit away!

For "daemon"-style projects, please be aware that `boilerplate-gen` currently *does not* produce `deploy.json` or the
`restart.sh` script that Courier requires.

## Updating boilerplate-gen

    retool upgrade code.justin.tv/kdkly/boilerplate-gen/cmd/boilerplate-gen origin/master

    retool do boilerplate-gen

## Makefile targets

In addition to the per-configuration-variant Makefile targets, which invoke `manta`, there are three phony targets that
invoke the lint, test, and build phases of the CI process in your local environment (i.e. without using Manta).  They
are, simply enough:

    make lint
    make test
    make build

## Terminology

- project type: one of {library, daemon, utility}

- variant (or "build variant"): a single build-time configuration; in Go, this is a platform, a version of Go, and a set of tags.

- primary variant: the one that will be deployed (for deployable projects)

## For maintainers

- On new Go release...
  - Add binaries' hash to `boilerplate/consts.go`.  See `cmd/scrape-go-binaries`, which can generate the appropriate
    data for you automagically.

- To cut a new boilerplate-gen release...
  - Commit a change that
    - increases the version number in `boilerplate/version.go`; and
    - adds a new entry to CHANGELOG summarizing changes since the last release.
  - Create a new annotated tag (`git tag -a v1.2.3 master`).
  - Push tag (`git push origin v1.2.3`).
  - Assuming that, per semver rules, the new version is the latest, people will start seeing prompts to upgrade.
  - Note that there IS NOT yet support for more complex semver rules (release candidates, etc.).

- Remember to test on OS X; some folks use it directly.

## Other notes

- based on derivates of build scripts originally by Rhys; possibly other contributors

## Internals

- The update tagging mechanism (TODO: This description is now outdated.)
 - Currently assumes that `common/golibs/bininfo `'s `Revision` function will return the tagged commit's object ID (not
   the ID of the tag itself).
 - You can manually trigger an update warning with e.g.
   `go build ./cmd/boilerplate-gen && ./boilerplate-gen -debug-bininfo-rev $(git rev-parse v0.1.0^{commit})`
