[Canonical-tech] Handling active dependencies in Go

roger peppe roger.peppe at canonical.com
Tue Jan 8 12:32:37 UTC 2013


On 8 January 2013 11:24, John Arbash Meinel <john.meinel at canonical.com> wrote:
> There is an option to take that next step, and create a branch for
> every revision that we want to use. Its possible, but quite a bit
> heavier weight than we are used to. Also note, it isn't possible to
> just take trunk and release it as 1.1.1, because if the import URL is
> in the juju-core code, it *also* needs to be in the 1.1.1 branch of
> goose. (otherwise when "launchpad.net/goose/nova" tries to import
> "launchpad.net/goose/identity" it will get something different than
> juju-core importing "launchpad.net/goose/1.1.1/identity")
>
> So to do a release, we need to rename all the imports inside goose,
> test that it still works, push it to the new URL, and then update
> juju-core to also rename all of its imports.

Assuming govers, the goose release should be as simple as this:

    govers launchpad.net/goose/v1.1.1
    bzr commit -m 'release v1.1.1'
    bzr push lp:goose/v1.1.1

Possibly with a go test (or maybe just go test -i ./...) there too to check that
things are still working.

Yes, the diff may be large, but given that it's a mechanical change, if we
trust the tool, we don't need to inspect it in detail.

> Launchpad uses both 'sourcedeps' for things it deploys from branches
> and buildout's 'versions.cfg' for things it deploys using eggs. To
> update a source branch, you commit it to trunk, and then the diff in
> launchpad is:
>
> - -loggerhead lp:~loggerhead-team/loggerhead/trunk-rich;revno=472
> +loggerhead lp:~loggerhead-team/loggerhead/trunk-rich;revno=473
>
> Or:
> - -testtools = 0.9.14
> +testtools = 0.9.15
>
> (aka, a 1 line change)

(genuine question) What happens about source code that still depends on the
old version? Does it search the revision history for the right version?

> Compare that to the diffs I did put up:
> https://code.launchpad.net/~gophers/goose/unstable-001/+merge/140140
> https://code.launchpad.net/~jameinel/juju-core/goose-unstable-001/+merge/140141
>
> Which is 8 lines in juju-core and 47 lines in goose.
>
> That is all scriptable (and probably helped by your program), but it
> is a lot more overhead than 1 line change to a config file.

I'm not sure that the human-time overhead is necessarily that different.

> (Not to
> mention the overhead of actually creating the 0.0.10 branch, and
> publishing to it, etc.)

Isn't that just a single "bzr push"?

> The go version is ok for a *series* (aka a real branch), but it is
> just not usable at a snapshot (aka revision) level (IMO).

I definitely understand your concerns, and I see that other systems might
make the overhead of releasing smaller, but I still think that there
are significant advantages to having all Go code declare its dependencies
explicitly, including the API version.

If we're to move forward with the conventional Go way, there's one
issue I'm not entirely clear about: should we use immutable versions
corresponding to each released change to the source, or mutable versions
corresponding to each API change?

The former has the advantage that you know exactly what you're
importing and testing against, but you incur the release overhead
every time you want to make the changes available to juju-core.
The latter means that there's less chance of version skew and you
can update internal details without the requirement to change all clients,
but you run the risk of breaking working clients with a code change that's
not careful enough.

It might be possible, I suppose, to use a combination of both
approaches - provide
a versioned path that represents an API version, and also provide a path
that represents a particular source version. That may well be the
worst of both worlds
though :-)

Aside: it's a pity that "go tool api" doesn't work with general packages.



More information about the Juju-dev mailing list