
Indie game Haunts unable to compile its Go code - pavel_lishin
http://forums.thedailywtf.com/forums/t/27755.aspx
======
Udo
How is this Go's fault? Just because you can pull code automatically from a
remote repository doesn't mean you always should. It seems to me that keeping
the entirety of the code necessary to compile a project in a local build
directory is a very good idea if you don't want to compile against moving
targets.

~~~
tiredofcareer
You are correct. Go's remote imports are dangerous for long-term project
maintenance, but the feature is still useful for quick, throwaway projects.

Go badly needs two things:

1\. A best practice that dictates that you never import from remote
repositories in production, long-term code; the feature is fine for one-offs
and experimentation, but the article summarizes only _one_ way this style of
work can lead you in to a maintenance world of pain. What happens if the repo
you're importing from Github is deleted? What do you do for fresh clones?
You're going to end up changing the URL _anyway_. I feel the Go community has
kind of glossed over this (and I _like_ Go).

2\. An equivalent of CPAN or PyPI, which you could then import from in concert
with a tool to manage those dependencies, a la:

    
    
        import (
            "cgan/video/graphics/opengl"
        )
    

This model works for CPAN, PyPI, and so on for a reason, and that reason is
avoiding several of the dependency/merge hells that remote repos can create.
CPAN provides Perl a lot, such as distributed testing in a variety of
environments. I personally think such a thing is necessary for long-term
maintenance of any software project that utilizes third-party libraries. This
is one of Google's oversights in Go, because they have an (obviously)
different take on third-party code. Here's a good case:

 _Developer A checks out the code clean. Five minutes later, developer B
checks out the code clean. In both cases, your "go get" bootstrap script
fetches two different commits, because in that five minutes, upstream
committed a bug. Developer B cannot build or, worse, can build but has several
tests fail for unknown reasons or, even worse, the program no longer functions
properly. Developer A has none of those problems. In a world with a CPAN-like,
developer B can see that he has 0.9.1 and developer A has 0.9.0, developer B
can commit "foo/bar: =0.9.0" to the project's dependency file, then everybody
else doesn't suffer the same fate. In the current world, you're either
massaging your local fork to keep the new commit out, or any other
troublesome, non-scalable approach to this._

Building large software projects against a _repository_ never works. You need
tested, versioned, cut releases to build against, not master HEAD. It only
takes one bad upstream commit to entirely torpedo your build, and you've now
completely removed the ability to qualify a new library version against the
rest of your code base. Other people are suggesting "well, maintain your own
forks," so you're basically moving merge hell from one place to another. I,
personally, have better things to do with my time; I've seen (Java) apps with
dozens of dependencies before, and keeping dozens of repositories remotely
stable for a team of people will rapidly turn into multiple full-time jobs. Do
you want to hire two maintenance monkeys[0] to constantly keep your build
green by massaging upstream repositories, or do you want to hire two feature
developers? Exactly.

I've started writing a CPAN-like for Go a couple times but I'm always held
back by these threads:

[https://groups.google.com/forum/?fromgroups=#!topic/golang-n...](https://groups.google.com/forum/?fromgroups=#!topic/golang-
nuts/c-s4_uxamf8)

[https://groups.google.com/forum/?fromgroups=#!topic/golang-n...](https://groups.google.com/forum/?fromgroups=#!topic/golang-
nuts/-UG-lF_Ey-o)

The second one highlighting how difficult Go is to package as a language -- my
personal opinion is treat Go just like C and distribute binary libraries in
libpackage, then the source in libpackage-src. If one message in that thread
is true and binaries refuse to compile with different version compilers, I'm
troubled about Go long-term.

[0]: I'm not calling all build engineers maintenance monkeys. I'm saying the
hypothetical job we just created is a monkey job. I love you, build engineers,
you keep me green.

~~~
skybrian
You're right that syncing directly with the net is a problem. However, the
problem is basically developer education. Go doesn't work like other languages
and the consequences aren't well-documented. If you do it right, the process
works fine; it's basically how Google works internally.

The basic idea is to commit everything under $GOPATH/src so that you never
need to touch the net to reproduce your build. After running "go install" you
should check in the third-party code locally, just like any other commit.

Then updating a new third-party library to sync with their trunk is like any
other commit: run "go install", test your app, and then commit locally if it
works. If it doesn't work, don't commit that version; either wait for them to
fix it, sync to the last known good version, or patch it yourself.

If you aren't committing your dependencies then you're doing it wrong.

~~~
tiredofcareer
> If you aren't committing your dependencies then you're doing it wrong.

