func Example() {
	// Create file watcher
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatalln(err)
	}
	defer watcher.Close()

	// Watch dir
	err = watcher.Watch("/path/to/watched/dir")
	if err != nil {
		log.Fatalln(err)
	}

	// Start LiveReload server
	lr, err := lrserver.New(lrserver.DefaultName, lrserver.DefaultPort)
	if err != nil {
		log.Fatalln(err)
	}
	go lr.ListenAndServe()

	// Start goroutine that requests reload upon watcher event
	go func() {
		for {
			event := <-watcher.Event
			lr.Reload(event.Name)
		}
	}()

	// Start serving html
	http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
		rw.Write([]byte(html))
	})
	http.ListenAndServe(":3000", nil)
}
Exemple #2
0
// launchServer sets up the http fileserver. Exciting!
func launchServer() {
	r := mux.NewRouter().
		StrictSlash(true)

	// Grab all our config junk and prepare to launch
	ip := viper.GetString("ListenAddr")
	port := viper.GetInt("ListenPort")
	fmt.Println(viper.GetInt("ListenPort"))

	// I... I guess, if you want TLS, you can totally have it
	cert, key := viper.GetString("CertFile"), viper.GetString("KeyFile")
	useTLS := len(cert) > 0 && len(key) > 0
	scheme := "https"
	if !useTLS {
		if port == 0 {
			port = 80
		}
		scheme = "http"
	} else if port == 0 {
		port = 443
	}

	p := fmt.Sprintf("%s:%d", ip, port)

	root, files := viper.GetString("ServerRoot"), viper.GetString("StaticFiles")

	reload, err := lr.New(lr.DefaultName, lr.DefaultPort)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	go reload.ListenAndServe()

	r.PathPrefix(root).
		Handler(
			handlers.CombinedLoggingHandler(
				os.Stdout, injectReload(root, files, scheme),
			),
		)

	go func() {
		fmt.Printf("Launching ogload on %s\n", p)
		if !useTLS {
			if err := http.ListenAndServe(p, r); err != nil {
				fmt.Printf("Server failed! scheme=%s, addr=%s, err=%v\n", scheme, p, err)
				os.Exit(1)
			}
			return
		}

		if err := http.ListenAndServeTLS(p, cert, key, r); err != nil {
			fmt.Printf("TLS Server failed! scheme=%s, addr=%s, err=%v\n", scheme, p, err)
			os.Exit(1)
		}
	}()

	wait := watchDir(files, reload)
	<-wait
}
Exemple #3
0
func start() {
	lr := lrserver.New(lrserver.DefaultName, lrserver.DefaultPort)
	go lr.ListenAndServe()
	loopIndex := 0
	buildDelay := buildDelay()

	started := false

	go func() {
		for {
			loopIndex++
			mainLog("Waiting (loop %d)...", loopIndex)
			eventName := <-startChannel

			mainLog("receiving first event %s", eventName)

			mainLog("sleeping for %d milliseconds", buildDelay)
			time.Sleep(buildDelay * time.Millisecond)
			mainLog("flushing events")

			flushEvents()

			mainLog("Started! (%d Goroutines)", runtime.NumGoroutine())
			err := removeBuildErrorsLog()
			if err != nil {
				mainLog(err.Error())
			}

			errorMessage, ok := build()
			if !ok {
				mainLog("Build Failed: \n %s", errorMessage)
				if !started {
					os.Exit(1)
				}
				createBuildErrorsLog(errorMessage)
			} else {
				if started {
					stopChannel <- true
				}
				run()
				liveReload(eventName, lr)
			}

			started = true
			mainLog(strings.Repeat("-", 20))
		}
	}()
}
Exemple #4
0
//NewServer creates a new Server
func NewHandler(c Config) (http.Handler, error) {
	s := &Handler{
		c:      c,
		served: map[string]bool{},
	}
	_, err := os.Stat(c.Directory)
	if c.Directory == "" || err != nil {
		return nil, fmt.Errorf("Missing directory: %s", c.Directory)
	}

	if c.PushState {
		s.root = filepath.Join(c.Directory, "index.html")
		if _, err := os.Stat(s.root); err != nil {
			return nil, fmt.Errorf("'%s' is required for pushstate", s.root)
		}
		s.hasIndex = true
	}

	if c.Fallback != "" {
		u, err := url.Parse(c.Fallback)
		if err != nil {
			return nil, err
		}
		if !strings.HasPrefix(u.Scheme, "http") {
			return nil, fmt.Errorf("Invalid fallback protocol scheme")
		}
		s.fallbackHost = u.Host
		s.fallback = httputil.NewSingleHostReverseProxy(u)
	}

	if c.LiveReload {
		s.lr, _ = lrserver.New("serve-lr", lrserver.DefaultPort)
		discard := log.New(ioutil.Discard, "", 0)
		s.lr.SetErrorLog(discard)
		s.lr.SetStatusLog(discard)
		s.watching = map[string]bool{}
		s.watcher, err = fsnotify.NewWatcher()
		if err != nil {
			return nil, err
		}
	}

	if s.c.LiveReload {
		go func() {
			if err := s.lr.ListenAndServe(); err != nil {
				fmt.Printf("LiveReload server closed: %s", err)
			}
		}()
		go func() {
			for {
				event := <-s.watcher.Events
				switch event.Op {
				case fsnotify.Create, fsnotify.Rename, fsnotify.Write:
					s.lr.Reload(event.Name)
				case fsnotify.Remove:
					if s.watching[event.Name] {
						delete(s.watching, event.Name)
					}
				}
			}
		}()
	}

	h := http.Handler(s)
	//logging is enabled
	if !c.Quiet {
		h = requestlog.WrapWith(h, requestlog.Options{TimeFormat: c.TimeFmt})
	}
	//listen
	return h, nil
}
func run(ctx *cli.Context) {
	watchDirs := ctx.StringSlice("watch")
	services := ctx.StringSlice("service")

	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error setting up file watcher: %v", err)
	}
	for _, d := range watchDirs {
		watcher.Add(d)
	}
	defer watcher.Close()

	lr, err := lrserver.New(lrserver.DefaultName, lrserver.DefaultPort)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error starting live reload: %v", err)
	}
	go lr.ListenAndServe()

	composeBin, err := exec.LookPath("docker-compose")
	if err != nil {
		fmt.Fprintf(os.Stderr, "could not find docker-compose path")
		os.Exit(1)
	}

	var cmd *exec.Cmd
	var t <-chan time.Time
	var ignore bool

MainLoop:
	for {
		select {
		case e := <-watcher.Events:
			select {
			case <-t:
				ignore = false
			default:
				if ignore {
					continue MainLoop
				}

				match, _ := filepath.Match("*.sw*", e.Name)
				if match || strings.HasSuffix(e.Name, "~") {
					continue MainLoop
				}
			}

			if len(services) == 0 {
				cmd = exec.Command(composeBin, "up")
			} else {
				args := []string{"up", "--no-deps"}
				args = append(args, services...)
				cmd = exec.Command(composeBin, args...)
			}

			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			if err := cmd.Start(); err != nil {
				fmt.Fprintf(os.Stderr, "error reloading compose file: %v", err)
			}
			ignore = true
			time.Sleep(1 * time.Second)
			lr.Reload("")
			t = time.After(3 * time.Second)
		case err := <-watcher.Errors:
			fmt.Fprintf(os.Stderr, "error watching files: %v", err)
			os.Exit(1)
		}
	}
}