1. 12
  1. 4

    My current preferred style for apps (not libraries), is to supply a Makefile that does:

    1. constructs a $CWD/build directory
    2. sets GOPATH to this directory
    3. uses something like gpm or godep with -copy=false (which is sadly now deprecated) to fetch libs at desired checkouts/revisions into the build gopath tree
    4. symlink CWD to $CWD/build/src/github.com/username/project (or whatever the actual location of the app I am developing)
    5. use env GOPATH="constructed:go:path" go install to build/install the app
    6. perform any other tasks, such as building man pages, etc.
    7. construct final package (rpm, tar, etc), reaching into the build dir as needed.

    Vendoring, while popular and seemingly what the community is converging on, “feels” to me like a wrong/inelegant solution. Maybe I am just nuts or have some unique mental baggage against it?

    The two things come to mind when I introspect my own feelings of dislike for vendoring:

    • For small apps sometimes I am pulling 10x LOC in as dependencies vs what is in-tree. I care less about overall repo size, as couple extra MB of source isn’t the end of the world. It is wasteful for fetching over slow links though (tethered, poor internet). However, I do care quite a bit about readability of history and the GIANT diffs of vendored code when a dep changes.

    • Vendoring code often lowers the barrier to people making small changes to vendored code in-tree, creating what is effectively “a hidden fork in place”. This makes it much harder to update vendored code when/if the time comes, and sharing the improvements amongst other internal projects down the road becomes more difficult. Instead, the less future-frictionless solution would be to try to push changes upstream, or to just actively fork the project into its own external repo. The barrier to “oh I will just hack this one thing in place just this one time” becomes much lower when vendoring in-tree.

    1. 1

      That sounds very close to what I want to do. Do you have an example of such a Makefile?

      1. 1

        I do: Makefile

    2. 1

      The most problematic piece of the conventional Go project layouts is its expectation that your Go code resides in a repository of its own as a subdirectory of GOROOT. I’d really like the tools to accept environments where GOPATH is the root of a version control repository rather than a subdirectory of src/.

      1. 4

        I don’t understand your comment, can you clarify? GOPATH has no enforced relation to GOROOT. For example I have GOPATH=$HOME and GOROOT=/usr/local/go.

        Also I think people forget that GOPATH is a list of paths, so you could have something like GOPATH=project1:project2:stdlib

        1. 2

          Err, typo: s/GOROOT/GOPATH. My general concern is that many organizations find it useful to maintain a single, large repository for all of their projects rather than one-repo-per-project (ex: Google, Facebook, …). This isn’t something that godep handles. The ability to commit everything under a GOPATH (including vendor’d code), or even code across different languages (such as when you have .proto files to share), simplifies many workflows.

      2. 1

        This deserves a mod up for the pictures alone. But good read, too.

        1. 1

          Thanks. It was a lot of fun making those packages and then taking gopher pictures.

          I have an album with more gopher photos on Google+.