예제 #1
0
파일: dev.go 프로젝트: rainycape/gondola
func devCommand(args *command.Args, opts *devOptions) error {
	if !opts.Verbose {
		log.SetLevel(log.LInfo)
	}
	dir := opts.Dir
	if dir == "" {
		dir = "."
	}
	path, err := filepath.Abs(dir)
	if err != nil {
		return err
	}
	configPath := findConfig(dir, opts.Config)
	if configPath == "" {
		name := opts.Config
		if name == "" {
			name = fmt.Sprintf("(tried %s)", strings.Join(autoConfigNames(), ", "))
		}
		log.Panicf("can't find configuration file %s in %s", name, dir)
	}
	log.Infof("Using config file %s", configPath)
	p := NewProject(path, configPath)
	p.port = opts.Port
	p.tags = opts.Tags
	p.goFlags = opts.GoFlags
	p.noDebug = opts.NoDebug
	p.noCache = opts.NoCache
	p.profile = opts.Profile
	go p.Build()
	log.Infof("Starting Gondola development server on port %d (press Control+C to exit)", p.port)
	if !opts.NoBrowser {
		time.AfterFunc(time.Second, func() {
			host := "localhost"
			if sshConn := os.Getenv("SSH_CONNECTION"); sshConn != "" {
				parts := strings.Split(sshConn, " ")
				// e.g. SSH_CONNECTION="10.211.55.2 56989 10.211.55.8 22"
				if len(parts) == 4 {
					if net.ParseIP(parts[2]) != nil {
						host = parts[2]
					}
				}
			}
			url := fmt.Sprintf("http://%s:%d", host, p.App.Config().Port)
			if err := browser.Open(url); err != nil {
				log.Errorf("error opening browser: open %s manually (error was %s)", url, err)
			}
		})
	}
	p.Listen()
	return nil
}
예제 #2
0
파일: app.go 프로젝트: rainycape/gondola
// MustListenAndServe works like ListenAndServe, but panics if
// there's an error
func (app *App) MustListenAndServe() {
	err := app.ListenAndServe()
	if err != nil {
		log.Panicf("error listening on port %d: %s", app.cfg.Port, err)
	}
}
예제 #3
0
파일: dev.go 프로젝트: rainycape/gondola
func (p *Project) StartMonitoring() error {
	watcher, err := newFSWatcher()
	if err != nil {
		return err
	}
	var files []string
	pkgs, err := p.Packages()
	if err != nil && len(pkgs) == 0 {
		// Monitor just the files in the project directory
		infos, err2 := ioutil.ReadDir(p.dir)
		if err2 != nil {
			// Return the original error, since it will show
			// why the the packages failed to import
			return err
		}
		for _, entry := range infos {
			if !entry.IsDir() {
				files = append(files, filepath.Join(p.dir, entry.Name()))
			}
		}
	}
	watcher.IsValidFile = func(path string) bool {
		return path == p.configPath || isSource(path)
	}

	var timer *time.Timer
	var mu sync.Mutex
	onChanged := func(path string) {
		if path == p.configPath {
			log.Infof("Config file %s changed, restarting...", p.configPath)
			if err := p.Stop(); err != nil {
				log.Errorf("Error stopping %s: %s", p.Name(), err)
			}
			if err := p.Start(); err != nil {
				log.Panicf("Error starting %s: %s", p.Name(), err)
			}
		} else {
			// Merge multiple events arriving in
			// a small time window
			mu.Lock()
			if timer == nil {
				timer = time.AfterFunc(10*time.Millisecond, func() {
					mu.Lock()
					timer = nil
					p.Build()
					mu.Unlock()
				})
			}
			mu.Unlock()
		}
	}
	watcher.Added = onChanged
	watcher.Removed = onChanged
	watcher.Changed = onChanged
	if len(files) > 0 {
		// Packages could not be imported and we're
		// using files as a fallback.
		for _, f := range files {
			if err := watcher.Add(f); err != nil {
				return err
			}
		}
	} else {
		if err := watcher.AddPackages(pkgs); err != nil {
			return err
		}
	}
	if err := watcher.Add(p.configPath); err != nil {
		return err
	}
	p.watcher = watcher
	return nil
}