Disagree _strongly_ (and hate absolutes like "doing it wrong"). Their
metadata, yes, by all means, commit that. There is absolutely no reason,
however, to have the source code for a dependency in my tree, Go or not.

Give me a binary I can link against, or at least the temporary source in a
.gitignored location, and let's call it a day. When I want to bump to a new
version my commit should be a one-line version bump in a metadata file, not
the entirety of the upstream changes as a commit. I've seen a sub-1MLoC
project take 10 minutes just to _clone_. Internally! You're telling me you
want to add all the LoC and flattened change history of your dependencies in
your _repo_? Egads, no thanks! Where do you draw that line? Do you commit
glibc?

There's just no reason to store that history unless you are in the business of
actively debugging your dependencies and fixing the problems yourself, rather
than identifying the issue and rolling back to a previous version after
reporting the problem upstream. I guess it's paying your engineers to fix
libopenal versus paying your engineers to work on your product; one's a broken
shop, the other isn't. Some people will feel it's one, some the other.

~~~
skybrian
No really! Go isn't like other languages. You have to think differently.
Please try it!

There's no such thing as, say, Maven binary dependencies for Java. If you
don't check in the source code for your dependencies, your team member won't
get the same version as you have and builds won't be reproducible. You won't
be able to go back to a previous version of your app and rebuild it, because
the trunk of your dependencies will have changed. By checking in the source
code you're avoid a whole lot of hurt.

Checking in source is okay because Go source files are small and the compiler
is fast. There isn't a huge third-party ecosystem for Go yet.

~~~
tiredofcareer
> There's no such thing as, say, Maven binary dependencies for Java.

I'm saying there should be, but not necessarily the same thing. That's my
entire point.

I'm also not a fan of the "you have a dissimilar opinion to mine, so obviously
you've never used Go properly" attitude in this thread. One way to read your
last is that I've never used Go _at all_ , though I'm giving you the benefit
of the doubt and assuming you meant _used Go properly_. Either way, I don't
get the condescension of assuming I'm unaware of everything you're explaining
to me simply because I have an opinion that is different than yours.
Especially since half of your comment is repeating things to me that I said
earlier.

~~~
skybrian
Maybe it sounds like condescension. I was in the same place at the beginning.
No exceptions? No generics? Heresy. How dare you Go people ignore my many
years of experience? I wrote a few rants to the mailing list, which were
basically ignored.

The reason I assume you haven't used Go much is that your examples of problems
with checking stuff in aren't examples of problems happening in Go. It's an
analogy with other languages and other environments. Such arguments don't seem
to get very far.

Maybe it won't scale and something will have to give. I expect the Go
maintainers will find their own solution when it happens, and it won't look
like Maven or traditional shared libraries. (If anything, it might be by
replacing Git/hg with something that scales better.)

------
etchalon
I don't understand the issue, or why it's such a show stopper.

If the original programmer is using git, he should have a complete history of
his code. They know the date (or thereabout) when the last version of the code
"worked". Revert down to the a commit around that date.

For each dependency, do the same. Pull the dependencies repo down, revert to
the last commit that was around the date of the working version, and use a new
fork of that repo to get things back to the working state.

One by one, move the dependencies forward, resolving bugs as you go.

~~~
stdbrouw
Maybe they did and it didn't work? You're giving them very little credit.

~~~
etchalon
That wouldn't make any sense. Either the code worked at some point, or it
didn't.

~~~
shardling
You know, I haven't worked on _that_ much software, and I've run into
situations I at first thought impossible often enough that your comment just
makes me laugh. :P

Unlikely? Surprising? Insane? Sure. But never call something impossible unless
you can not only write down a formal proof for it but also verify your
assumptions.

~~~
thepicard
Unlikely, I would go with. It's unlikely that it couldn't be done. Based on
the level of understanding in that thread, I'm not terribly surprised.

------
ChuckMcM
Wow, that's awkward.

One of the things I spent a bit of time on when Java was being developed was
class management. We had an ongoing discussion about embedding versioning
information in class files, creating signatures that could be checked at
runtime, and just winging it. Bill Joy was convinced that it was possible to
give the class loader the ability to statically analyze a class and determine
whether or not it would work with the code that was trying to invoke it. This
was when I was first exposed to the idea of creating a digest type 'signature'
for a method/class invocation that would encode semantics.

The end result was 'just wing it' of course. This was expedient but didn't
advance the state of the art :-)

