@@ -9,14 +9,17 @@ import (
99 "flag"
1010 "fmt"
1111 "io/fs"
12+ "io/ioutil"
1213 "log"
1314 "net"
1415 "net/http"
1516 "os"
1617 "os/exec"
18+ "os/signal"
1719 "path/filepath"
1820 "runtime"
1921 "strings"
22+ "syscall"
2023 "time"
2124
2225 "golang.org/x/tools/go/packages"
@@ -31,38 +34,50 @@ import (
3134)
3235
3336func init () {
34- flags ()
35- folders ()
36- }
37- func flags () {
3837 flag .IntVar (& port , "port" , 8080 , "The port at which to serve http." )
3938 flag .StringVar (& host , "host" , "127.0.0.1" , "The host at which to serve http." )
4039 flag .DurationVar (& nap , "poll" , quarterSecond , "The interval to wait between polling the file system for changes." )
4140 flag .IntVar (& parallelPackages , "packages" , 10 , "The number of packages to test in parallel. Higher == faster but more costly in terms of computing." )
4241 flag .StringVar (& gobin , "gobin" , "go" , "The path to the 'go' binary (default: search on the PATH)." )
43- flag .BoolVar (& cover , "cover" , true , "Enable package-level coverage statistics. Requires Go 1.2+ and the go cover tool. " )
42+ flag .BoolVar (& cover , "cover" , true , "Enable package-level coverage statistics." )
4443 flag .IntVar (& depth , "depth" , - 1 , "The directory scanning depth. If -1, scan infinitely deep directory structures. 0: scan working directory. 1+: Scan into nested directories, limited to value." )
4544 flag .StringVar (& timeout , "timeout" , "0" , "The test execution timeout if none is specified in the *.goconvey file (default is '0', which is the same as not providing this option)." )
4645 flag .StringVar (& watchedSuffixes , "watchedSuffixes" , ".go" , "A comma separated list of file suffixes to watch for modifications." )
4746 flag .StringVar (& excludedDirs , "excludedDirs" , "vendor,node_modules" , "A comma separated list of directories that will be excluded from being watched." )
4847 flag .StringVar (& workDir , "workDir" , "" , "set goconvey working directory (default current directory)." )
4948 flag .BoolVar (& autoLaunchBrowser , "launchBrowser" , true , "toggle auto launching of browser." )
49+ flag .BoolVar (& leakTemp , "leakTemp" , false , "leak temp dir with coverage reports." )
5050
5151 log .SetOutput (os .Stdout )
5252 log .SetFlags (log .LstdFlags | log .Lshortfile )
5353}
54- func folders () {
55- _ , file , _ , _ := runtime .Caller (0 )
56- here := filepath .Dir (file )
57- reports = filepath .Join (filepath .Join (here , "/web/client" ), "reports" )
58- }
5954
6055func main () {
6156 flag .Parse ()
6257 log .Printf (initialConfiguration , host , port , nap , cover )
6358
59+ tmpDir , err := ioutil .TempDir ("" , "*.goconvey" )
60+ if err != nil {
61+ log .Fatal (err )
62+ }
63+ reports := filepath .Join (tmpDir , "coverage_out" )
64+ if err := os .Mkdir (reports , 0700 ); err != nil {
65+ log .Fatal (err )
66+ }
67+ if leakTemp {
68+ log .Printf ("leaking temporary directory %q\n " , tmpDir )
69+ } else {
70+ defer func () {
71+ if err := os .RemoveAll (tmpDir ); err != nil {
72+ log .Printf ("failed to clean temporary directory %q: %s\n " , tmpDir , err )
73+ }
74+ }()
75+ }
76+
77+ done := make (chan os.Signal )
78+ signal .Notify (done , os .Interrupt , syscall .SIGTERM , syscall .SIGINT )
79+
6480 working := getWorkDir ()
65- cover = coverageEnabled (cover , reports )
6681 shell := system .NewShell (gobin , reports , cover , timeout )
6782
6883 watcherInput := make (chan messaging.WatcherCommand )
@@ -83,7 +98,13 @@ func main() {
8398 if autoLaunchBrowser {
8499 go launchBrowser (listener .Addr ().String ())
85100 }
86- serveHTTP (server , listener )
101+ srv := serveHTTP (reports , server , listener )
102+
103+ <- done
104+ log .Println ("shutting down" )
105+ if err := srv .Shutdown (nil ); err != nil {
106+ log .Printf ("failed to shutdown: %s\n " , err )
107+ }
87108}
88109
89110func browserCmd () (string , bool ) {
@@ -179,24 +200,16 @@ func createListener() net.Listener {
179200 return l
180201}
181202
182- func serveHTTP (server contract.Server , listener net.Listener ) {
183- serveStaticResources ()
184- serveAjaxMethods (server )
185- activateServer (listener )
186- }
187-
188203//go:embed web/client
189204var static embed.FS
190205
191- func serveStaticResources () {
206+ func serveHTTP ( reports string , server contract. Server , listener net. Listener ) * http. Server {
192207 webclient , err := fs .Sub (static , "web/client" )
193208 if err != nil {
194209 log .Fatal (err )
195210 }
196211 http .Handle ("/" , http .FileServer (http .FS (webclient )))
197- }
198212
199- func serveAjaxMethods (server contract.Server ) {
200213 http .HandleFunc ("/watch" , server .Watch )
201214 http .HandleFunc ("/ignore" , server .Ignore )
202215 http .HandleFunc ("/reinstate" , server .Reinstate )
@@ -205,36 +218,18 @@ func serveAjaxMethods(server contract.Server) {
205218 http .HandleFunc ("/status" , server .Status )
206219 http .HandleFunc ("/status/poll" , server .LongPollStatus )
207220 http .HandleFunc ("/pause" , server .TogglePause )
208- }
209221
210- func activateServer (listener net.Listener ) {
211- log .Printf ("Serving HTTP at: http://%s\n " , listener .Addr ())
212- err := http .Serve (listener , nil )
213- if err != nil {
214- log .Println (err )
215- }
216- }
217-
218- func coverageEnabled (cover bool , reports string ) bool {
219- return (cover &&
220- ensureReportDirectoryExists (reports ))
221- }
222-
223- func ensureReportDirectoryExists (reports string ) bool {
224- result , err := exists (reports )
225- if err != nil {
226- log .Fatal (err )
227- }
228- if result {
229- return true
230- }
222+ http .Handle ("/reports" , http .FileServer (http .Dir (reports )))
231223
232- if err := os .Mkdir (reports , 0755 ); err == nil {
233- return true
234- }
235-
236- log .Printf (reportDirectoryUnavailable , reports )
237- return false
224+ log .Printf ("Serving HTTP at: http://%s\n " , listener .Addr ())
225+ ret := & http.Server {}
226+ go func () {
227+ err := http .Serve (listener , nil )
228+ if err != nil {
229+ log .Println (err )
230+ }
231+ }()
232+ return ret
238233}
239234
240235func exists (path string ) (bool , error ) {
@@ -281,20 +276,16 @@ var (
281276 watchedSuffixes string
282277 excludedDirs string
283278 autoLaunchBrowser bool
284-
285- reports string
279+ leakTemp bool
286280
287281 quarterSecond = time .Millisecond * 250
288282 workDir string
289283)
290284
291285const (
292- initialConfiguration = "Initial configuration: [host: %s] [port: %d] [poll: %v] [cover: %v]\n "
293- pleaseUpgradeGoVersion = "Go version is less that 1.2 (%s), please upgrade to the latest stable version to enable coverage reporting.\n "
294- coverToolMissing = "Go cover tool is not installed or not accessible: for Go < 1.5 run`go get golang.org/x/tools/cmd/cover`\n For >= Go 1.5 run `go install $GOROOT/src/cmd/cover`\n "
295- reportDirectoryUnavailable = "Could not find or create the coverage report directory (at: '%s'). You probably won't see any coverage statistics...\n "
296- separator = string (filepath .Separator )
297- endGoPath = separator + "src" + separator
286+ initialConfiguration = "Initial configuration: [host: %s] [port: %d] [poll: %v] [cover: %v]\n "
287+ separator = string (filepath .Separator )
288+ endGoPath = separator + "src" + separator
298289)
299290
300291// This method exists because of a bug in the go cover tool that
0 commit comments