Syntax-K

Know-How für Ihr Projekt

Publishing Packages for The Go Programming Language

Last updated: 2011-07-14

Jörg Walter <golang@syntax-k.de>

Change Log of this article

Introduction

Sooner or later, you will want to publish some of your code. Many contemporary programming languages have a package repository where authors can upload their code for others to use. Go has something similar.

The Dashboard

Go has a very simple, yet modern and effective public package distribution system. In contrast to other languages' official code repositories, it is decentralized by design. There is only a central place where you can find information about packages, the Package Dashboard.

Repositories

The Package Dashboard serves as a central registry, but not as repository. Code is intended to be stored in public DVCS repositories. To benefit from Go's install mechanism and the Dashboard, you should use one of these free services:

Which one you choose is a matter of taste. The difference are in the details. You should base your decision on the source code management software you want to use, as this piece of software is the part you will be using more often than the website of the hosting service.

Short Introduction into Source Control

A word on source code management (SCM) systems: The suggested hosting services all offer state-of-the-art distributed version control systems. That's the most sensible thing you could possibly use if you're publishing open-source code. Older popular SCM systems are CVS and SVN, but they are significantly inferior. CVS is considered broken by design, while SVN more or less only fixes that brokenness without providing the power of the newer distributed systems.

Why do you benefit?

Even if you didn't use any SCM before, when you start to develop a Go project, start using SCM right from the start. It's not much to learn, but you will come to appreciate it.

The number one killer feature of source control, even if you are just a single developer maintaining a 500-line standalone program, is the ability to go back in time. Imagine your program grows, you add features, and one day you notice something which used to work doesn't anymore. With SCM, it is trivial to check out any older release that you ever committed to the repository. You can check when exactly the feature broke, compare current and past code and fix it in no time.

There are plenty of other reasons for retrieving past versions. Compatibility with older systems or APIs since left behind, bug-compatibillity for some crucial data file, you name it.

For larger projects, other features become indispensable. SCM makes it easy and safe for multiple people to work on the same code at the same time, for example. Complex projects often maintain several versions of their software at once. SCM makes this possible through branches and offers tools to apply changes of one branch to another branch as well so that bugs can be fixed in all branches.

How it works

In a version-control system, you first check out your repository, do your changes, then commit those changes. During commit, you summarize your changes in a commit message. Later, you can easily find out when you did what, and for what reason. Once you have your checked-out repository, you usually only do the edit-commit cycle over and over again. Commit often! Do small changes, commit after each one, then you get a nice, detailed timeline of your work. This is very important, as you can only time-travel from commit to commit.

Once more users get the privilege to edit your repository, the cycle gets another step, update. Then it is like update-edit-update-commit. Updates can be skipped many times, but should two people edit the same code at the same time, conflicts may occur. The SCM system will notify you of that, you will need to update and resolve those conflicts. This is a big improvement over any other code sharing mechanism, because you will never accidentally overwrite other people's work, nor will they.

In a distributed SCM system, you don't even need permission of the repository owner to check out code, edit it, and commit your changes. You clone the original repository, work on it, and when you think your work is done, you can send your changes to the original author as a code donation. If the original author doesn't maintain his library or you two disagree on what to do, you can just publish your own repository, and it will include all neccessary information to merge both repositories later on.

Here is how it works in the Mercurial DVCS using the Bitbucket hosting service:

# Create a local copy of your (actually, any) repository
hg clone https://your-username@bitbucket.org/your-username/

# ... make some changes ...

# Commit your changes. Commit often!
hg commit

# That's it! Make more changes, commit again, over and over again.

# It's time to publish your changes. For this, you must have
# write access to the cloned repository.
hg push

Of course, there are many more possibilities, but this is the bare minimum to get you started. As you can see, it's no big deal. Since you are using a nice public hosting service, you can use the web interface to view what you did, to view older revisions and so on. No need to learn the Mercurial commands for that.

Once a second developer regularly wants to contribute code, you can give her write access to your repository. Then you should consult a Mercurial tutorial to find out how updating and pulling other people's changes work.

Joel Spolsky has written a great Mercurial Tutorial which explains how everything works and what you can do with a DVCS. The Git tutorial isn't nearly as detailed but should suffice for anyone already familiar with SCM systems in general.

What DVCS should I use?

Between the three DVCSs mentioned above, there is no fundamental difference. If you already know one, use that. Your time is better spend creating code than learning another SCM.

If you aren't yet into SCM, or you come from CVS/SVN, I'd suggest Mercurial. People say it's a little less powerful than Git (I can't tell, I don't know Git in much detail), but it's easier to get started. If you really insist on knowing the background, you may want to see this comparison between Git and Mercurial. I don't know Bazaar at all, so I don't know how this fits into the picture.

Again, please don't worry too much. There are no big mistakes waiting for you to make. Just choose one and then write code.

Organizing Your Code

Once you have signed up for the code hoster of your choice, create a repository named exactly like the package you want to write. This is important!

You may also use a common repository for all of your packages and then use one subdirectory for each package, but this may not show up on the Package Dashboard as nicely, so I suggest the former until you are more experienced to decide on your own.

Your code should be buildable using gomake. This involves creating a suitable Makefile, but no fear! You don't need to mess with hideous autoconf scripts or the like. It just works. Read the rest of the linked document to find out how to structure your code.

Installing

Now that you have a public repository and a completely working Go library (one that builds when you type "gomake", and one that passes all tests when you type "gotest" -- you did write tests, didn't you?), and your code is already published and showing up in the web interface, it's time to get users to install and use it.

goinstall bitbucket.org/your-username/your-package

Yes, that's it. It doesn't print anything if successful and runs too fast to be true. No worries, it did work. Your package is now importable like this:

import "bitbucket.org/your-username/your-package"

This naming convention is the reason why it's recommended to name your repository after the package. If you named your repository differently, it wouldn't match the package name used to access the package's types and function. This can get quite confusing, so you better make sure both match.

The Package Dashboard Revisited

Now all Go coders worldwide can use your library. But how do you make your package show up on the Dashboard? After installing your package, visit the Package Dashboard, and you may notice your package is already listed. How did that happen?

goinstall publishes your package repository every time someone installs it. That way, users have a central location to search for new packages and you even get a usage count. In the rare case you don't want to publish your published code (huh?), like when doing some testing, there is a command line switch to inhibit the Dashboard submission.

On the Dashboard, there is also a Project List. If you want your project to be listed there, you need to submit it manually, including a short description.

Conclusion

Now you should be able to quickly set up a new publicly available Go package. Hopefully, you're also convinced that source control is a Good Thing™ and will commit often.

Have fun creating awesome code!

Document History


  2011-07-14  added tutorial links
  2011-07-14  fixed package name / import path relationship description
  2011-07-14  initial release

License

Creative   Commons License
Publishing Packages for The Go Programming Language by Jörg Walter is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.