Go's implementation seems a bit more dangerous. Not the least of which being
drive by malware injection attacks on abandoned/poorly administered code
repositories. It seems in principle to be no more or less dangerous than
something like "apt-get install libcairo-dev ; make" but that would only be
true if there was a trusted repository system.

Can someone from Go comment on the ability to create and manage trusted
repositories? Should we look for a go 'distro' to build with?

~~~
yepguy
When you install a package with `apt-get`, that package can potentially change
your system in any way it pleases. Running `go get` will download and compile
code, but there is no security risk until you run or use that code without
checking it first.

~~~
reidrac
You're comparing things that are different. When you install a package with
apt-get:

\- it comes from a repository that has been signed by the distributor.

\- the package has been tested and has a good level of integration with the
system (ie different distributions may package things differently).

\- depending on the distribution, there may be a commitment to API/ABI
stability (ie. Debian backports security fixes most of the time).

That said... running "go get" is very convenient if you control the code
repository where you're fetching the code, but it's not a good idea when using
3rd party software that is in active development.

EDIT: formatting

------
collinvandyck76
Go didn't screw anything over. It sounds like poor version control practices.
Although the Go team eschews versioning of dependencies, they do so mainly
because they are in control of said dependencies. If you're building software
that relies on untrusted source code, do yourself a favor and make a copy of
it that is known to work well and use that copy in your build environment.

~~~
coolsunglasses
>Go didn't screw anything over.

Erm, yes it did. The civilized world (Java, Ruby, Python, Clojure, Scala,
Haskell, OCaml) has version numbers in their dependency management. Albeit
out-of-band from the source files (pom.xml, gemfile, requirements.txt,
project.clj, sbt, .cabal, OPAM version pinning) but it _does_ work.

Hell with Clojure and Leiningen (the standard choice for dependency mgmt) even
the language version is a per project dependency ala:

[org.clojure/clojure "1.5.1"]

So you can still build jars that "just work" even if it's some legacy stuff
that you haven't updated to the latest Clojure version yet.

That's not to say Clojure would've helped here - it's a game. And one that's
aiming for better graphics - JVM isn't a good idea.

But that doesn't excuse Go's poor package management design that decided being
facile and hid complexity of the real problems (changes breaking existing
code) was more important than working builds.

The decision to make it facile, weak, and fragile was egregious and very out-
of-character with the rest of their design decisions. I think Go can be
faulted for failing at their own goals on this particular matter.

~~~
wtbob
> Erm, yes it did. The civilized world (Java, Ruby, Python, Clojure, Scala,
> Haskell, OCaml) has version numbers in their dependency management.

Go has localised dependencies: you package your code with exactly the versions
you need.

> So you can still build jars that "just work" even if it's some legacy stuff
> that you haven't updated to the latest Clojure version yet.

And with a Go project, one would have a complete system which 'just works,'
complete with all dependencies, regardless of how old those dependencies
actually are.

> But that doesn't excuse Go's poor package management design that decided
> being facile and hid complexity of the real problems (changes breaking
> existing code) was more important than working builds.

Go doesn't do what you think it does (probably not your fault: the article is
misleading). It only pulls down updates if you tell it to. It sounds like the
developer of the original code was doing the wrong thing, not using GOPATH the
way it was designed, not checking his entire source tree—including
dependencies—into version control. I could be wrong, of course: it's possible
that he really did use it properly but discovered a misfeature I've not yet
found.

~~~
happy_dino
"The developer should have done X!", well, then why doesn't Go just do it by
default instead of choosing an approach which has been discarded by pretty
much every other modern language/ecosystem?

I think the fact that every Go proponent attacks the developer of the game is
one thing which keeps me from using Go. The community seems to be incredibly
closed-minded and hostile.

~~~
sanderjd
This line of reasoning seems to make it hard to suggest that certain things
are and aren't idiomatic in different languages without being accused of being
closed-minded and hostile. If I read an article claiming that Ruby sucks
because of some project where the developer decided to use a Makefile instead
of bundler, I would say "the developer should have used bundler!", and you
could accuse me of the same hostility you're accusing Go proponents of here.
Conventions really do exist for a reason, and really should be followed until
you understand them well enough to reject them for a good reason.

~~~
happy_dino
Amazingly, other communities manage to do that without being so utterly
condescending.

~~~
sanderjd
I'll see your anecdotes with my own; I've had nothing but extremely pleasant
interactions with the Go community and think it is much less closed-minded and
condescending than most.

------
iand
I used go get on the source code and the errors are caused by dependencies on
2 C libraries: opengl and lua. Basically the Go bindings for the C libraries
are out of date and/or unmaintained.

