<div dir="ltr"><div>Several months ago, I posted a message asking about the Golang Portgroup and offline builds[1] and got one response which suggested that this was a broader ecosystem problem[2]. There are problems unique to how the MacPorts Golang portgroup handles `go.vendors` and how it does so *differently* than the Cargo portgroup handles `cargo.crates`, and it makes it such that using `go.vendors` for Go packages is wasteful, inconvenient, and IMO the wrong choice with the v1 portgroup.</div><div><br></div><div>For those not familiar with Golang portgroup internals, the handle_set_go_vendors proc attempts to translate the provided `go.vendors` package into a source repository package, with whole project and subproject support for GitHub-based packages (this is broken; see below) and whole project support on Bitbucket, gitlab, <a href="http://salsa.debian.org">salsa.debian.org</a>, <a href="http://git.sr.ht">git.sr.ht</a>, and <a href="http://go.googlesource.com">go.googlesource.com</a> — with no support for other domains. This means that, although `go install` will work for a cloned repository because of the way that `go mod` works (this is the way forward; also see below), it cannot be resolved into a meaningful dependency by the portgroup, leaving online builds as the only viable option.</div><div><br></div><div>The fact that project and subproject support is entirely repository based is a much bigger problem with the v1 portgroup than it might appear, because it means that multiple archive files must be downloaded for different tags. In the case of `<a href="http://gopkg.in/yaml`">gopkg.in/yaml`</a>, if I refer to both `v2` and `v3`, then I’ve duplicated that twice. But when I start adding AWS dependencies:</div><div><br></div><div>```</div><div>$ go get <a href="http://github.com/aws/aws-sdk-go-v2/aws">github.com/aws/aws-sdk-go-v2/aws</a><br>$ go get <a href="http://github.com/aws/aws-sdk-go-v2/config">github.com/aws/aws-sdk-go-v2/config</a><br>$ go get <a href="http://github.com/aws/aws-sdk-go-v2/service/dynamodb">github.com/aws/aws-sdk-go-v2/service/dynamodb</a><br></div><div>```</div><div><br></div><div>I’m now downloading the *full repository archive* for each and every direct and transitive dependency in that repository. In February, I found that it was downloading > 10 copies of the Google Cloud repository, and would be doing the same for the AWS and Azure SDKs as well. If GitHub allowed one to request a *partial* archive, this would be less problematic, but it is not possible.</div><div><br></div><div>However, Go has already solved this problem and provides authenticated sources for those subprojects through GOPROXY:</div><div><br></div><div>```</div><div>$ curl <a href="https://proxy.golang.org/github.com/aws/aws-sdk-go-v2/service/dynamodb/@v/v1.34.6.info">https://proxy.golang.org/github.com/aws/aws-sdk-go-v2/service/dynamodb/@v/v1.34.6.info</a><br>{"Version":"v1.34.6","Time":"2024-08-22T18:48:12Z","Origin":{"VCS":"git","URL":"<a href="https://github.com/aws/aws-sdk-go-v2">https://github.com/aws/aws-sdk-go-v2</a>","Subdir":"service/dynamodb","Hash":"d1d210dd11afc2ef0efa2e980d6b6c09cac0f5cb","Ref":"refs/tags/service/dynamodb/v1.34.6"}}<br></div><div>$  curl -sSL <a href="https://proxy.golang.org/github.com/aws/aws-sdk-go-v2/service/dynamodb/@v/v1.34.6.zip">https://proxy.golang.org/github.com/aws/aws-sdk-go-v2/service/dynamodb/@v/v1.34.6.zip</a> -O</div>$ ls -l v1.34.6.zip<br>.rw-r--r--@ 315k austin 22 Aug 15:17   -I v1.34.6.zip<div><div>```</div><div><br></div><div>It's only a little more complicated when pulling down these files when referencing hashes, but Google is providing the package infrastructure while making it *look* like it's just a Git clone (it sometimes is, but not often).</div><div><br></div><div>This, by the way, is really close to what the `rust::handle_crates` proc does, with explicit support for `cargo.crates_github`.</div><div><br></div><div>I’d like to explore how this might be approached as it would allow us to take advantage of the same sort of caching that the Cargo portgroup provides and will result in smaller build directories (only the required code from each subresource is included), faster builds, and as far as I can tell, working with *any* dependency module URI.</div><div><br></div><div>There are some challenges to this:</div><div><ol><li>Go's hash calculations are stable based on the *contents* of the dep zipfile[3], not the zipfile itself. (An approach *similar* to this would likely be advisable for Macports itself as we were affected by the GitHub archive apocalypse[4]. It would require changing every hash calculation, though.)</li><li>go2port would need to be updated, but I think that this would *simplify* the approach by allowing it to only parse `go.mod` and/or `go.sum` for the target repo), and not all ports would be able to use even this new offline approach.<br></li><li>I don't really know where to begin to explore this, and if I get it working for a few test cases, I don't know the process for upstreaming this.</li></ol></div><div>-a</div><br clear="all"><div>[1] <a href="https://marc.info/?l=macports-dev&m=170796760520486&w=2">https://marc.info/?l=macports-dev&m=170796760520486&w=2</a></div><div>[2] It might be, but many ecosystems—including Go—handle offline build requirements with vendoring.</div><div>[3] <a href="https://cs.opensource.google/go/x/mod/+/refs/tags/v0.20.0:sumdb/dirhash/hash.go">https://cs.opensource.google/go/x/mod/+/refs/tags/v0.20.0:sumdb/dirhash/hash.go</a></div><div>[4] <a href="https://github.blog/changelog/2023-01-30-git-archive-checksums-may-change/">https://github.blog/changelog/2023-01-30-git-archive-checksums-may-change/</a><br><span class="gmail_signature_prefix">--</span></div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Austin Ziegler • <a href="mailto:halostatue@gmail.com" target="_blank">halostatue@gmail.com</a> • <a href="mailto:austin@halostatue.ca" target="_blank">austin@halostatue.ca</a><br><a href="http://www.halostatue.ca/" target="_blank">http://www.halostatue.ca/</a> • <a href="http://twitter.com/halostatue" target="_blank">http://twitter.com/halostatue</a></div></div></div>