diff --git a/.travis.yml b/.travis.yml
index 4bef48a0db28f60f7b2d387d8e129c80876ca6e4..d3b0d427c76b64df3711ed20f9b91ef18b5b6472 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,8 +12,10 @@ matrix:
         - sudo modprobe fuse
         - sudo chmod 666 /dev/fuse
         - sudo chown root:$USER /etc/fuse.conf
+        - go run build/ci.go install
+        - go run build/ci.go test -coverage
 
-    # These are the latest Go versions, only run go vet and misspell on these
+    # These are the latest Go versions.
     - os: linux
       dist: trusty
       sudo: required
@@ -24,7 +26,7 @@ matrix:
         - sudo chmod 666 /dev/fuse
         - sudo chown root:$USER /etc/fuse.conf
         - go run build/ci.go install
-        - go run build/ci.go test -coverage -vet -misspell
+        - go run build/ci.go test -coverage -misspell
 
     - os: osx
       go: 1.8
@@ -34,7 +36,7 @@ matrix:
         - brew install caskroom/cask/brew-cask
         - brew cask install osxfuse
         - go run build/ci.go install
-        - go run build/ci.go test -coverage -vet -misspell
+        - go run build/ci.go test -coverage -misspell
 
     # This builder does the Ubuntu PPA and Linux Azure uploads
     - os: linux
diff --git a/appveyor.yml b/appveyor.yml
index c1569670520c3c187896ee7871457f53446f9058..c9c2e357e8e6aa52b8fab0f9df90b3dd40879db4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -36,4 +36,4 @@ after_build:
 
 test_script:
   - set CGO_ENABLED=1
-  - go run build\ci.go test -vet -coverage
+  - go run build\ci.go test -coverage
diff --git a/build/ci.go b/build/ci.go
index 27589fc7f5a5ce0bc098f966d722726f577bed9d..62241758047ba312be2c9b9f69efdf6d8e031087 100644
--- a/build/ci.go
+++ b/build/ci.go
@@ -24,7 +24,7 @@ Usage: go run ci.go <command> <command flags/arguments>
 Available commands are:
 
    install    [ -arch architecture ] [ packages... ]                                           -- builds packages and executables
-   test       [ -coverage ] [ -vet ] [ -misspell ] [ packages... ]                             -- runs the tests
+   test       [ -coverage ] [ -misspell ] [ packages... ]                                      -- runs the tests
    archive    [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artefacts
    importkeys                                                                                  -- imports signing keys from env
    debsrc     [ -signer key-id ] [ -upload dest ]                                              -- creates a debian source package
@@ -173,19 +173,7 @@ func doInstall(cmdline []string) {
 	if flag.NArg() > 0 {
 		packages = flag.Args()
 	}
-
-	// Resolve ./... manually and remove vendor/bazil/fuse (fuse is not in windows)
-	out, err := goTool("list", "./...").CombinedOutput()
-	if err != nil {
-		log.Fatalf("package listing failed: %v\n%s", err, string(out))
-	}
-	packages = []string{}
-	for _, line := range strings.Split(string(out), "\n") {
-		if !strings.Contains(line, "vendor") {
-			packages = append(packages, strings.TrimSpace(line))
-		}
-	}
-
+	packages = build.ExpandPackagesNoVendor(packages)
 
 	if *arch == "" || *arch == runtime.GOARCH {
 		goinstall := goTool("install", buildFlags(env)...)
@@ -274,7 +262,6 @@ func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd {
 
 func doTest(cmdline []string) {
 	var (
-		vet      = flag.Bool("vet", false, "Whether to run go vet")
 		misspell = flag.Bool("misspell", false, "Whether to run the spell checker")
 		coverage = flag.Bool("coverage", false, "Whether to record code coverage")
 	)
@@ -284,23 +271,10 @@ func doTest(cmdline []string) {
 	if len(flag.CommandLine.Args()) > 0 {
 		packages = flag.CommandLine.Args()
 	}
-	if len(packages) == 1 && packages[0] == "./..." {
-		// Resolve ./... manually since go vet will fail on vendored stuff
-		out, err := goTool("list", "./...").CombinedOutput()
-		if err != nil {
-			log.Fatalf("package listing failed: %v\n%s", err, string(out))
-		}
-		packages = []string{}
-		for _, line := range strings.Split(string(out), "\n") {
-			if !strings.Contains(line, "vendor") {
-				packages = append(packages, strings.TrimSpace(line))
-			}
-		}
-	}
+	packages = build.ExpandPackagesNoVendor(packages)
+
 	// Run analysis tools before the tests.
-	if *vet {
-		build.MustRun(goTool("vet", packages...))
-	}
+	build.MustRun(goTool("vet", packages...))
 	if *misspell {
 		spellcheck(packages)
 	}
diff --git a/internal/build/util.go b/internal/build/util.go
index 4df7b91381e51fa1bb2fddbaffe0d75d9ae408eb..44f6760b95ef33d93cb7be2ac7d19dc56209b98a 100644
--- a/internal/build/util.go
+++ b/internal/build/util.go
@@ -26,6 +26,7 @@ import (
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"text/template"
 )
@@ -136,3 +137,30 @@ func CopyFile(dst, src string, mode os.FileMode) {
 		log.Fatal(err)
 	}
 }
+
+// ExpandPackagesNoVendor expands a cmd/go import path pattern, skipping
+// vendored packages.
+func ExpandPackagesNoVendor(patterns []string) []string {
+	expand := false
+	for _, pkg := range patterns {
+		if strings.Contains(pkg, "...") {
+			expand = true
+		}
+	}
+	if expand {
+		args := append([]string{"list"}, patterns...)
+		cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			log.Fatalf("package listing failed: %v\n%s", err, string(out))
+		}
+		var packages []string
+		for _, line := range strings.Split(string(out), "\n") {
+			if !strings.Contains(line, "/vendor/") {
+				packages = append(packages, strings.TrimSpace(line))
+			}
+		}
+		return packages
+	}
+	return patterns
+}
diff --git a/log/handler.go b/log/handler.go
index abb17b4c41c73002b70186442363d79dbf5b48a3..d5594b853de8d39bfbb00428a713c1aa86cade39 100644
--- a/log/handler.go
+++ b/log/handler.go
@@ -106,11 +106,16 @@ func CallerFileHandler(h Handler) Handler {
 // the context with key "fn".
 func CallerFuncHandler(h Handler) Handler {
 	return FuncHandler(func(r *Record) error {
-		r.Ctx = append(r.Ctx, "fn", fmt.Sprintf("%+n", r.Call))
+		r.Ctx = append(r.Ctx, "fn", formatCall("%+n", r.Call))
 		return h.Log(r)
 	})
 }
 
+// This function is here to please go vet on Go < 1.8.
+func formatCall(format string, c stack.Call) string {
+	return fmt.Sprintf(format, c)
+}
+
 // CallerStackHandler returns a Handler that adds a stack trace to the context
 // with key "stack". The stack trace is formated as a space separated list of
 // call sites inside matching []'s. The most recent call site is listed first.