Sample output:

    
    
        # github.com/runningwild/glop/gos
        /usr/bin/ld: cannot find -lglop
        collect2: error: ld returned 1 exit status
        # github.com/runningwild/opengl/gl
        gl.go:142: cannot use _Ctype_GLint(mapsize) (type C.GLint) as type C.GLsizei in function argument
        gl.go:147: cannot use _Ctype_GLint(mapsize) (type C.GLint) as type C.GLsizei in function argument
        gl.go:152: cannot use _Ctype_GLint(mapsize) (type C.GLint) as type C.GLsizei in function argument
        gl.go:158: cannot use _Ctype_GLenum(internalformat) (type C.GLenum) as type C.GLint in function argument
        gl.go:164: cannot use _Ctype_GLenum(internalformat) (type C.GLenum) as type C.GLint in function argument
        gl.go:170: cannot use _Ctype_GLenum(internalformat) (type C.GLenum) as type C.GLint in function argument
    
    
    
        /usr/bin/ld: Warning: size of symbol `luaX_tokens' changed from 8 in $WORK/github.com/xenith-studios/golua/_obj/lcode.o to 256 in $WORK/github.com/xenith-studios/golua/_obj/llex.o
        /usr/bin/ld: Warning: size of symbol `luaT_typenames' changed from 8 in $WORK/github.com/xenith-studios/golua/_obj/lapi.o to 88 in $WORK/github.com/xenith-studios/golua/_obj/ltm.o
        # github.com/xenith-studios/golua
        /usr/bin/ld: Warning: size of symbol `luaX_tokens' changed from 8 in $WORK/github.com/xenith-studios/golua/_obj/lcode.o to 256 in $WORK/github.com/xenith-studios/golua/_obj/llex.o
        /usr/bin/ld: Warning: size of symbol `luaT_typenames' changed from 8 in $WORK/github.com/xenith-studios/golua/_obj/lapi.o to 88 in $WORK/github.com/xenith-studios/golua/_obj/ltm.o
    

Seems like a familiar problem that every similar language encounters when
using bindings to native code, not just a Go issue.

