Skip to content

JaredReisinger/cbp

Repository files navigation

cbp

build status test coverage Go Report Card commitizen friendly semantic-release
version commit layers license

Super-simple Golang remote import path service.

Usage

Let's say you have your source hosted on GitHub (https://github.com/example/my-awesome-go-package), but you really want the package exposed via your vanity domain, as go.example.org/my-awesome-go-package. All you need to do is:

cbp https://github.com/example

Once you ensure that HTTP traffic for go.example.org is connected to the cbp started above, requests for go.example.org/my-awesome-go-package will result in a response containing the meta tag:

<meta
  name="go-import"
  content="go.example.org/my-awesome-go-package git https://github.com/example/my-awesome-go-package"
/>

(If the block above is blank, it’s because the markdown renderer isn’t escaping the angle brackets in the HTML example—I’m looking at you, docker.com—you should instead see this same README on GitHub for a more-accurate rendering.)

In the case of this example, if you were to visit http://go.example.org/my-awesome-go-package in a web browser, you'd see something that looks like:

go.example.org/my-awesome-go-package

This is the same information that's in the meta tag, but in an easier-to-read format.

Or, if you have (say) a private company-wide Subversion service with three levels to get to an individual project (for /organization/team/project), hosted at svn://svn.internal.example.org, and you again want that exposed (again internally) as go.internal.example.org/..., you can use:

cbp --vcs svn --depth 3 svn://svn.internal.example.org

And again with proper traffic routing, requests to import go.internal.example.org/group/team/project will be redirected to svn://svn.internal.example.org/group/team/project:

<meta
  name="go-import"
  content="go.internal.example.org/group/team/project git svn://svn.internal.example.org/group/team/project"
/>

go.internal.example.org/group/team/project

  • VCS: svn
  • Repository root: svn://svn.internal.example.org/group/team/project

Options

long short description
--addr address -a address/port on which to listen (defaults to ":http")
--depth number -d number of path segments to respository root (defaults to 2, minus any segments from --import-prefix)
--help -h help for cbp
--import-prefix nameAndOrPath -i hostname and/or leading path for the custom import path; the 'Host' header of each incoming request is used by default
--vcs vcsType version control system (VCS) name for the repos (default "git")
--version show version for cbp

Further reading

For a detailed description of the mechanism at play, please see the go documentation for remote import paths.

Caveats

  • It only handles mapping for a particular import host to a single backend repository server.

  • It assumes (and requires) that all revision-control roots are the same number of path components long (2, by default). It has to do so because it dead-reckons the repository root rather than verifying against it or requiring pre-registration.

On the plus side, because of these restrictions, no advance registration of repositories is needed; the service does not need to be informed/updated when a new repo is created. It blindly assumes that given a request for path foo... all it really has to do is glue the repo-prefix onto it.

Why "cbp"?

CBP is the common initialism for the U.S. Customs and Border Protection, which deals with customs and importing, and this service is all about custom import paths.

Developing / contributing

This repo is "commitizen-friendly", despite being a golang project and not a Node.js/npm project. The caveat is that you need to have commitizen and cz-conventional-changelog installed locally/globally and on your path for git-cz to give you the interactive prompt.

If you are building locally, you will need to run go generate at least once to create the version information. There's no Makefile or magefile.go because that seems like overkill for something like this. Besides, the go generate is run by the CI, so any "real" releases will include the proper version information.

Guidelines / Notes to self...

As I re-work the internals, here are the guidelines I'm following:

  • Defaults should accomodate the 80/20 rule. In the majority of cases, the service will run on the root endpoint for a given hostname. Further, all modern tools send the HTTP Host header. Therefore, the import path prefix to strip doesn't need to be specified at all; cbp can simply parse the request path as the path on the VCS.

  • Testing should be robust. Creating good, robust tests is an art. The goal is to test "what do we expect as a result", not "was this implemented a particular way". The former will detect changes in behavior, while the latter often need to be "fixed" for even minor code changes.