Repository: uber-go/fx
Pull request #685 (2019-11-10 23:26:26)

Migrate to Go modules
This migrates Fx to Go modules. This simplifies some of the build and CI
setup in the process.

I've left the glide.yaml in place for legacy ecosystems.

A test that referred to import paths of vendored dependencies had to be
fixed.

We should wait until uber-go/dig#250 is released before we do this,
though.

codecov[bot]: # [Codecov](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=h1) Report
> Merging [#685](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=desc) into [master](https://codecov.io/gh/uber-go/fx/commit/9e3de39f43114f6cc5993e0b2460e710b5bb4f9b?src=pr&el=desc) will **increase** coverage by `0.72%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/uber-go/fx/pull/685/graphs/tree.svg?width=650&token=PYY9PSfaC6&height=150&src=pr)](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #685      +/-   ##
==========================================
+ Coverage   96.01%   96.74%   +0.72%     
==========================================
  Files          10       12       +2     
  Lines         427      430       +3     
==========================================
+ Hits          410      416       +6     
+ Misses         12       11       -1     
+ Partials        5        3       -2
```


| [Impacted Files](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [internal/fxlog/sample.git/sample.go](https://codecov.io/gh/uber-go/fx/pull/685/diff?src=pr&el=tree#diff-aW50ZXJuYWwvZnhsb2cvc2FtcGxlLmdpdC9zYW1wbGUuZ28=) | `0% <0%> (ø)` | |
| [internal/fxlog/foovendor/foovendor.go](https://codecov.io/gh/uber-go/fx/pull/685/diff?src=pr&el=tree#diff-aW50ZXJuYWwvZnhsb2cvZm9vdmVuZG9yL2Zvb3ZlbmRvci5nbw==) | `0% <0%> (ø)` | |
| [internal/fxreflect/fxreflect.go](https://codecov.io/gh/uber-go/fx/pull/685/diff?src=pr&el=tree#diff-aW50ZXJuYWwvZnhyZWZsZWN0L2Z4cmVmbGVjdC5nbw==) | `93.33% <0%> (+10%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=footer). Last update [9e3de39...fc2993d](https://codecov.io/gh/uber-go/fx/pull/685?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

abhinav: Ready for review.

Patch:
diff --git a/.build/build_vendored.sh b/.build/build_vendored.sh
deleted file mode 100755
index 87101c6..0000000
--- a/.build/build_vendored.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-
-# build_vendored.sh builds executables from vendored code inside a repository.
-# For example,
-#
-# 	build_vendored.sh .bin go.uber.org/thriftrw
-#
-# Will build the version of thriftrw at vendor/go.uber.org/thriftrw and place
-# the executable at .bin/thriftrw.
-#
-# This is better than doing `go install ./vendor/go.uber.org/thriftrw` because
-# it takes care of fetching dependencies of the installed package (if it uses
-# Glide) and does not change the globally installed version.
-
-if [[ "$VERBOSE" == "1" ]]; then
-	set -x
-fi
-
-if [[ -z "$2" ]]; then
-	echo "USAGE: $0 DIR IMPORTPATH"
-	echo ""
-	echo "The binary at IMPORTPATH will be built and saved to DIR."
-	exit 1
-fi
-
-if [[ ! -d vendor ]]; then
-	echo "Must be run from a directory containing vendored code."
-	exit 1
-fi
-
-function die() {
-	echo "$1" >&2
-	exit 1
-}
-
-function abspath() {
-	(cd "$1" || die "Directory $1 does not exist"; pwd)
-}
-
-# findGlideLock dir looks for glide.lock in dir or any of its parent
-# directories.
-#
-# Returns the full path to glide.lock or an empty string.
-function findGlideLock() {
-	if [[ -e "$1/glide.lock" ]]; then
-		echo "$1/glide.lock"
-		return
-	fi
-
-	if [[ "$GOPATH/src" == "$1" ]]; then
-		return
-	fi
-
-	findGlideLock "$(abspath "$1/..")"
-}
-
-outputDir="$1"
-importPath="$2"
-
-# not an absolute path
-if [[ "${outputDir#/}" == "$outputDir" ]]; then
-	outputDir="$(pwd)/$outputDir"
-fi
-
-GOPATH=$(mktemp -d)
-export GOPATH
-
-ln -s "$PWD/vendor" "$GOPATH/src" || die "Failed to symlink vendor"
-cd "$GOPATH/src/$importPath" || die "Cannot find $importPath"
-
-# We have dependencies
-glideLock=$(findGlideLock "$GOPATH/src/$importPath")
-if [[ -n "$glideLock" ]]; then
-	(cd "$(dirname "$glideLock")" && glide install) || die "Could not install dependencies"
-	trap 'rm -rf $(dirname $glideLock)/vendor' EXIT
-fi
-
-go build -o "$outputDir/$(basename "$importPath")" . || dir "Failed to build"
diff --git a/.build/check_license.sh b/.build/check_license.sh
deleted file mode 100755
index bb53dae..0000000
--- a/.build/check_license.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-set -eo pipefail
-
-DIR="$(cd "$(dirname "${0}")/.." && pwd)"
-cd "${DIR}"
-
-run_update_license() {
-  go install ./vendor/go.uber.org/tools/update-license
-  # doing this because of SC2046 warning
-  for file in $(find . -name '*.go' | grep -v \./vendor); do
-    update-license "$@" "${file}"
-  done
-}
-
-if [ -z "${DRY_RUN}" ]; then
-  run_update_license
-else
-  DRY_OUTPUT="$(run_update_license --dry)"
-  if [ -n "${DRY_OUTPUT}" ]; then
-    echo "The following files do not have correct license headers."
-    echo "Please run make license and amend your commit."
-    echo
-    echo "${DRY_OUTPUT}"
-    exit 1
-  fi
-fi
diff --git a/.gitignore b/.gitignore
index c6dced3..607f44f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ coverage.txt
 *.pprof
 /.bin
 /.cache
+/bin
diff --git a/.travis.yml b/.travis.yml
index e8c932c..0c4e173 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,17 +1,24 @@
-language: go
 sudo: false
-
+language: go
 go_import_path: go.uber.org/fx
-go:
-  - 1.11.x
-  - 1.12.x
 
-cache:
-  directories:
-    - vendor
+env:
+  global:
+    - GO111MODULE=on
+
+matrix:
+  include:
+  - go: 1.12.x
+  - go: 1.13.x
+    env: LINT=1
 
 install:
-  - make dependencies
+  - make install
 
 script:
-  - make ci
+  - test -z "$LINT" || make lint
+  - make test
+
+after_success:
+  - make cover
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index af7647c..9b51e37 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## [Unreleased]
+### Changed
+- Migrated to Go modules.
+
 ## [1.9.0] - 2019-01-22
 ### Added
 - Add the ability to shutdown Fx applications from inside the container. See
@@ -175,6 +179,7 @@ promising API compatibility between beta releases and the final 1.0.0 release.
 In fact, we expect our beta user feedback to require some changes to the way
 things work. Once we reach 1.0, we will provider proper version compatibility.
 
+[Unreleased]: https://github.com/uber-go/fx/compare/v1.9.0...HEAD
 [1.9.0]: https://github.com/uber-go/fx/compare/v1.8.0...v1.9.0
 [1.8.0]: https://github.com/uber-go/fx/compare/v1.7.1...v1.8.0
 [1.7.1]: https://github.com/uber-go/fx/compare/v1.7.0...v1.7.1
diff --git a/Makefile b/Makefile
index dadb70c..c75c442 100644
--- a/Makefile
+++ b/Makefile
@@ -1,59 +1,42 @@
-PKGS ?= $(shell glide novendor)
-PKG_FILES ?= *.go
-
-# The linting tools evolve with each Go version, so run them only on the latest
-# stable release.
-GO_VERSION := $(shell go version | cut -d " " -f 3)
-GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION)))
-LINTABLE_MINOR_VERSIONS := 12
-ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),)
-SHOULD_LINT := true
-endif
-
-.PHONY: dependencies
-dependencies:
-	@echo "Installing Glide and locked dependencies..."
-	glide --version || go get -u -f github.com/Masterminds/glide
-	glide install
-	@echo "Installing uber-license tool..."
-	update-license || go get -u -f go.uber.org/tools/update-license
-ifdef SHOULD_LINT
-	@echo "Installing golint..."
-	go install ./vendor/golang.org/x/lint/golint
-else
-	@echo "Not installing golint, since we don't expect to lint on" $(GO_VERSION)
-endif
+export GOBIN ?= $(shell pwd)/bin
+
+GOLINT = $(GOBIN)/golint
+
+GO_FILES := $(shell \
+	find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
+	-o -name '*.go' -print | cut -b3-)
+
+.PHONY: build
+build:
+	go build ./...
+
+.PHONY: install
+install:
+	go mod download
 
 .PHONY: test
 test:
-	@.build/test.sh
+	go test -race ./...
 
-.PHONY: license
-license:
-	$(ECHO_V).build/check_license.sh
+.PHONY: cover
+cover:
+	go test -race -coverprofile=cover.out -coverpkg=./... ./...
+	go tool cover -html=cover.out -o cover.html
 
-.PHONY: ci
-ci: SHELL := /bin/bash
-ci: test lint
-	bash <(curl -s https://codecov.io/bash)
+$(GOLINT):
+	go install golang.org/x/lint/golint
 
 .PHONY: lint
-lint:
-ifdef SHOULD_LINT
+lint: $(GOLINT)
 	@rm -rf lint.log
 	@echo "Checking formatting..."
-	@gofmt -d -s $(PKG_FILES) 2>&1 | tee lint.log
-	@echo "Installing test dependencies for vet..."
-	@go test -i $(PKGS)
+	@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
 	@echo "Checking vet..."
-	@go vet ./... 2>&1 | tee -a lint.log;
+	@go vet ./... 2>&1 | tee -a lint.log
 	@echo "Checking lint..."
-	@$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;)
+	@$(GOLINT) ./... | tee -a lint.log
 	@echo "Checking for unresolved FIXMEs..."
 	@git grep -i fixme | grep -v -e vendor -e Makefile -e .md | tee -a lint.log
 	@echo "Checking for license headers..."
