cmd/tip: fix the build

https://golang.org/cl/52390 was submitted too early with failing trybots.

This fixes it, hiding the cloud.google.com stuff behind a build tag,
used by the Dockerfile but not the Go build system.

Change-Id: I66c6b40d4b06bf6c763f3ab221c7997856bfc910
Reviewed-on: https://go-review.googlesource.com/52470
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jessie Frazelle <me@jessfraz.com>
diff --git a/cmd/tip/Dockerfile b/cmd/tip/Dockerfile
index 3604d52..86dfe36 100644
--- a/cmd/tip/Dockerfile
+++ b/cmd/tip/Dockerfile
@@ -126,7 +126,7 @@
 
 # golang sets GOPATH=/go
 ADD . /go/src/tip
-RUN go install tip
+RUN go install --tags=autocert tip
 ENTRYPOINT ["/go/bin/tip"]
 # App Engine expects us to listen on port 8080
 EXPOSE 8080
diff --git a/cmd/tip/cert.go b/cmd/tip/cert.go
new file mode 100644
index 0000000..e00777b
--- /dev/null
+++ b/cmd/tip/cert.go
@@ -0,0 +1,50 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+// +build autocert
+
+// This file contains autocert and cloud.google.com/go/storage
+// dependencies we want to hide by default from the Go build system,
+// which currently doesn't know how to fetch non-golang.org/x/*
+// dependencies. The Dockerfile builds the production binary
+// with this code using --tags=autocert.
+
+package main
+
+import (
+	"context"
+	"crypto/tls"
+	"log"
+	"net/http"
+
+	"cloud.google.com/go/storage"
+	"golang.org/x/build/autocertcache"
+	"golang.org/x/crypto/acme/autocert"
+)
+
+func init() {
+	runHTTPS = runHTTPSAutocert
+}
+
+func runHTTPSAutocert(h http.Handler) error {
+	var cache autocert.Cache
+	if b := *autoCertCacheBucket; b != "" {
+		sc, err := storage.NewClient(context.Background())
+		if err != nil {
+			log.Fatalf("storage.NewClient: %v", err)
+		}
+		cache = autocertcache.NewGoogleCloudStorageCache(sc, b)
+	}
+	m := autocert.Manager{
+		Prompt:     autocert.AcceptTOS,
+		HostPolicy: autocert.HostWhitelist(*autoCertDomain),
+		Cache:      cache,
+	}
+	s := &http.Server{
+		Addr:      ":https",
+		Handler:   h,
+		TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
+	}
+	return s.ListenAndServeTLS("", "")
+}
diff --git a/cmd/tip/tip.go b/cmd/tip/tip.go
index 30f1864..6e0fd47 100644
--- a/cmd/tip/tip.go
+++ b/cmd/tip/tip.go
@@ -8,8 +8,6 @@
 
 import (
 	"bufio"
-	"context"
-	"crypto/tls"
 	"encoding/json"
 	"errors"
 	"flag"
@@ -25,10 +23,6 @@
 	"path/filepath"
 	"sync"
 	"time"
-
-	"cloud.google.com/go/storage"
-	"golang.org/x/build/autocertcache"
-	"golang.org/x/crypto/acme/autocert"
 )
 
 const (
@@ -44,6 +38,10 @@
 	autoCertCacheBucket = flag.String("autocert-bucket", "", "if non-empty, the Google Cloud Storage bucket in which to store the LetsEncrypt cache")
 )
 
+// runHTTPS, if non-nil, specifies the function to serve HTTPS.
+// It is set non-nil in cert.go with the "autocert" build tag.
+var runHTTPS func(http.Handler) error
+
 func main() {
 	flag.Parse()
 
@@ -64,34 +62,20 @@
 
 	log.Printf("Starting up tip server for builder %q", os.Getenv(k))
 
-	errc := make(chan error)
+	errc := make(chan error, 1)
 
 	go func() {
 		errc <- http.ListenAndServe(":8080", mux)
 	}()
 	if *autoCertDomain != "" {
+		if runHTTPS == nil {
+			errc <- errors.New("can't use --autocert without building binary with the autocert build tag")
+		} else {
+			go func() {
+				errc <- runHTTPS(mux)
+			}()
+		}
 		log.Printf("Listening on port 443 with LetsEncrypt support on domain %q", *autoCertDomain)
-		var cache autocert.Cache
-		if b := *autoCertCacheBucket; b != "" {
-			sc, err := storage.NewClient(context.Background())
-			if err != nil {
-				log.Fatalf("storage.NewClient: %v", err)
-			}
-			cache = autocertcache.NewGoogleCloudStorageCache(sc, b)
-		}
-		m := autocert.Manager{
-			Prompt:     autocert.AcceptTOS,
-			HostPolicy: autocert.HostWhitelist(*autoCertDomain),
-			Cache:      cache,
-		}
-		s := &http.Server{
-			Addr:      ":https",
-			Handler:   mux,
-			TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
-		}
-		go func() {
-			errc <- s.ListenAndServeTLS("", "")
-		}()
 	}
 	if err := <-errc; err != nil {
 		p.stop()