Hi,
On Fri, Jan 4, 2013 at 4:56 AM, Aram Hăvărneanu <
ara...@mgk.ro> wrote:
> I suggest dropping the idea of providing more Debian packages other
> than the Go distributions itself. C libraries using autotools are a
> PITA to install, and providing development Debian packages for them
> makes sense, but Go packages are not like that. apt-get as an
> alternative to go get is a solution to a problem that no one has.
That is the path taken by the Ruby (and more exactly, the Ruby Gems)
folks. It leads to a very unhappy place. I really hope Go doesn't
follow along.
There are scenarios where what you say _is_ the right solution. There
are others where it is the wrong one.
For example, consider the case of a very popular end-user-oriented
wonderful-program written in Go (and it is bound to show up sooner or
later, if one doesn't already exists). End-users want two things:
1. Easily install wonderful-program
2. Keep wonderful-program updated (security- and feature-wise) in a
somewhat automated way
For this Debian offers a great solution, which involves providing
Debian packages for Go packages. There _is_ a certain type of user
who feels comfortable (or even, prefers) following scripted
instructions ("type <this> at the prompt", "type <this> to upgrade",
...), who might find the solution you suggest acceptable, but that is
not true for every user.
Another use case where Debian provides a nice solution is for a
developer who wants to be able to code against an stable API. It
might be the case that more recent, more featureful releases of a Go
package, but I, as a developer, might be trying to provide a Debian
package for machines which are not under my control. In that
situation I like to know what the environment looks like and what's
available there (which I can express via dependencies communicated to
the packaging system).
Part of the reason for caring about the lack of shared objects is
precisely being able to provide security updates in a sane fashion.
You have to keep in mind that Debian cares about software licensing,
so it's not enough to provide a binary for a package and stick the
sources somewhere. Debian actually makes an effort to make sure that
you can rebuild that same package from the provided sources. This
means that if pkg-go-[1..n] all depend on pkg-go-0, if you update
pkg-go-0, you have to rebuild pkg-go-[1..n] and upload pkg-go-[0..n].
Maybe pkg-go-j doesn't use the code that was updated, but it has to be
rebuilt anyways because a) we need to verify that it still builds
(i.e. it still conforms to the terms of the license); b) we don't have
enough information to know, without further examination, that the
changed code doesn't affect the package (i.e. it's cheaper to just
rebuild). With shared objects this is relatively easy: update the
package providing the shared object; test the existing binaries;
rebuild everything in the dependency chain to make sure everything
still builds; upload only the updated package (and no, this is not
exactly the way Debian does it, but the concept still applies).
Another problem exhibited by the Ruby community is the lack of a
convention for specifying whether or not an API was updated and/or
broken.
With shared libraries it's relatively easy, even if it requires a lot
of discipline. The ELF headers include a SONAME, which is, within
some limits, pretty much an arbitrary string. Nothing forces you to
call something libfoo.so.1 and keep that name as long as the API is
not broken. You can add a function to the library and keep
libfoo.so.1 as the SONAME. This is a problem, because if binary foo
uses the new function, it will work as long as the libfoo.so.1 in the
system also has that function. On systems where that is not true,
stuff breaks, as you should have changed the SONAME (e.g.
libfoo.so.2). About a decade ago we had to fix a lot of stuff
precisely because of things like this. I'm guilty of developing
crutches to deal with this for specific cases, which are almost
certainly present in your computer if you happen to be using a modern
Linux distribution.
With systems that do not use shared libraries, you have to resort to
other ways of encoding this information. This is what Ruby developers
_do not_ do in the general case (and they too, have developed crutches
to deal with it). One way of dealing with this is simply encode an
API version in the package name. So your package is not foo, but
foo1. If you break your API, you switch to foo2. Many people will,
of course, have the luxury of not having to resort to this, but any
widely distributed code _should_ be doing this. Perl, with which Ruby
shares all the problems and shortcomings in this particular regard,
has, in general terms, done a wonderful job at getting things right.
Sorry to have veered off a tangent there, but I wanted to provide some
context as to why this is important.
Marcelo
PS: Where I say "Ruby", "Perl" and "Go", unless otherwise clear, I do
not mean the languages, but their respective (developer) communities.