FAQ
Let's say I have packages A and B which both depend on package X.

I own package A, a friend owns package B and an internet randomer owns
package X.

We need to improve package X and we do so by temporarily forking. Internet
randomer seems happy and competent to merge pull requests, but is swamped
so it is going to take a bit of time.

A practice I've used successfully for myself until now is to checkout my
fork of X at $GOPATH/src/github.com/internet-randomer/X and then A and B
both build correctly against my fork. All is fine!

However, now ten friends come along and want to build C, which depends on A
and B. These ten friends need the new features of A and B, which means they
need the fork of X, which needs to live at $GOPATH/src/
github.com/internet-randomer/X.

I'm yet to figure out if any existing dependency management tools can
handle this. They all seem to store tuples of ($URL, $SHA) and not
($IMPORTPATH, $REPOSITORY_WHERE_SHA_CAN_BE_FOUND, $SHA).

Has someone found a good solution for this situation?

My take on it until now is that the resulting pressure to upstream the
changes to X is good. But in this case we simply can't for a while, but we
need to move on in a reproducible and sane manner.

Thanks,

- Peter

On 5 August 2014 14:48, robfig wrote:

Announcing a vendor-less dependency management tool.

https://github.com/robfig/glock

## Overview

This one is very simple. It provides 2 commands and a version control
hook:

- "glock save project" writes the transitive root package[1]
dependencies of all packages under "project/..." to a GLOCKFILE
- "glock sync project" updates all packages listed in
project/GLOCKFILE to the listed version.
- "glock install project" installs a version control hook that watches
for changes to project/GLOCKFILE and incrementally applies them.

Glock is similar to "godep -copy=false"

GLOCKFILEs are simple text files that record a root package's version, e.g.

bitbucket.org/tebeka/selenium 02df1758050f
code.google.com/p/cascadia 4f03c71bc42b
code.google.com/p/go-uuid 7dda39b2e7d5
...

## Workfow

Here's the expected flow for working with a Glock-managed repo:

1. Clone the repo
2. "glock sync" your GOPATH
3. "glock install" the hook
4. "glock save" when you add/update a dependency


## Use case

At work, we keep our Go code in one repo (rather than many small ones) and
use a single GOPATH. This tool allows us to gain reproducible builds, with
version updates automatically propagated to the team via the hook, with the
following advantages:

- We still use the normal Go toolchain / dev process (e.g. not having
to run everything in a godep sandbox). We can more easily contribute to
3rd party libraries, since they are not in a vendor sandbox or have
rewritten import paths.
- We avoid the repo bloat of checking in our dependencies (> 100 MB),
in addition to the extra churn. Updating a dependency involves a change to
one line of a text file instead of thousand-line diffs.
- Much easier and less error-prone than manually checking in
dependencies. Developers don't have to fight git because git wants to make
the project a submodule instead of just checking in the files. Running
glock on your CI server or as a pre-commit hook can ensure that any new
dependencies have been recorded.

Hope it's useful for others as well. There is some more information in
the README <https://github.com/robfig/glock>

Questions / comments?

-Rob

[1] "root package" refers to the base package in a repository. For
example, although *code.google.com/p/go.net/websocket
<http://code.google.com/p/go.net/websocket>* is a Go package, *code.google.com/p/go.net
<http://code.google.com/p/go.net>* is the "root package", and any
dependencies on non-root packages roll up to the root.

--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Roger peppe at Aug 15, 2014 at 2:18 pm

    On 15 August 2014 13:20, Peter Waller wrote:
    Let's say I have packages A and B which both depend on package X.

    I own package A, a friend owns package B and an internet randomer owns
    package X.

    We need to improve package X and we do so by temporarily forking. Internet
    randomer seems happy and competent to merge pull requests, but is swamped so
    it is going to take a bit of time.

    A practice I've used successfully for myself until now is to checkout my
    fork of X at $GOPATH/src/github.com/internet-randomer/X and then A and B
    both build correctly against my fork. All is fine!

    However, now ten friends come along and want to build C, which depends on A
    and B. These ten friends need the new features of A and B, which means they
    need the fork of X, which needs to live at
    $GOPATH/src/github.com/internet-randomer/X.

    I'm yet to figure out if any existing dependency management tools can handle
    this. They all seem to store tuples of ($URL, $SHA) and not ($IMPORTPATH,
    $REPOSITORY_WHERE_SHA_CAN_BE_FOUND, $SHA).

    Has someone found a good solution for this situation?
    Interesting problem. I think at some point any distributed
    versioning system is going to break down. Here we have
    two conflicting expectations:

    - you expect that your package should be built only against your fork of X.
    - other people expect that X lives at github.com/internet-randomer/X.

    I think the only reasonable solution is to fork X, change its
    location too (and any import paths in it) and encourage the
    ten friends to use your fork instead of the original. Perhaps
    they're using another package out of their control which also
    uses X, though. There's a fundamental conflict here, I think: you
    want your fork of X to be treated as "the" place for X, but
    you don't have control of the default repository for X.

    I think that it would be quite confusing to have a package that says that
    it imports github.com/internet-randomer/X but actually relies on
    content from an entirely separate place.

    That said, if it's explicit, then it's probably OK. Your ten
    friends could explicitly add your upstream as the default upstream
    branch to github.com/internet-randomer/X, and then everything
    should just work.

    I'm not sure I'd want my dependency tool doing that for me automatically.
    I like being able to scan through my dependencies and know
    that they've all come from the expected place.
    My take on it until now is that the resulting pressure to upstream the
    changes to X is good. But in this case we simply can't for a while, but we
    need to move on in a reproducible and sane manner.
    Talking to your downstream friends and telling them the situation
    sounds like it might be OK.

       cheers,
         rog.

    PS note that in many cases, it doesn't actually matter much if
    a given package is imported twice under different names.
    The main things to watch out for are 1) central registries and
    2) incompatible types (watch out for interfaces that use
    package-local types, such as bson.Setter in gopkg.in/mgo.v2,
    which I was bitten by recently)

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedAug 15, '14 at 12:20p
activeAug 15, '14 at 2:18p
posts2
users2
websitegolang.org

2 users in discussion

Peter Waller: 1 post Roger peppe: 1 post

People

Translate

site design / logo © 2022 Grokbase