-	@DRY_RUN=1 .build/check_license.sh | tee -a lint.log
+	@./checklicense.sh | tee -a lint.log
 	@[ ! -s lint.log ]
-else
-	@echo "Skipping linters on" $(GO_VERSION)
-endif
diff --git a/checklicense.sh b/checklicense.sh
new file mode 100755
index 0000000..345ac8b
--- /dev/null
+++ b/checklicense.sh
@@ -0,0 +1,17 @@
+#!/bin/bash -e
+
+ERROR_COUNT=0
+while read -r file
+do
+	case "$(head -1 "${file}")" in
+		*"Copyright (c) "*" Uber Technologies, Inc.")
+			# everything's cool
+			;;
+		*)
+			echo "$file is missing license header."
+			(( ERROR_COUNT++ ))
+			;;
+	esac
+done < <(git ls-files "*\.go")
+
+exit $ERROR_COUNT
diff --git a/glide.lock b/glide.lock
deleted file mode 100644
index 4fb9226..0000000
--- a/glide.lock
+++ /dev/null
@@ -1,44 +0,0 @@
-hash: 71b848dcf5bde6b02fd7ca7cf3ac1e7628dd27e7248f3823900bce9a78005038
-updated: 2018-09-20T11:31:48.18331584-07:00
-imports:
-- name: go.uber.org/atomic
-  version: 1ea20fb1cbb1cc08cbd0d913a96dead89aa18289
-- name: go.uber.org/dig
-  version: 7ff117f761a3f1b3eb521945c17a1091438eb6de
-  subpackages:
-  - internal/digreflect
-  - internal/dot
-- name: go.uber.org/multierr
-  version: 3c4937480c32f4c13a875a1829af76c98ca3d40a
-testImports:
-- name: github.com/davecgh/go-spew
-  version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73
-  subpackages:
-  - spew
-- name: github.com/pmezard/go-difflib
-  version: 792786c7400a136282c1664665ae0a8db921c6c2
-  subpackages:
-  - difflib
-- name: github.com/stretchr/testify
-  version: f35b8ab0b5a2cef36673838d662e249dd9c94686
-  subpackages:
-  - assert
-  - require
-- name: go.uber.org/goleak
-  version: 1ac8aeca0a53163331564467638f6ffb639636bf
-  subpackages:
-  - internal/stack
-- name: go.uber.org/tools
-  version: ce2550dad7144b81ae2f67dc5e55597643f6902b
-  subpackages:
-  - update-license
-- name: golang.org/x/lint
-  version: 06c8688daad7faa9da5a0c2f163a3d14aac986ca
-  repo: https://github.com/golang/lint
-  vcs: git
-  subpackages:
-  - golint
-- name: golang.org/x/tools
-  version: 4e70a1b26a7875f00ca1916637a876b5ffaeec59
-  subpackages:
-  - cover
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..31fdede
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,12 @@
+module go.uber.org/fx
+
+go 1.13
+
+require (
+	github.com/stretchr/testify v1.4.0
+	go.uber.org/dig v1.8.0
+	go.uber.org/goleak v0.10.0
+	go.uber.org/multierr v1.4.0
+	golang.org/x/lint v0.0.0-20190930215403-16217165b5de
+	golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..281f903
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,60 @@
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/dig v1.8.0 h1:1rR6hnL/bu1EVcjnRDN5kx1vbIjEJDTGhSQ2B3ddpcI=
+go.uber.org/dig v1.8.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
+go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4=
+go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI=
+go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
+go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508 h1:0FYNp0PF9kFm/ZUrvcJiQ12IUJJG7iAc6Cu01wbKrbU=
+golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/tools.go b/tools.go
new file mode 100644
index 0000000..aecc9e8
--- /dev/null
+++ b/tools.go
@@ -0,0 +1,28 @@
+// Copyright (c) 2019 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// +build tools
+
+package fx
+
+import (
+	// Tools we use during development.
+	_ "golang.org/x/lint/golint"
+)


Test patch:
diff --git a/.build/test.sh b/.build/test.sh
deleted file mode 100755
index e870e8b..0000000
--- a/.build/test.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-echo "" > coverage.txt
-
-# aggregate coverage from multiple packages
-for d in $(go list ./... | grep -v vendor); do
-    go test -race -coverprofile=profile.out -covermode=atomic "$d"
-    if [ -f profile.out ]; then
-        cat profile.out >> coverage.txt
-        rm profile.out
-    fi
-done
diff --git a/internal/fxlog/fxlog_test.go b/internal/fxlog/fxlog_test.go
index 5d55479..aab0d0e 100644
--- a/internal/fxlog/fxlog_test.go
+++ b/internal/fxlog/fxlog_test.go
@@ -138,7 +138,7 @@ func TestPrint(t *testing.T) {
 		logger.PrintProvide(assert.New)
 		assert.Contains(
 			t, sink.String(),
-			"*assert.Assertions <= vendor/github.com/stretchr/testify/assert.New()")
+			"*assert.Assertions <= github.com/stretchr/testify/assert.New()")
 	})
 
 	t.Run("printFooVendorPath", func(t *testing.T) {