This project is no longer maintained by Turbine Labs, which has shut down.
The developer project is meant to describe our methodology for open-sourcing software.
There are a few interesting restrictions we placed on ourselves that led to our methodology for open-sourcing projects:
-
We develop our code internally in a monorepo, and feel pretty strongly about the benefits of doing so within an organization.
-
Much of our code is not (and will not be) open-sourced
-
As strongly as we feel developing in a monorepo is great for internal development, it's terrible for external developers, who will typically be submitting patches to individual projects.
Our goal is to bring many of the benefits of developing in a monorepo (chiefly atomicity of large changes and compatibility guarantees) to our open-source projects, while keeping each project relatively small and purpose-driven.
Our source code is written almost entirely in Go. Most of what we talk about below is targeted at Go development.
The source of truth for all projects is our internal monorepo. We will push "slices" of it to smaller open-source projects at a roughly weekly cadence.
We maintain a single, global version string for all Turbine Labs open-source projects, maintaining with the following invariant:
All Turbine Labs projects with the same version can be safely used together.
The version string follows Semantic Versioning rules, but applied to the aggregation of all projects. We push all projects every push (though some will be no-ops), and we tag all projects with the same version tag.
The main benefit of this approach is that contributors can easily work in individual projects, while enjoying the compatibility guarantees of our monorepo as they extend their reach. The downside is that the version increments will seem pretty chatty, especially for lower-velocity repositories. We may introduce project-specific semantic version numbers in the future, but for now are avoiding the operational overhead.
Turbine Labs open-source go projects will never publicly depend on anything other than other Turbine Labs open-source Go projects, with the exception of gomock, which is used extensively in our test code, but whose interfaces are both stable and unused in any part of our public API.
Some of our projects depend on other open-source projects, and in these cases we vendor those projects within ours. That we do so should be considered an implementation detail, entirely opaque to consumers of our library code. Vendored library code is hermetically sealed, and will never be part of the public types or interfaces of our library projects.
If our open-source projects need to share common dependencies, we will encapsulate the (private) dependency within a (public) interface.
For repeatable builds, you will probably want to vendor our library projects
rather than depending on go get
. As long as all vendored packages in the
github.com/turbinelabs
namespace include the same tag (not SHA!), they
can be safely used together.
You may find that you vendor some of the same dependencies that our packages privately vendor, and this may be a source of consternation to you because of the size of the resulting source tree or binary. From a correctness standpoint, it's totally fine (better even) to have multiple versions of the same code vendored at various levels of your source tree, as long as those vendored types and interfaces do not escape the API of their enclosing project.
While you may tempt yourself to flatten our vendored dependencies with your own, we hope to talk you out of it: our code is made to work with the exact code we've chosen to vendor, and it will work either surprisingly or not at all with other code. Similarly, you will find it onerous to pin yourself to whatever old package version we're using. Best to pretend our vendored code isn't there.
We decided to open-source some of our software because we thought it would be useful to people outside our company, but we also know the satisfaction gained from finding and fixing a tricky bug. That's where you come in.
We'd love for you to fork and contribute back to any of our projects, though the process has a little more overhead than the usual GitHub workflow. Filing issues for bugs you've found is the same, but pull requests behave a little differently. While the code review process will feel familiar, because of the unidirectionality of our open-source export, your pull request will be applied as a patch in our monorepo, and then pushed back out. We'll do this by hand until it becomes onerous, at which point we'll build some automation.
If you have a patch that affects multiple projects, that's fine! Be sure to reference each pull request in each other pull request, and we'll apply the change in a single patch. Yay monorepo!
All Turbine Labs open-sourced projects are released with a Contributor Code of Conduct. By participating in our projects you agree to abide by its terms, which will be carefully enforced.
Here we describe each of the projects in brief, and show how they depend on one another. We will do our best to keep this accurate.
api
:
defines the types and interfaces of the Turbine Labs public API
├──
nonstdlib
└──
test
cache
: a simple Cache interface,
with several concrete implementations
└──
test
cli
:
still yet another command line interface library
├──
nonstdlib
└──
test
codec
:
a simple interface for encoding and decoding values with JSON and YAML
implementations
└──
test
developer
: this very project!
docs
: the source for our
documentation site
envoy-simple
: a Docker
image of Envoy proxy that makes it easy to
configure Envoy from a dynamic control plane.
envtemplate
: a simple
mechanism to fill in golang-style templated files with variables from the
environment
├──
cli
├──
nonstdlib
└──
test
examples
: examples referenced by
Turbine Labs blog posts
gcloud-build
:
a build base image for a CI environment, based on the
Google CloudSDK image,
with docker and kubectl installed.
golang-gotchas
:
examples of some things that might feel awkward if you're coming to Go from
other languages
houston-crx
:
source for the Houston Chrome Extension, which lets you easily set version
routing cookies for your Houston-fronted application
idgen
:
a simple interface for generating IDs, including UUID and counter-based implementations
└──
test
nonstdlib
:
extensions to the Go stdlib and other useful utility code
└──
test
rotor
:
envoy service discovery bridge and xDS implementation
├──
api
├──
cache
├──
cli
├──
codec
├──
nonstdlib
├──
stats
└──
test
stats
: a standard Stats interface
to a variety of underlying backends, along with a means to configure it from
command line flags
├──
api
├──
idgen
├──
nonstdlib
└──
test
tbnctl
:
command line interface to the Turbine Labs public API
├──
api
├──
cli
├──
codec
├──
nonstdlib
└──
test
test
:
small helper packages to make writing tests in go a little easier