Liam Staskawicz avatar Liam Staskawicz committed a7d3028

moving src files to top level, kill makefile

Comments (0)

Files changed (7)

Makefile

-include $(GOROOT)/src/Make.inc
-
-TARG = devsrvr
-
-GOFILES = src/srvr.go \
-          src/config.go \
-          src/compilation.go
-
-include $(GOROOT)/src/Make.cmd
+package main
+
+import (
+	"os"
+	"path/filepath"
+	"time"
+)
+
+// return the most recent modified time for any file
+// in the given directory hierarchy
+func SourceModifiedMoreRecentlyThan(root string, modtime time.Time) bool {
+	mostRecentModTime := modtime
+	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
+		thistime := info.ModTime()
+		if mostRecentModTime.After(modtime) {
+			return filepath.SkipDir // don't bother
+		}
+		if thistime.After(modtime) {
+			ext := filepath.Ext(info.Name())
+			// TODO - make extensions configurable
+			if ext == ".go" || ext == ".html" || ext == ".tmpl" {
+				mostRecentModTime = thistime
+			}
+		}
+		return nil
+	})
+	return mostRecentModTime.After(modtime)
+}
+package main
+
+import (
+	"encoding/json"
+	"io/ioutil"
+	"log"
+	"path"
+	"time"
+)
+
+// data type for config information
+type Config struct {
+	DevServerAddress string
+	AppAddress       string
+	App              string
+	CrashTimeout     time.Duration
+	StartupTime      time.Duration
+	LogFile          string
+}
+
+// load a json config file with details about the app we're running
+func LoadConfig(configpath string) *Config {
+	b, err := ioutil.ReadFile(path.Join(configpath, "app.json"))
+	if err != nil {
+		log.Fatal(err.Error())
+	}
+
+	// config file defaults, overwritten by anything in the real file
+	conf := &Config{
+		"127.0.0.1:8080", // DevServerAddress
+		"127.0.0.1:8081", // AppAddress
+		"",               // App
+		100000000,        // CrashTimeout
+		time.Second / 2,  // StartupTime
+		"",               // LogFile
+	}
+
+	if err = json.Unmarshal(b, &conf); err != nil {
+		log.Fatal("ReadFile: ", err.Error())
+	}
+
+	if conf.App == "" {
+		log.Fatal("must include 'App' in your app.json")
+	}
+
+	return conf
+}
+package main
+
+import (
+	"bytes"
+	"flag"
+	"io"
+	"log"
+	"net/http"
+	"net/http/httputil"
+	"net/url"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"time"
+)
+
+type Reloader struct {
+	reverseProxy *httputil.ReverseProxy
+	config       *Config
+	appRoot      string
+	appCmd       *exec.Cmd
+	appOutBuf    bytes.Buffer
+}
+
+func main() {
+	var err error
+	var approot string
+	flag.StringVar(&approot, "approot", "", "your app root's directory path")
+	flag.Parse()
+
+	// if not specified, assume the current working directory
+	if approot == "" {
+		if approot, err = os.Getwd(); err != nil {
+			log.Fatal("Getwd: ", err.Error())
+		}
+	}
+	conf := LoadConfig(approot)
+
+	// fire up the app under development
+	proxy := httputil.NewSingleHostReverseProxy(
+		&url.URL{
+			Scheme: "http",
+			Host:   conf.AppAddress,
+			Path:   "/",
+		},
+	)
+	reloader := &Reloader{
+		config:       conf,
+		reverseProxy: proxy,
+		appRoot:      approot,
+	}
+
+	// and start proxying requests to it
+	http.Handle("/", reloader)
+	log.Println("serving", conf.DevServerAddress)
+	if err := http.ListenAndServe(conf.DevServerAddress, nil); err != nil {
+		log.Fatal("ListenAndServe: ", err.Error())
+	}
+}
+
+// main entry point.
+// if any files have changed, recompile
+// and restart the app before proxying the request
+func (r *Reloader) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	appPath := filepath.Join(r.appRoot, r.config.App)
+	if r.targetMustBeBuilt(appPath) {
+		if output, err := r.buildWithGoMake(r.appRoot); err != nil {
+			w.Write([]byte("so sorry, there appear to be some errors:\n\n"))
+			w.Write(output)
+			// TODO: a nicer template here
+			return
+		}
+	}
+	r.ensureTargetIsRunning(appPath)
+	if !r.checkForTargetErrors(w) {
+		r.reverseProxy.ServeHTTP(w, req)
+	}
+
+	// TODO - figure out how to write errors back to browser
+	// after app fails while serving request. currently, fails because the content-length
+	// header gets set somewhere, and we cann't write any more bytes to the connection.
+	// r.checkForTargetErrors(w)
+	// r.appOutBuf.Reset()
+}
+
+// build a project
+// right now, we only support calling gomake
+// but we could potentially call out to the compiler or some other build tool
+// in the future if that seems useful
+func (r *Reloader) buildWithGoMake(projectDir string) ([]byte, error) {
+	gomake := exec.Command("gomake")
+	gomake.Dir = projectDir
+	return gomake.CombinedOutput()
+}
+
+// determine whether the target app needs to be built.
+// if it doesn't exist, it must be built
+// if it already exists, check last modified timestamps on source files,
+// and if they're newer, it must be built
+func (r *Reloader) targetMustBeBuilt(appPath string) bool {
+	appFileInfo, err := os.Stat(appPath)
+	if err != nil {
+		// assume it doesn't exist - TODO: determine appropriate error type to check against...
+		return true
+	}
+	// check last modified time for both the binary and all its sources
+	if SourceModifiedMoreRecentlyThan(r.appRoot, appFileInfo.ModTime()) {
+		println("modifications detected - recompiling!")
+		if r.appCmd != nil {
+			r.appCmd.Process.Kill()
+			r.appCmd.Wait()
+			r.appCmd = nil
+		}
+		return true
+	}
+	return false
+}
+
+// start up the target app, and keep a pointer to it on the Reloader
+func (r *Reloader) ensureTargetIsRunning(appPath string) {
+	if r.appCmd != nil {
+		return
+	}
+	r.appCmd = exec.Command(appPath)
+	r.appCmd.Dir = r.appRoot
+	r.appCmd.Stdout = io.MultiWriter(os.Stdout, &r.appOutBuf)
+	r.appCmd.Stderr = io.MultiWriter(os.Stderr, &r.appOutBuf)
+	if err := r.appCmd.Start(); err != nil {
+		log.Fatal("couldn't start app:", err.Error())
+	}
+	time.Sleep(r.config.StartupTime) // give it a moment to start up...surely there's a better way?
+}
+
+func (r *Reloader) checkForTargetErrors(errDest io.Writer) bool {
+	// check for error
+	waitmsg, err := r.appCmd.Process.Wait(os.WNOHANG)
+	// TODO - on darwin, even if WaitStatus is 256, Stopped() returns false...
+	// just check directly for now, but it's not nice
+	if err != nil || waitmsg.WaitStatus != 0 { //}.Stopped()
+		errDest.Write([]byte("so sorry, not running anymore:\n\n"))
+		// NOTE: write outbuf bytes, but leave them in the buffer so we still
+		// keep the same error message in case we see subsequent reloads before
+		// the error is resolved
+		errDest.Write(r.appOutBuf.Bytes())
+		return true
+	}
+	r.appOutBuf.Reset()
+	return false
+}