~~~
pygy_
The Lua issue is weird. The bindings are maintained (last update one month
ago), and the repo provides its own Lua source files (but the API of minor
versions of Lua is stable, so it shouldn't matter).

They should file an issue on GitHub.

<https://github.com/xenith-studios/golua/issues>

------
buro9
Or you could fork.

Or you could create a version of your src folder as a github checkout with
submodules for each of the things you want to import.

I struggle to see what the issue is. I knew the first time I wrote an import
in Go that this was possible, and that as the libraries for Go are relatively
young that it is also likely.

My personal preference is just to keep track of changes fairly regularly and
not allow much drift. But that's because up until Go1.1 I was following tip,
which meant I was already in that habit.

Though it would be nice if ``go get`` could take a revision or branch/tag
name.

~~~
MetaCosm
Yeah, this article made my head hurt. It can be summarized as

"Original author didn't localize dependencies, obviously caused problems."

~~~
cpleppert
I'm a little confused about how this would be an issue in the first place. I
mean, surely all the changes are checked into a repository and the working
code is on the programmers computer right??? So why doesn't he just share the
'working' code with all of the dependencies if he somehow didn't check in his
local copies of the dependencies.

I'm a little suspicious when it is claimed that the original author can't get
it to compile. That is just so strange and the simplest explanation was that
it was never in a great state anyway.

~~~
MetaCosm
Yeah... it smells a little odd, goes against the general golang development
(when you have a dep, it ends up in src and you check in src... so... yeah).

------
iand
I offered to help out on the Haunts game when they had their first round of
problems. They had lost the developer who had chosen Go and so were left with
no way to continue development. I wrote and offered my help and apparently so
did a large number of other people because we were all sent a long
questionnaire to fill in with our skills, experience and what we could offer
the project. It just seemed like a big barrier to cross simply to offer my
volunteer services, so I didn't bother completing it.

In retrospect they were probably being protective of their IPR, but erred on
the side of being overprotective and pushing away a few folk that could have
helped.

------
eric970
This might sound harsh, but...

Maintaining software is hard.

Blaming your own incompetence on a library or an entire language is easy.

I've been guilty of this at times, but when you get down to it, it's your job
as a software developer to understand how your software works and how to
maintain it well. This doesn't just include the code you write; it includes
your tools, third party libraries, and the internals of the language (VM,
compiler, etc.). Its not easy, but it's part of the job.

On a more positive note, versioning packages in Go is already possible and is
starting to gain momentum. Check out <http://www.gonuts.io/>

~~~
stdbrouw
> it's your job as a software developer to understand how your software works
> and how to maintain it well

And it's the job of language (and language ecosystem) developers to make this
as straightforward as possible. It's perfectly possible to blame both the
author and the language.

------
wtbob
I've only been writing Go for a short while, but my experience so far is that
'go get' only pulls down updated versions of dependencies if you tell it to,
with -u.

The developer should have set up a proper Go tree for his project, prepended
it to GOPATH, run 'go get DEPENDENCY1…' (which would have put the complete
current source of that dependency into his src directory) and then checked his
project tree into his VCS (adhering, of course, to the licenses of his
dependencies). Anyone who downloaded his code would have gotten the compatible
version of all dependencies from the VCS. Then when he felt it was time to
upgrade the dependency, he should have committed his work (and branched in
something like git), then run 'go get -u DEPENDENCY1…' to fetch the latest
version, which—yes—would break his code's compilation. The next step would be
to fix his code to work with the new version, then commit that.

It sounds like the guy was doing something developing his project in his main
Go tree, not putting his dependencies into version control, blindly updating
dependencies and so forth.

But possibly I missed something.

------
carbocation
Go pulls down remote repos/libraries locally. If the original developer has
any sort of backup of his system from the time the game was working, he will
have all of the working code.

If the original developer does not have that but at least hasn't nuked his src
directory, he will have all of the working code (but may need to, e.g., git
bisect).

~~~
eric970
Yeah exactly. This shit is ridiculous.

------
KirinDave
From now on, remember this anecdote every time you curse at Maven for making
dependency management a huge effing hassle unless you publish publicly on
version drops to an official repo.

Go's sin here is being permissive. And it's true that _clearly_ the game dev
team just... didn't do things right. They were pretty much on a collision
course with failure by managing their project's code the way they did. But Go
allowed them to get much further along than they otherwise would have.

------
ominous_prime
I'm not making any judgements on the project itself, or its dependencies, but
I see a lot of people just use code off github (or butbucket, or launchpad)
with no regard for the quality of said code. Just because it's on github
doesn't mean it's good code, or the maintainer has any idea what they're
doing. In general, if I can't trust a project to maintain a stable master
branch (or a Go version tag) following best practice guidelines, I'm not going
to trust that code in my project without a full review. In that case, I'd fork
it (or clone it into another VCS) and work from there.

There are some issues with the way the Go tooling handles dependencies, but I
think the minimalist way in which it does is very useful, and easy to build
upon. Go uses a distributed dependency system, and you can't give it the same
level of trust you give to centralized repositories, like one does with gems,
Pypi, NPM, CPAN, and so on.

------
stcredzero
This indie project goofed up, so now they're (probably unintentionally)
hurting Go and Kickstarter with more bad publicity. It's going to be
information that's hard for the public to properly understand, so it will
probably hurt that understanding as well.

------
lnanek2
They claim there is nothing about Go that makes it bad for games, but there
certainly is. There are no large, mature game engines for it. If someone was
hiring me to write a basic mobile game I could do with a big engine like
Cocos2D, and said I couldn't use the engine, I'd probably multiply my time
estimate by five.

I've written complex OpenGL ES games from the ground up before, and its a long
slog, especially at the end where you you are trying to crank it up to 60 FPS
and doing tons of work rewriting it to be high performance.

------
mpyne
I think everyone here saying "just fork your dependencies" is missing the idea
that it's supposed to be an open-source game.

Managing DLL hell may be acceptable to _ship_ a game, but it's not acceptable
to _openly develop_ software.

In this case it wasn't even intended to be open-source, which may be why the
dev went the route he did, but doing so essentially closed the door on the
later option of easily letting the community take over on code development.

There's a reason people codified semantic versioning. Projects like gstreamer
take it even further and make the major version part of the library name, even
allowing for co-installability of old and new (e.g. gstreamer-0.10 and
gstreamer-1.0 can both be installed and used).

~~~
stcredzero
_> Managing DLL hell may be acceptable to ship a game, but it's not acceptable
to openly develop software._

Why not? Having something that compiles and runs is probably a bit of a boon
to the development effort.

~~~
mpyne
Yes, that's my point.

It's not acceptable to merely "manage" dependency hell as the net result is
still unmanageable at OSS scale. You have to essentially eliminate the
interplay of "which exact version do I have" with your code, which is why
things like semver and soversions (on .ld.so's) try to accomplish.

Being able to have an unknown user download your code and the listed
dependencies and have a repeatable build is invaluable for development.

------
bradhe
I totally agree that packaging and dependency management is Go's weak spot,
and I've experienced similar issues. That said, I wouldn't blame this on
_golang_ per-se. I have run in to the same issues in Ruby, although versioning
is a bit better.

Whenever I see a fast-moving dependency I fork it and use my fork, then
integrate upstream changes when appropriate. If you have to do that for _every
damn dependency_ I can see that being horrible, though...

~~~
MetaCosm
Why? I can't imagine building a serious product and being dependent on a
github repo I don't personally control. It is terror inducing to even consider
any real project that would be... even if you are based on a tag or a hash,
the author can destroy or rewrite it.

~~~
numbsafari
Agreed. Also, if your dependency graph starts to get unmanageable, it's
usually a sign you've made a mistake somewhere (likely by relying on something
else that's poorly designed).

If you keep your system simple and don't rely on too many "kitchen sink"
frameworks, then keeping your own source tree of your dependencies isn't that
much different from maintaining a local repository of the same code in
compiled form (with the added benefit of having the original source
available).

------
ushi
Hmm, they have issues with dependency handling and 3rd party libraries.

Go doesn't have a gem/pip/cpan/npm/... like ecosystem, instead you import
git/mercurial repos directly. This is pretty nice for rapid development and to
test things out, but not the right approach for complex long term projects
like a game.

The original author of the game missed to include the dependencies into the
project and now they are doomed. Put the libs you rely on in your version
control, be it as a submodule.

I'm wondering if anybody is working on a package manager for Go libs... That
would be great.

~~~
dkulchenko
> I'm wondering if anybody is working on a package manager for Go libs... That
> would be great.

@aleksi is: <http://www.gonuts.io/>

------
EvanYou
Seems to me lame excuses from the original developer who made horrible version
control decisions and then abandoned ship.

~~~
TazeTSchnitzel
It's not even a Go problem, you can be equally stupid by putting "package":
"*" in npm's package.json instead of, say, "package": "1.2"

------
djvu9
IMO this is some sort of clueless scapegoating. Dependency could be an issue
in software development but only for large projects. A project with $28k
funding and probably 1 or 2 developers, seriously? And no details like lines
of code, libraries being used, etc makes it hardly plausible.

~~~
cthackers
I agree. I believe is scapegoating too. The guy that wrote the mail had no
clue about anything technical, and the other guys that help him explain,
didn't really understood what the programmer did and perhaps wasn't even a Go
dev. And it seems that the original developer just left and doesn't want
anything to do with the game anymore. So...they blame it on the language and
3th party hobby libraries from github because they can't set up the project
right. That shit happens on any language even with inhouse built libraries if
you put unskilled people to to the job.

------
xtx23
why would they use go, a language aimed at building scalable web services to
build a game is puzzling...I am not sure if people who made that decision
actually knows what they are doing. Many open source libs and system-level
linux libraries can be installed from git or github repos... that is not news
at all. Can't see why people are fighting over such things. O.O

~~~
jcromartie
Looking at their Kickstarter page, they really could have used anything.

------
frio
This sounds like a problem the community can resolve. Check
<http://golang.org/cmd/go/#hdr-Remote_import_path_syntax> \-- anyone can
create a Go "repo" by using a <meta> tag in an HTML page.

I don't think it'd be difficult to create a CGAN/GoPI/Gobal/gojars/etc. that
provided versioning.

~~~
bluehex
That's a good idea. The limitation being that your service can redirect go get
to a different repository url, but go will still fetch that repository and
check out what it thinks is the best branch for that version of go: one with
the name of the current go version, or master. So you'd have to play some
tricks to keep a full clone-able repo with master locked at some commit for
each version of each library, rather than just one repo per library with tags.
I guess there are some ways to do that where the clones share the objects so
you aren't wasting space, though so not insurmountable.

~~~
frio
Space usage doesn't worry me _too_ much. If a "package" is just a set of
files, then storing them in some sort of compressed form (.tar.gz) and simply
un-tarring them and making the API mimic a git repo with one revision should
be fairly straightforward.

------
djvu9
FYI source code at <https://github.com/mobrulesgames> It seems to me the
developers must have been working really hard and the failure is due to that
the size of the project is way too large for the two person team. It is
unavoidable and the dependency issue is just a symptom.

~~~
lunixbochs
That GitHub page tells me they _did_ clone all of the dependency repos six
months when they were trying to recover it.

If the game was finished and working but does not compile anymore, that sounds
like a trivial thing for a hardworking developer to fix in a pretty short
amount of time.

I've seen much worse when porting games across platforms. This doesn't look
even close to "beyond repair".

------
entropy_
This is ridiculous, there's a correct way to handle this and it's called git
submodules. Instead of using go get for non-trivial long-term projects you
should just be adding the dependency as a submodule in your git repo and
including the files directly. This way you can have your submodule pointing to
a specific commit in the upstream repo, you can update it when you want
to/need to and all this information is kept track of in version control.

Also, if you want even more control(ie, you want to modify the library you're
using in some way), fork it on github and include your fork as a submodule.
That way you can patch bugs easily(and send the upstream a pull request)
without having to wait for upstream to fix things you know how to fix
yourself.

------
smegel
This is ridiculous. I have come across numerous projects written in half the
languages under the sun that were impossible to build and/or run for various
reasons, mainly because the original developer had so much stuff in his
environment that it depended on. At least Go has urls to original source repos
which is a whole lot better than mysterious binary blobs that noone knows what
the hell they do let alone where they came from (but were most likely brittle
chunks of Fortran77). And if you modify someone elses code and it gets out of
sync...well that's a problem but its not Go's fault.

------
bradjs
I'm a Go developer using Go for commercial projects in production.

I can tell that the article and its comments is absolutely misleading. Seems
that the developer(s) are trying to justify the lack of professionalism and
blame language/tools/someone else. In the article I see total misunderstanding
of how the Go ecosystem works, strange decisions, obvious failures during
development and weird situations like 'original dev cannot compile the code
anymore'.

I think an engineer should have a decent understanding of the
tools/concepts/... BEFORE starting to use them. Not AFTER some problems occur.

------
landr0id
The dependency could have easily been avoided by forking the repo which you're
using, and using that instead. Obviously the maintainer(s) of the original
will be making changes, so wouldn't you want to make sure that if you're
distributing the code, you're all on the same version?

> _Why does this matter?_

Maybe I'm not understanding this, but the dependency issue and the issues in
this paragraph are not related. Issues like improper syntax? That's not
related.

Sounds like bad planning as far as the dependency stuff goes. For everything
else, sounds like a distribution issue.

~~~
eknkc
Let's say I depend on github/A and github/A depends on github/B. If I fork A,
that does not solve the problem. Now I need to fork B and modify import paths
in A to resolve my fork. Wouldn't this be a mess in time?

I assume, instedad of forking, it might be possible to import a specific tag,
or commit hash from a git repo. If it's possible, it'd solve the backward
incompatible change problem but I guess the original author can always delete
the github repo.

What is a good way to manage dependencies locally?

~~~
landr0id
I hadn't considered the A/B issue, and yeah that can get messy. Importing a
specific commit hash to the repo would be great. As far as managing
dependencies locally, I couldn't say since I haven't had much experience with
Go, but there exists a package manager called "Go Nuts" (see:
<http://www.gonuts.io/>). While obviously not widely used, it seems to fix
this issue. It's almost like rubygems all over again though.

What I'd like to see is a site similar to this, with a similar tool. Instead
of having to upload the package to the site though, you could add a `pkg.json`
file (or something similar) with application data. Every time this is
committed, the site would automatically check to see if the version has
changed, and then index that commit hash as a new version.

This almost sounds fun...

------
krakensden
It's a good point. I've had it as a worry in the back of my mind for a while
now, the 'best' solution for now seems to be linking to your own personal
forks of projects you depend on.

~~~
revscat
That's a pretty heavy solution.

~~~
potatolicious
Sure, but it's also a common solution outside of Go. I write iPhone apps and
we have all of our major dependencies forked, because at _some_ point you're
going to butt up against the limits of what your lib does. Even just
redirecting a git submodule at a later point is a minor brainfuck - so
nowadays we just instinctively fork as soon as we decide to pull it in as a
dependency.

What I really want to know is why they chose Go in the first place. Go isn't a
game development language and it has little to no support, documentation, or
just plain old previous community experience in the gaming context. This feels
like the classic software development of putting the technology ahead of the
product - using a tool because it's cool, rather than using it because it's
the best thing for the job.

It's _all_ about shipping, people. Use whatever you need to you can ship what
you want, when you want to, at the quality and reliability you desire.

~~~
pjmlp
> Sure, but it's also a common solution outside of Go.

In the C and C++ world, yes. Because they lack the software repositories many
mainstream languages have.

The problem is that we got used to Maven, Ivy, CPAN, Gems, eggs, NuGet, ...

~~~
dagw
Back when I worked on a large commercial Python project, we did the same
thing. All dependencies where on our server and that's the only place we
grabbed them from when building a new release.

~~~
pjmlp
I think the main problem is that we got used to these dependency tools, and
many developers coming to Go don't have experience how development was done
before they came into existence.

~~~
rurounijones
Or the fact that many developers look at the previous methods and quite
rightly say "That is a hideous method, we have moved on (and IMHO improved)
from that, why the hell has a new language reverted to old and busted methods"

As I said in another comment regarding Go. If any company has the ability to
create a stable, maintained CPAN / rubygems equivalent for the Go language, it
would be Google.

Which just makes the lack of it more jarring (although I see the arguments
that Go is designed for Google and may not fit other's ideas of what important
features are)

------
bbayer
I really struggle to understand what is going on here. Wrong usage of a
feature isn't tools fault. I saw lots of projects that messed up things with
gcc and Make. So can we consider gcc and Make are both broken. Developer
should know pros and cons of feature that is about to be used.

Using an unofficial release or development version of a library is always
risk. It is not language dependent. Things can always be broken if you don't
follow release notes on an actively developed project.

------
iand
It seems that Haunts uses Makefiles to wrap the Go tools so there is some non-
standard complexity there. See
[https://github.com/losinggeneration/haunts/blob/type_fixes/M...](https://github.com/losinggeneration/haunts/blob/type_fixes/Makefile)
which was linked from the 7 month old issue <https://mrg-
trac.sourcerepo.com/mrg_Haunts/ticket/34>

------
ricardobeat
It's bewildering to see a project that "can't compile" after having $70k+
poured into it. This article sums up this clusterfuck:
[http://www.joystiq.com/2012/10/24/haunts-anatomy-of-a-
kickst...](http://www.joystiq.com/2012/10/24/haunts-anatomy-of-a-kickstarter-
collapse/)

Back on topic, maybe Go should take a page from node's NPM: simple versioned
tarballs with isolated dependencies.

------
hpcorona
Wait, so, they were expecting to develop agains an X version, and then after
release, when they release the source it will compile easily for all it's
users with zero dependencies problems?

I don't see how bashing Go would help these guys out of the hole they are in,
same would have happened with any other programming language in a project that
uses fast-moving dependencies...

They were making a game, they could have just forked the projects they needed,
and build from that, that's the way to do these kind of projects, you stick on
a revision, and when there is an update on a dependency, the team should agree
to make the upgrade changing all the required source code.

For what they say, the main developer had no idea that the repositories were
changing a lot, and he never updated them, so everything was going thru
smoothly... I don't see the need to bash Go, neither the main programmer, i
just believe he needed more experience to handle the project correctly.

What i don't like is their attitude "nobody can fix this Go garbage code
because Go is all wrong"...

------
eric970
I love how people jumped all over Go on that thread, without having any idea
of what they are talking about.

Gotta love the Internets.

------
uvTwitch
It's a poor workman who blames his tools.

------
meshko
Wow, how is this Go's fault? Shouldn't it be obvious that one has to be very
careful when patching upstream libraries and maintain a forked repository
and/or submit patches upstream?

~~~
prodigal_erik
Did they have a fork with local changes? The way I read it, they just did

    
    
      import "github.com/go-gl/opengl/gl"
    

and then at some point the go-gl project (which they don't manage) made
incompatible changes that broke their build. Presumably there is some version
of go-gl they could build against (which happened to be cached on their
developer's machine), but they don't know which one because there's no version
or tag in that string.

~~~
meshko
But this is what software development is all about anyways... it's like
complaining that they have to type a lot in order to get _anything_ working.
My whining detector went off.

------
codygman
I'm willing to bet that any Go programmer worth their salt not tired of the
project can get it running if it were simply build dependency version issues.

I'll take a stab at it this weekend (if I have time).

For the curious, here is their repo: <https://github.com/runningwild/haunts>

------
cthackers
I bet tomorrow morning half of people here will download and backup their 3th
party libraries :). And perhaps even burn them on a CD (just to be safe)

------
p0nce
Death march project fail, blame the tools.

------
bencollier49
From the Kickstarter trailer: "If we don't get this game out by Halloween,
something will claim our souls".

------
orangethirty
Question: Could we give Open Source git repos permalinks?

~~~
stdbrouw
What do you think the hashes are for? :-)

~~~
orangethirty
Well, I know. But seems people need to be told about it in a different manner.
Not every product fails due to the product itself. Sometimes the failure is
due to how it is referred to. If we had something like _permalink this repo_ ,
then people who be moved to used that.

------
qompiler
This project was haunted from the get-go.

------
scrapcode
Go fuck itself?

