-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: Add a command to zip the current project and push it to a hosted repository #33312
Comments
I think this can be achieved this by this zipping up Something like: zip -r gomods.zip $GOPATH/pkg/cache/download
curl -X POST -H "Content-Type: application/zip" --data @gomods.zip
https://example.org/gomods/download And then elswhere:
Unless I'm missing something? |
@triztian I’m referring to zipping your current project rather than its dependencies and then publishing that to a remote server such as Nexus Repository Manager. This would make for a better user experience for companies that are developing their own private libraries for use by other developers or teams. |
This is closely related to #28835. |
@triztian, there are some constraints on the file paths within the They also need to omit any directory subtrees containing a |
CC @jayconrod |
Perhaps we should start with a function in |
@jlstephens89 Got it that makes sense, then yes, it's definitively missing such feature specially with the limitations that @bcmills mentioned. After looking at the linked issue #28835 it seems that the same could be achieved with a combination of For example one could still zip up the private source and then download it as a zip file and extract it somewhere on disk. After extracting one could use wget https://repsmanager.org/provider.com/some/library.zip # downloads library.zip
mkdir -p /path/to/extracted/sources
unzip library.zip -d /path/to/extracted/sources
cd myproject # the root of the project that depends on provider.com/some/library package
go mod edit -replace=provider.com/some/library=/path/to/extracted/sources
go build -mod=readonly . Doing this avoids having to pre-populate the I just did a sample test of the λ ui ~> cat go.mod
module gioui.org/ui
go 1.12
require (
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
) Performing the edit: λ ui ~> go mod edit -replace=golang.org/x/image=/opt/thirdparty/go/sources/x/image After the edit: λ ui ~> cat go.mod
module gioui.org/ui
go 1.12
require (
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
)
replace golang.org/x/image => /opt/thirdparty/go/sources/x/image Based on the |
@triztian. GOPROXY and the download API make for a very natural user experience when working with a repository manager. If we went the route of adding a command that created a zip with the correct file paths then any developer that has set GOPROXY to point to a “Group” repository, a repository type that aggregates public and private sources (or alternatively list the URLs comma separated), would have access to both internal and external dependencies with no additional effort. This would be a one time configuration for all developers in an organisation and from then on would allow centralised tooling teams to manage remotes/sources in a single place. To publish a private dependency developers could do something like “go push http://repourl” and that dependency would then be available to an entire organisation. |
At the moment, it would be hard to implement this in an external tool or in |
Actually, I think all of the logic for actually constructing the I think it would be pretty straightforward to extract that body out to a function. |
So basically it'd be a tool that performs the following HTTP (or similar) requests for the given module path?:
Append the version of this module to the ist of all known versions of the given module, one per line.
Set JSON-formatted metadata about that version of the given module.
Set the go.mod file for that version of the given module.
Set the zip archive for that version of the given module. |
@triztian that would work and some ecosystems work that way. Alternatively it could just POST the zip and leave the rest of the work to the repository manager. The repo manager could extract the mod from the zip and could update .info and list based of the version and module name provided in the upload. |
CC @dmitshur |
I think the k8s team might have already put together something in terms of a utility that can create valid Go module .zip files. I have not looked at it carefully myself, but could be something to examine for anyone here that is interested. From https://github.com/kubernetes/publishing-bot/tree/master/cmd/gomod-zip/zip.go:
There is also https://pagure.io/modist/, which I think might include the ability to create a proper Go modules zip starting with files on disk, but I haven’t looked at that recently, so not 100% sure. I don't believe either of those include pushing the result somewhere else, but one or both of them might solve the piece of the problem discussed here about how to create a canonical zip file with the same resulting hash as a zip file created by the CC @nikhita |
The k8s author here 👋 Thanks for surfacing that, @thepudds! https://github.com/kubernetes/publishing-bot/blob/master/cmd/gomod-zip/zip.go is indeed the tool used to create
The tool essentially duplicates the internal go code to achieve this. It would be really helpful if this logic were extracted out though.
We "fake" publish the repo to the local go mod cache. The code for it can be found here:
While having a zip command can be helpful, there would still be some more steps needed to actually publish the repo (as mentioned in #33312 (comment)), so IMHO a command like #28835 would be much more helpful than a simple zip command. |
@nikhita My purpose with this issue is for publishing to a Repository Manager such as Nexus Repository Manager rather than the module cache. The RM can then take care of generating/extracting the additional metadata files provided the information is available within the zip. For those purposes a simple zip and POST command would be the easiest route. |
We are using jfrog artifactory as a GOPROXY and jfrog-cli to publish go modules into the jfrog repository. For example, we use it for generated swagger API clients - we don't store generated code in git, but in Go repository. Also, we are publishing releases of libraries. I found this very convenient and I think it makes sense to have a RW Go proxy (or Go repository) and be able to publish/download modules from it. |
Change https://golang.org/cl/193557 mentions this issue: |
CL 193557 implements this as a Perhaps it would be a better fit as a standalone tool within |
Change https://golang.org/cl/202042 mentions this issue: |
zip provides three new functions: * Create - build a zip from an abstract list of files, filtering out files in submodules and vendor directories. This is useful for filtering a zip produced by a VCS tool (as the go command does). * CreateFromDir - build a zip from a directory. This is a convenience wrapper for Create. * Unzip - extract a zip file, checking various restrictions. A list of restrictions on module paths, versions, files within zips, and size limits is included in the package documentation. Both Create and Unzip enforce these restrictions. Also: copied cmd/go/internal/txtar to internal/txtar for testing. Updates golang/go#31302 Updates golang/go#33312 Updates golang/go#33778 Change-Id: I6fedb8b839a0cd991c9b210e73bafedc4b286ec5 Reviewed-on: https://go-review.googlesource.com/c/mod/+/202042 Run-TryBot: Jay Conrod <jayconrod@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
While the new zip tool creates a mechanism for packaging modules, it doesn't answer the original request about managing and consuming the module zips... It would be amazing if a module's vanity URL could redirect to an https hosted zip file. Something like setting the VCS to <meta name="go-import" content="go.vanity.dev/package zip https://somesite.com/go.vanity.dev-{version}.zip">
<meta name="go-tags" content="go.vanity.dev/package https://somesite.com/go.vanity.dev-tags.json"> Where ["1.2.3", "1.2.4", "1.2.5"] This would allow for quite a bit of flexibility in hosting module zips. |
@shaunco That should already work. In Finding a repository for a module path:
So the server needs to return a tag like the one below, and the URL needs to point to a server that implements the proxy protocol and provides the module.
This only works in module mode; GOPATH users will not be able to depend on a module like this. |
Good to know, but the ask in my was specifically to avoid needing a full blown GOPROXY server. Posting a zip file an manifest would be substantially easier. |
Note that I don't think we need to add that to |
Problem
With go.mod and GOPROXY the go tooling now has a good story for proxying open source packages but doesn't have a clear story for how best to manage and consume private packages. This is especially problematic for Repository Managers (such as Nexus Repository Manager) and makes it difficult for Go developers to share their private packages within their organizations.
Goal
Add a new command the Go CLI that creates a zip in a format that can be consumed via GOPROXY and push/POST that zip to a HTTP(s) endpoint.
This would allow Repository Managers to implement this endpoint and consume Go packages, making those packages available to Go developers via the download APIs. Go developers could then use this for sharing their private packages within their organizations.
The text was updated successfully, but these errors were encountered: