Skip to content
This repository has been archived by the owner on Feb 4, 2020. It is now read-only.

Commit

Permalink
add support for configuration file
Browse files Browse the repository at this point in the history
  • Loading branch information
rande committed Dec 16, 2014
1 parent e457ec5 commit 06adaca
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 53 deletions.
46 changes: 26 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
SHELL=/bin/bash
VERSION=0.1.1
VERSION=0.1.2

.PHONY: build release deps golang-crosscompile

build: deps golang-crosscompile
source golang-crosscompile/crosscompile.bash; \
go-darwin-386 build -o release/golisten-Darwin-i386; \
go-darwin-amd64 build -o release/golisten-Darwin-x86_64; \
go-linux-386 build -o release/golisten-Linux-i386; \
go-linux-386 build -o release/golisten-Linux-i686; \
go-linux-amd64 build -o release/golisten-Linux-x86_64; \
go-linux-arm build -o release/golisten-Linux-armv6l; \
go-linux-arm build -o release/golisten-Linux-armv7l; \
go-freebsd-386 build -o release/golisten-FreeBSD-i386; \
go-freebsd-amd64 build -o release/golisten-FreeBSD-amd64; \
go-windows-386 build -o release/golisten.exe
go-darwin-386 build -o release/golisten-darwin-i386; \
go-darwin-amd64 build -o release/golisten-darwin-amd64; \
go-freebsd-386 build -o release/golisten-freebsd-i386; \
go-freebsd-amd64 build -o release/golisten-freebsd-amd64; \
go-freebsd-arm build -o release/golisten-freebsd-arm; \
go-linux-386 build -o release/golisten-linux-386; \
go-linux-amd64 build -o release/golisten-linux-amd64; \
go-linux-arm build -o release/golisten-linux-arm; \
go-windows-386 build -o release/golisten-windows-386.exe
go-windows-amd64 build -o release/golisten-windows-amd64.exe
go-openbsd-386 build -o release/golisten-openbsd-386; \
go-openbsd-amd64 build -o release/golisten-openbsd-amd64; \


release:
github-release release --user ekino --repo golisten --tag v$(VERSION) --name "golisten v$(VERSION)" --pre-release
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-darwin-i386" --file release/golisten-Darwin-i386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-darwin-x86_64" --file release/golisten-Darwin-x86_64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-freebsd-amd64" --file release/golisten-FreeBSD-amd64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-freebsd-i386" --file release/golisten-FreeBSD-i386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-armv6l" --file release/golisten-Linux-armv6l
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-armv7l" --file release/golisten-Linux-armv7l
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-i386" --file release/golisten-Linux-i386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-i686" --file release/golisten-Linux-i686
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-x86_64" --file release/golisten-Linux-x86_64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-darwin-i386" --file release/golisten-darwin-i386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-darwin-amd64" --file release/golisten-darwin-amd64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-freebsd-i386" --file release/golisten-freebsd-i386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-freebsd-amd64" --file release/golisten-freebsd-amd64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-freebsd-arm" --file release/golisten-freebsd-arm
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-386" --file release/golisten-linux-386
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-amd64" --file release/golisten-linux-amd64
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-linux-arm" --file release/golisten-linux-arm
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-windows-386.exe" --file "release/golisten-windows-386.exe"
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-windows-amd64.exe" --file "release/golisten-windows-amd64.exe"
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-openbsd-386" --file "release/golisten-openbsd-386"
github-release upload --user ekino --repo golisten --tag v$(VERSION) --name "golisten-openbsd-amd64" --file "release/golisten-openbsd-amd64"

golang-crosscompile:
rm -rf golang-crosscompile
Expand Down
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ As always, solutions exist: the present one, is to watch files on the host machi
process inside the guest machine to refresh the code.

golisten installation
-------------------------
---------------------

1. Retrieve the valid version for your OS (only OSX has been tested) on https://github.com/ekino/golisten/releases
2. You need to retrieve the ip address of the bridge (something like: 192.168.30.1)
3. Start the process ``golisten`` with the option ``-server=192.168.30.1:4001`` flag and the ``-server-format=gem-listen`` flag.
A typical command will be: ``./golisten -path ~/myproject/with/ -server-format="gem-listen" -server="192.168.30.1:4000"``

Gulp integration
gulp integration
----------------

- Make sure you have ``gulp-util`` installed
Expand Down Expand Up @@ -54,3 +54,37 @@ Gulp integration
```

If you are using ``golang``, you can also get the binary by running the command ``go get github.com/ekino/golisten``.

all in one
----------

It is possible to start the watcher command and the remote command in one command:

./golisten \
-path ~/Projects/go/src/github.com/rande/gonodeexplorer \
-server="192.168.30.1:4000" \
-server-format="gem-listen" \
-parallel-command="vagrant ssh -c \"cd /vagrant/go/src/github.com/rande/gonodeexplorer && gulp watch-network\"" \
-verbose

Let's explain the option:
- ``path``: specify the path to listen
- ``server``: start a TCP server for remote process to listen to local change
- ``server-format``: send the format using the ruby gem format
- ``parallel-command``: start a command, the command will be restarted if the process exit.
- ``verbose``: very verbose output
config file
-----------
You can export a configuration into a toml format.
./golisten -p > config.toml
And use this configuration file:
./golisten -c config.toml
4 changes: 4 additions & 0 deletions config.toml.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Path = "/Users/rande/Projects/go/src/github.com/rande/gonodeexplorer"
Server = "192.168.30.1:4000"
ServerFormat = "gem-listen"
ParallelCommand = "vagrant ssh -c \"cd /vagrant/go/src/github.com/rande/gonodeexplorer && gulp watch-network\""
142 changes: 111 additions & 31 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package main

import (
"gopkg.in/fsnotify.v1"
"github.com/BurntSushi/toml"
"log"
"os"
"path/filepath"
Expand All @@ -27,10 +28,7 @@ const (
)

var (
configuration = &Configuration{
Path: ".",
Verbose: true,
}
configuration = &Configuration{}
exclude *regexp.Regexp
include *regexp.Regexp
)
Expand Down Expand Up @@ -99,13 +97,15 @@ func (o Operation) GemName() string {
type Configuration struct {
Path string
Server string
Verbose bool
Command string
Exclude string
Include string
ServerMaxConnection int
ServerFormat string
ParallelCommand string
ServerMaxConnection int
Verbose bool
FileConfiguration string
PrintConfiguration bool
}

func NewServer(conf *Configuration) *Server {
Expand Down Expand Up @@ -158,6 +158,8 @@ func AddFolder(watcher *fsnotify.Watcher, conf *Configuration) error {

cpt := 0

info(fmt.Sprintf("Scanning folders",))

err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
if err != nil {
debug(fmt.Sprintf("Folder does not exist: ", err))
Expand All @@ -178,6 +180,7 @@ func AddFolder(watcher *fsnotify.Watcher, conf *Configuration) error {
})

info(fmt.Sprintf("%d folders added", cpt))
info(fmt.Sprintf("End scanning."))

return err
}
Expand Down Expand Up @@ -223,15 +226,33 @@ func GetCommand(command string) *exec.Cmd {
}

func init() {
flag.StringVar(&configuration.Path, "path", ".", "The path to watch")
flag.StringVar(&configuration.Path, "path", "", "The path to watch")
flag.BoolVar(&configuration.Verbose, "verbose", false, "Display verbose information")
flag.StringVar(&configuration.Server, "server", "", "Open a TCP server with local modification")
flag.StringVar(&configuration.Command, "command", "", "The command to start, use {file} as placeholder for the file")
flag.StringVar(&configuration.Exclude, "exclude", "((.*)/\\.git|\\.svn|node_modules|bower_components|/dist)", "Folder pattern to ignore")
flag.StringVar(&configuration.Include, "include", "*", "Folder pattern to include (all by default)")
flag.StringVar(&configuration.Exclude, "exclude", "", "Folder pattern to ignore")
flag.StringVar(&configuration.Include, "include", "", "Folder pattern to include (all by default)")
flag.IntVar(&configuration.ServerMaxConnection, "server-max-connection", 8, "The number of maximun connection, default=8")
flag.StringVar(&configuration.ServerFormat, "server-format", FORMAT_GO_JSON, fmt.Sprintf("Output format, default to: %s (also: %s compatible with gem listen)", FORMAT_GO_JSON, FORMAT_GEM ))
flag.StringVar(&configuration.ServerFormat, "server-format", "", fmt.Sprintf("Output format, default to: %s (also: %s compatible with gem listen)", FORMAT_GO_JSON, FORMAT_GEM ))
flag.StringVar(&configuration.ParallelCommand, "parallel-command", "", fmt.Sprintf("Run a command as a child process"))
flag.StringVar(&configuration.FileConfiguration, "c", "", fmt.Sprintf("Configuration file to use"))
flag.BoolVar(&configuration.PrintConfiguration, "p", false, fmt.Sprintf("Print the current configuration into stdout"))
}

func PrintConfiguration(conf *Configuration) {
debug("")
debug(fmt.Sprintf("> Configuration"))
debug(fmt.Sprintf(">> Path: %s ", conf.Path))
debug(fmt.Sprintf(">> Verbose: %b ", conf.Verbose))
debug(fmt.Sprintf(">> Server: %s ", conf.Server))
debug(fmt.Sprintf(">> Command: %s ", conf.Command))
debug(fmt.Sprintf(">> Exclude: %s ", conf.Exclude))
debug(fmt.Sprintf(">> Include: %s ", conf.Include))
debug(fmt.Sprintf(">> ServerMaxConnection: %s ", conf.ServerMaxConnection))
debug(fmt.Sprintf(">> ServerFormat: %s ", conf.ServerFormat))
debug(fmt.Sprintf(">> ParallelCommand: %s ", conf.ParallelCommand))
debug("")
debug("")
}

// configure basic variable and check if the command can run properly
Expand All @@ -241,6 +262,79 @@ func configure() {
// parse command line argument
flag.Parse()

if configuration.FileConfiguration != "" {
var fileConf = Configuration{}
path, _ := filepath.Abs(configuration.FileConfiguration)

if _, err := toml.DecodeFile(path, &fileConf); err != nil {
info(fmt.Sprintf("Error while reading configuration file, %s", err))
}

if configuration.Command == "" {
configuration.Command = fileConf.Command
}

if configuration.Path == "" {
configuration.Path = fileConf.Path
}

if configuration.Server == "" {
configuration.Server = fileConf.Server
}

if configuration.Exclude == "" {
configuration.Exclude = fileConf.Exclude
}

if configuration.Include == "" {
configuration.Include = fileConf.Include
}

if configuration.ServerMaxConnection == 0 {
configuration.ServerMaxConnection = fileConf.ServerMaxConnection
}

if configuration.ServerFormat == "" {
configuration.ServerFormat = fileConf.ServerFormat
}

if configuration.ParallelCommand == "" {
configuration.ParallelCommand = fileConf.ParallelCommand
}
}

// fix default value
if configuration.Exclude == "" {
configuration.Exclude = "((.*)/\\.git|\\.svn|node_modules|bower_components|/dist)"
}

if configuration.Include == "" {
configuration.Include = "*"
}

if configuration.Path == "" {
configuration.Path = "."
}

if configuration.ServerFormat == "" {
configuration.ServerFormat = "127.0.0.1:4000"
}


if configuration.ServerFormat == "" {
configuration.ServerFormat = FORMAT_GO_JSON
}

configuration.Path, _ = filepath.Abs(configuration.Path)


if configuration.PrintConfiguration {
encoder := toml.NewEncoder(os.Stdout)
encoder.Encode(configuration)

os.Exit(0)
}

// check if the command can run
if configuration.Server == "" && configuration.Command == "" {
log.Fatal("You need to set either a -server option or a -command option")
Expand All @@ -259,19 +353,7 @@ func configure() {
panic(err)
}

debug("")
debug(fmt.Sprintf("> Configuration"))
debug(fmt.Sprintf(">> Path: %s ", configuration.Path))
debug(fmt.Sprintf(">> Path: %b ", configuration.Verbose))
debug(fmt.Sprintf(">> Server: %s ", configuration.Server))
debug(fmt.Sprintf(">> Command: %s ", configuration.Command))
debug(fmt.Sprintf(">> Exclude: %s ", configuration.Exclude))
debug(fmt.Sprintf(">> Include: %s ", configuration.Include))
debug(fmt.Sprintf(">> ServerMaxConnection: %s ", configuration.ServerMaxConnection))
debug(fmt.Sprintf(">> ServerFormat: %s ", configuration.ServerFormat))
debug(fmt.Sprintf(">> ParallelCommand: %s ", configuration.ParallelCommand))
debug("")
debug("")
PrintConfiguration(configuration)
}

func getWatcher() *fsnotify.Watcher {
Expand All @@ -281,12 +363,8 @@ func getWatcher() *fsnotify.Watcher {
log.Fatal(err)
}

debug(fmt.Sprintf("Scanning folders",))

AddFolder(watcher, configuration)

debug(fmt.Sprintf("End scanning."))

return watcher
}

Expand All @@ -298,7 +376,7 @@ func startParallelCommand() {
}

for {
debug(fmt.Sprintf("Running command: %s", configuration.ParallelCommand))
info(fmt.Sprintf("Running command: %s", configuration.ParallelCommand))

c := GetCommand(configuration.ParallelCommand)

Expand All @@ -316,9 +394,9 @@ func startParallelCommand() {

c.Wait()

debug(fmt.Sprintf("Parallel command exited, start a new one in 5s"))
info(fmt.Sprintf("Parallel command exited, start a new one in 2s"))

time.Sleep(5 * time.Second)
time.Sleep(2 * time.Second)
}

}
Expand All @@ -327,12 +405,14 @@ func main() {
var err error


configure()

info("golisten is a development tools and not suitable for production usage")
info(" more information can be found at https://github.com/ekino/golisten")
info(" Thomas Rabaix @ Ekino")
info("")

configure()


// start the watcher
watcher := getWatcher()
Expand Down

0 comments on commit 06adaca

Please sign in to comment.