Skip to content
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

all: change package manager from dep to go mod #1542

Merged
merged 59 commits into from
Sep 3, 2019
Merged

all: change package manager from dep to go mod #1542

merged 59 commits into from
Sep 3, 2019

Conversation

leighmcculloch
Copy link
Member

@leighmcculloch leighmcculloch commented Jul 26, 2019

PR Checklist

PR Structure

  • This PR has reasonably narrow scope (if not, break it down into smaller PRs).
  • This PR avoids mixing refactoring changes with feature changes (split into two PRs
    otherwise).
  • This PR's title starts with name of package that is most changed in the PR, ex.
    services/friendbot

Thoroughness

  • This PR adds tests for the most critical parts of the new functionality or fixes.
  • I've updated any docs (developer docs, .md
    files, etc... affected by this change). Take a look in the docs folder for a given service,
    like this one.

Release planning

  • I've updated the relevant CHANGELOG (here for Horizon) if
    needed with deprecations, added features, breaking changes, and DB schema changes.
  • I've decided if this PR requires a new major/minor version according to
    semver, or if it's mainly a patch change. The PR is targeted at the next
    release branch if it's not a patch change.

Summary

Converts the mono repo from using the dep package manager to using the go mod that has become the standard dependency manager in recent releases of Go.

Goal and scope

Make the monorepo more accessible to Go developers using standard Go tooling. Modules will be enabled by default in Go 1.13, and were enabled by default when not using a GOPATH in Go 1.11+.

Close #1634

Summary of changes

  • Add a go.mod file that contains the same dependencies and dependency versions/hashes/sources.
  • Add a go.sum which is the smallest set of hashes required to validate that the dependencies at those versions remain consistent.
  • Add a go.list which is a way for us to visibly see when our dependencies change. Note: This is not a standard file, but is something we can use to validate reproducibility until the go mod commands provide something similar.
  • Update CircleCI and TravisCI builds so that they succeed
  • Update CircleCI and TravisCI builds so that they fail if any of the above go.* files are out of date.
  • Update documentation within the repository
  • Test that other projects can import this repo. (This will be much easier, unfortunately, to test after merging, but I am currently attempting to test this before merging.)
  • Remove the existing dep files, Gopkg.toml and Gopkg.lock. (This will occur just before merging.)

Follow ups after merging

Known limitations & issues

This change bumps our minimum supported version of Go to 1.11.4. Versions prior to that version contained a bug when Modules are in use that prevented the importing of some packages. There are more details about the issue here: golang/go#30446 (comment).

What shouldn't be reviewed

It is unlikely going to be possible for you to review the go.mod, go.sum, and go.list files. The first two were auto-generated by go mod init and go mod tidy, and by a dozen subsequent go get commands to tell Go to use specific versions for specific libraries. The third is a capture of the output of go list -m all which lists all the dependencies of the project.

I used a tool I wrote yesterday deplockgomoddiff to compare our Gopkg.lock with the output of go list -m all. go list -m all is the recommended command mentioned here for validating dependencies when migrating to Modules to ensure we have alignment. The recommendation is to manually compare the output of that command with the dependencies we expected, but due to our large number of repositories it was impractical to do manually, hence the tool.

@leighmcculloch
Copy link
Member Author

leighmcculloch commented Aug 30, 2019

After sanity checking vendor directories generated by both tools, I've identified six packages that are different. I missed them because of a bug in deplockgomoddiff (leighmcculloch/deplockgomoddiff@872f6d2).

  • github.com/rcrowley/go-metrics
  • golang.org/x/crypto
  • golang.org/x/net
  • golang.org/x/sys
  • golang.org/x/text
  • gopkg.in/yaml.v2

I'll get these adjusted before this is merged in, the diff here should change very little.

Copy link
Contributor

@bartekn bartekn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Minor issues and questions.

.circleci/config.yml Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
services/horizon/internal/docs/developing.md Outdated Show resolved Hide resolved
go.list Show resolved Hide resolved
@leighmcculloch leighmcculloch mentioned this pull request Aug 30, 2019
7 tasks
leighmcculloch added a commit that referenced this pull request Aug 30, 2019
Remove `.travis.yml` and support for testing this repository on Travis CI.

Simplify the CI files we need to manage and maintain. @bartekn pointed out in #1542 (comment) that we don't use TravisCI anymore and we shouldn't keep it around and expect it to be kept up to date. For contributors who fork the repository and have TravisCI installed as an application in their GitHub account TravisCI also runs in addition to CircleCI because this file is present, which is distracting given it's not the build system we're relying on.
@leighmcculloch
Copy link
Member Author

Including the changes in unmerged PRs #1685 #1688 and comparing vendor directories using the pattern below, the vendored dependencies appear essentially same. Capturing commands and output below as a reference if I want to reattempt it.


  1. Get a vendor directory generated by each:
$ rm -fr vendor
$ dep ensure -v
$ mv vendor ~/devel/vendor-dep
$ go mod vendor
$ mv vendor ~/devel/vendor-mod
  1. Find the list of files that are different:
$ diff -qr vendor-dep vendor-mod
...
  1. The output was long, but it showed that the only difference was vendor-dep had extra files that vendor-mod didn't have. It's possible Modules is smarter about what files to include or exclude based on things like build constraints, which packages are actually used, etc, so I narrowed it down to only .go and .s (assembly) files, and reduced the output to a list of packages. This is what I get:
$ diff -qr ~/devel/vendor-dep ~/devel/vendor-mod | grep '\.\(go\|s\)$' | cut -d':' -f1 | sort -u | sed 's$^Only in /home/leighmcculloch/devel/vendor-dep/$$' | xargs -I {} echo {}       
github.com/aws/aws-sdk-go                                                                                                                                                                
github.com/aws/aws-sdk-go/service                                                                                                                                                        
github.com/btcsuite/btcd                                                                                                                                                                 
github.com/btcsuite/btcd/btcec                                                                                                                                                           
github.com/btcsuite/btcutil/base58                                                                                                                                                       
github.com/ethereum/go-ethereum/core                                                                                                                                                     
github.com/klauspost/compress/flate                                                                                                                                                      
github.com/klauspost/cpuid                                                                                                                                                               
github.com/lib/pq/oid                                                                                                                                                                    
github.com/stretchr/testify                                                                                                                                                              
golang.org/x/crypto/ssh                                                                                                                                                                  
golang.org/x/net/html/atom                                                                                                                                                               
golang.org/x/net/publicsuffix                                                                                                                                                            
golang.org/x/sys/unix                                                                                                                                                                    
golang.org/x/text                                                                                                                                                                        
golang.org/x/text/encoding/charmap                                                                                                                                                       
golang.org/x/text/encoding/htmlindex                                                                                                                                                     
golang.org/x/text/encoding/internal/identifier                                                                                                                                           
golang.org/x/text/encoding/japanese                                                                                                                                                      
golang.org/x/text/encoding/korean                                                                                                                                                        
golang.org/x/text/encoding/simplifiedchinese                                                                                                                                             
golang.org/x/text/encoding/traditionalchinese                                                                                                                                            
golang.org/x/text/internal                                                                                                                                                               
golang.org/x/text/internal/language                                                                                                                                                      
golang.org/x/text/internal/language/compact                                                                                                                                              
golang.org/x/text/language                                                                                                                                                               
golang.org/x/text/secure                                                                                                                                                                 
golang.org/x/text/unicode                                                                                                                                                                
golang.org/x/text/unicode/bidi                                                                                                                                                           
golang.org/x/text/unicode/norm                                                                                                                                                           
google.golang.org/appengine
  1. We can then take that list and compare it to the list of packages that go list returns to see which dep are including that are referenced by the code, or by a dependency we're using.
$ join <(diff -qr ~/devel/vendor-dep ~/devel/vendor-mod | grep '\.\(go\|s\)$' | cut -d':' -f1 | sort -u | sed 's$^Only in /home/leighmcculloch/devel/vendor-dep/$$') <(go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' all | sort -u)
github.com/btcsuite/btcd/btcec
github.com/btcsuite/btcutil/base58
github.com/klauspost/compress/flate
github.com/klauspost/cpuid
github.com/lib/pq/oid
golang.org/x/net/html/atom
golang.org/x/net/publicsuffix
golang.org/x/sys/unix
golang.org/x/text/encoding/charmap
golang.org/x/text/encoding/htmlindex
golang.org/x/text/encoding/internal/identifier
golang.org/x/text/encoding/japanese
golang.org/x/text/encoding/korean
golang.org/x/text/encoding/simplifiedchinese
golang.org/x/text/encoding/traditionalchinese
golang.org/x/text/internal
golang.org/x/text/internal/language
golang.org/x/text/internal/language/compact
golang.org/x/text/language
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm

Modules is definitely more aggressive at pruning packages and files that aren't required, so it isn't surprising we'd have some files not being included. I don't yet fully understand why the above shows packages not being included when they're in the go list, but it's possible the go list command is pulling packages that don't actually get compiled into the application. I suspect that because I sampled the first dependency btcec and I couldn't find it referenced via the code paths we use, or the two packages dependent on it that we import. There's not enough documentation published about the intricacies of go list and go mod vendor that explains why the above is happening.

I think the above is still okay for the following reasons:

  • The entire source is capable of building and all tests run and pass. This is a strong signal that Modules has all the packages and files it needs in its module checkout which has the entire packages and not a pruned version of them like what we get with the vendor directory.
  • The only diffs between the two vendors were files pruned out by Modules and there were no files that contained different contents that's strong signal that both dep and Modules are downloading the same dependencies. If dependencies were different we'd expect to see some changed files.

This test I documented above is just to compare vendor directories and we shouldn't plan to use the vendor directory. go mod vendor is so aggressive at pruning that it breaks some cgo packages that aren't strictly storing files where they need to be storing them for the Go tool to identify that they are required. The github.com/ethereum/go-ethereum package is one package that doesn't do this properly yet.

@leighmcculloch leighmcculloch merged commit 42ae51d into stellar:master Sep 3, 2019
@leighmcculloch leighmcculloch deleted the gomod branch September 3, 2019 21:54
leighmcculloch added a commit to stellar-deprecated/integration-tests that referenced this pull request Sep 4, 2019
Remove use of `dep` and update version of Go to Go 1.13.

The `stellar/go` repo was changed in stellar/go#1542 to use the build-in Go Modules instead of Dep for dependency management. The standard `go` commands can now be relied on for downloading and installing dependencies without any need to run any additional commands like we had to with Dep. Go 1.13 is the latest version of Go and we should use it for these tests since the repository no longer supports Go 1.10.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move repo dependency management from go dep to modules
5 participants