src/compilation.go

-package main
-
-import (
-	"os"
-	"path/filepath"
-	"time"
-)
-
-// return the most recent modified time for any file
-// in the given directory hierarchy
-func SourceModifiedMoreRecentlyThan(root string, modtime time.Time) bool {
-	mostRecentModTime := modtime
-	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
-		thistime := info.ModTime()
-		if mostRecentModTime.After(modtime) {
-			return filepath.SkipDir // don't bother
-		}
-		if thistime.After(modtime) {
-			ext := filepath.Ext(info.Name())
-			// TODO - make extensions configurable
-			if ext == ".go" || ext == ".html" || ext == ".tmpl" {
-				mostRecentModTime = thistime
-			}
-		}
-		return nil
-	})
-	return mostRecentModTime.After(modtime)
-}

src/config.go

-package main
-
-import (
-	"encoding/json"
-	"io/ioutil"
-	"log"
-	"path"
-	"time"
-)
-
-// data type for config information
-type Config struct {
-	DevServerAddress string
-	AppAddress       string
-	App              string
-	CrashTimeout     time.Duration
-	StartupTime      time.Duration
-	LogFile          string
-}
-
-// load a json config file with details about the app we're running
-func LoadConfig(configpath string) *Config {
-	b, err := ioutil.ReadFile(path.Join(configpath, "app.json"))
-	if err != nil {
-		log.Fatal(err.Error())
-	}
-
-	// config file defaults, overwritten by anything in the real file
-	conf := &Config{
-		"127.0.0.1:8080", // DevServerAddress
-		"127.0.0.1:8081", // AppAddress
-		"",               // App
-		100000000,        // CrashTimeout
-		time.Second / 2,  // StartupTime
-		"",               // LogFile
-	}
-
-	if err = json.Unmarshal(b, &conf); err != nil {
-		log.Fatal("ReadFile: ", err.Error())
-	}
-
-	if conf.App == "" {
-		log.Fatal("must include 'App' in your app.json")
-	}
-
-	return conf
-}

src/srvr.go

