14

I host my git repositories on a personal VPS and I have one package that I want to make "go get"-able. I have tried to set everything up per the help document found by issuing "go help importpath" with no luck. No matter what I do I get the following error:

package example.com/user/package: unrecognized import path "example.com/user/package"

I've tried every combination of the mentioned META tag with the same results.

<meta name="go-import" content="example.com git http://example.com/user/package">

The actual git repository is accessible via http://example.com/user/package.git. I am able to clone it directly but I want go to download and install it properly.

Per the help document, if go makes a request to http://example.com/user/package?go-get=1 the page returned contains the META tag. If go then makes a subsequent request to http://example.com/?go-get=1 the page returned also contains the exact same META tag.

Does any special configuration need to be done on the server? I wouldn't think so since go would be accessing the repository via an http request.

I'm at my wits end. Any help you can provide would be greatly appreciated.

brian newman
  • 3,964
  • 5
  • 25
  • 24
  • This shouldn't've been closed as duplicate.The other question is about private repos on a big name server. This question is about public repos on a personal server. Opposite question really. – Sandra Feb 13 '21 at 06:32

3 Answers3

19

This is the meta tag I've configured nginx to return for a gitlab server: if you request http://mygit.server/group/project?go-get=1

you get:

<meta content='mygit.server/group/project git git+ssh://git@mygit.server/group/project.git' name='go-import'>

And it works like a charm.

Here is the nginx rewrite rule that does this:

location ~ "(/[^/]+/[^/]+)(/.*)?" {
    if ($arg_go-get = "1") {
            echo '<html><head><meta name="go-import" content="my.domain.com$1 git git+ssh://git@my.domain.com$1"/></head></html>';
    }
    try_files $uri $uri/index.html $uri.html @gitlab;
  }

This of course assumes you're working with git over ssh. If you're using https rewrite the url accordingly.

Not_a_Golfer
  • 47,012
  • 14
  • 126
  • 92
2

I've just done this for myself - similar scenario: a few small go repos and a mostly-private website. Nginx configuration:

root /var/www;

location / {
    try_files $uri?$args $uri $uri/ @my-proxy;
}

I then run:

$ echo '<html><head><meta name="go-import" content="example.com/project-name git git+ssh://example.com/~/code/magic/blah/project-name.git" /></head></html>' > /var/www/project-name\?go-get\=1
  • The query-string is embedded into a filename, which nginx serves if it exists.
  • We create a file of the appropriate (slightly weird) name per project.
  • Each file contains a minimal HTML document with the appropriate <meta /> tag

The cost is an extra stat() call per hit to the location block, but you avoid the dreaded nginx if directive and the out-of-tree echo module, and can trivially tweak the meta content per-repository.

If those weird filenames bug you, you could restrict the scope: import "example.com/code/project-name" in your .go files, andlocation /code { try_files ... } in nginx.

  • I was doing this, then ran into trouble with redirect loops, and then I realized that just putting the meta tag on the repo's web page is enough! As long as it doesn't bork on getting cgi style get req args. But like a static web page is fine. – Sandra Feb 17 '21 at 01:56
  • In other words, a static normal non-CGI web page that just throws away the `?go-get=1` part still works, if it has that meta tag. No need to embed the query string, just as long as the $uri part on its own serves up a file that has that meta. Iow just stick that meta tag in your repo's web page. – Sandra Feb 17 '21 at 02:10
2

Just to expand on @Not_a_Golfer answer, which was very helpful.

I have that for my Gerrit installation using Gitiles for browsing source code, so now godoc works (It links documentation to the right line of code):

    # http://stackoverflow.com/questions/26347516/using-go-get-on-a-personal-git-repo/26348986#26348986
    location ~ "(/[^/]+)(/.*)?" {
        if ($arg_go-get = "1") {
                echo '<html><head><meta name="go-import" content="myserver.example.com$1 git https://myserver.example.com$1"/><meta name="go-source" content="myserver.example.com$1 https://myserver.example.com/plugins/gitiles$1 https://myserver.example.com/plugins/gitiles$1/+/master/{dir} https://myserver.example.com/plugins/gitiles$1/+/master/{dir}/{file}#{line}" /></head></html>';
        }
        try_files $uri @gerrit;
    }

    location / {
        try_files $uri @gerrit;
    }
Yann
  • 170
  • 7