-package main
-
-import (
-	"bytes"
-	"flag"
-	"io"
-	"log"
-	"net/http"
-	"net/http/httputil"
-	"net/url"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"time"
-)
-
-type Reloader struct {
-	reverseProxy *httputil.ReverseProxy
-	config       *Config
-	appRoot      string
-	appCmd       *exec.Cmd
-	appOutBuf    bytes.Buffer
-}
-
-func main() {
-	var err error
-	var approot string
-	flag.StringVar(&approot, "approot", "", "your app root's directory path")
-	flag.Parse()
-
-	// if not specified, assume the current working directory
-	if approot == "" {
-		if approot, err = os.Getwd(); err != nil {
-			log.Fatal("Getwd: ", err.Error())
-		}
-	}
-	conf := LoadConfig(approot)
-
-	// fire up the app under development
-	proxy := httputil.NewSingleHostReverseProxy(
-		&url.URL{
-			Scheme: "http",
-			Host:   conf.AppAddress,
-			Path:   "/",
-		},
-	)
-	reloader := &Reloader{
-		config:       conf,
-		reverseProxy: proxy,
-		appRoot:      approot,
-	}
-
-	// and start proxying requests to it
-	http.Handle("/", reloader)
-	log.Println("serving", conf.DevServerAddress)
-	if err := http.ListenAndServe(conf.DevServerAddress, nil); err != nil {
-		log.Fatal("ListenAndServe: ", err.Error())
-	}
-}
-
-// main entry point.
-// if any files have changed, recompile
-// and restart the app before proxying the request
-func (r *Reloader) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	appPath := filepath.Join(r.appRoot, r.config.App)
-	if r.targetMustBeBuilt(appPath) {
-		if output, err := r.buildWithGoMake(r.appRoot); err != nil {
-			w.Write([]byte("so sorry, there appear to be some errors:\n\n"))
-			w.Write(output)
-			// TODO: a nicer template here
-			return
-		}
-	}
-	r.ensureTargetIsRunning(appPath)
-	if !r.checkForTargetErrors(w) {
-		r.reverseProxy.ServeHTTP(w, req)
-	}
-
-	// TODO - figure out how to write errors back to browser
-	// after app fails while serving request. currently, fails because the content-length
-	// header gets set somewhere, and we cann't write any more bytes to the connection.
-	// r.checkForTargetErrors(w)
-	// r.appOutBuf.Reset()
-}
-
-// build a project
-// right now, we only support calling gomake
-// but we could potentially call out to the compiler or some other build tool
-// in the future if that seems useful
-func (r *Reloader) buildWithGoMake(projectDir string) ([]byte, error) {
-	gomake := exec.Command("gomake")
-	gomake.Dir = projectDir
-	return gomake.CombinedOutput()
-}
-
-// determine whether the target app needs to be built.
-// if it doesn't exist, it must be built
-// if it already exists, check last modified timestamps on source files,
-// and if they're newer, it must be built
-func (r *Reloader) targetMustBeBuilt(appPath string) bool {
-	appFileInfo, err := os.Stat(appPath)
-	if err != nil {
-		// assume it doesn't exist - TODO: determine appropriate error type to check against...
-		return true
-	}
-	// check last modified time for both the binary and all its sources
-	if SourceModifiedMoreRecentlyThan(r.appRoot, appFileInfo.ModTime()) {
-		println("modifications detected - recompiling!")
-		if r.appCmd != nil {
-			r.appCmd.Process.Kill()
-			r.appCmd.Wait()
-			r.appCmd = nil
-		}
-		return true
-	}
-	return false
-}
-
-// start up the target app, and keep a pointer to it on the Reloader
-func (r *Reloader) ensureTargetIsRunning(appPath string) {
-	if r.appCmd != nil {
-		return
-	}
-	r.appCmd = exec.Command(appPath)
-	r.appCmd.Dir = r.appRoot
-	r.appCmd.Stdout = io.MultiWriter(os.Stdout, &r.appOutBuf)
-	r.appCmd.Stderr = io.MultiWriter(os.Stderr, &r.appOutBuf)
-	if err := r.appCmd.Start(); err != nil {
-		log.Fatal("couldn't start app:", err.Error())
-	}
-	time.Sleep(r.config.StartupTime) // give it a moment to start up...surely there's a better way?
-}
-
-func (r *Reloader) checkForTargetErrors(errDest io.Writer) bool {
-	// check for error
-	waitmsg, err := r.appCmd.Process.Wait(os.WNOHANG)
-	// TODO - on darwin, even if WaitStatus is 256, Stopped() returns false...
-	// just check directly for now, but it's not nice
-	if err != nil || waitmsg.WaitStatus != 0 { //}.Stopped()
-		errDest.Write([]byte("so sorry, not running anymore:\n\n"))
-		// NOTE: write outbuf bytes, but leave them in the buffer so we still
-		// keep the same error message in case we see subsequent reloads before
-		// the error is resolved
-		errDest.Write(r.appOutBuf.Bytes())
-		return true
-	}
-	r.appOutBuf.Reset()
-	return false
-}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.