From 8800b8fb860f6d8429487bf6bb45dc9cca29507a Mon Sep 17 00:00:00 2001 From: Shulhan Date: Sat, 25 Sep 2021 23:43:13 +0700 Subject: all: simplify development on trunks-example Previously to developer and test trunks on local we need to run "tsc -w" on directory _www to watch and recompile any changes to TypeScript files, and run "go run ./cmd/trunks-example" to view the Trunks web interface. Since we will have internal documentation inside _www/docs, we need to run another ciigo server that watch any changes to .adoc files and convert it to HTML. Three separate commands for development. This changes refactoring the development process by running two goroutines when TRUNKS_DEV environment variable is set to non-empty. One goroutine watch any changes to TypeScript, HTML, and tsconfig files inside the _www, and when there is an update it will execute "tsc -p" to recompile and "go run ./internal/generate-memfs" to embed them into Go source. Another goroutine watch any changes to .adoc files inside "_www/docs" directory and convert them into HTML files. This goroutine will running in the background while the HTTP server is running too. --- Makefile | 2 +- _www/tsconfig.json | 3 +- _www/wui | 2 +- cmd/trunks-example/main.go | 3 +- go.mod | 3 +- go.sum | 20 ++++++++--- internal/generate-memfs/main.go | 1 + trunks.go | 79 +++++++++++++++++++++++++++++++++++++++-- 8 files changed, 101 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index dfc4b3b..e17eee9 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ all: embed go test -v -race ./... run: - DEBUG=3 go run ./cmd/trunks-example + go run ./cmd/trunks-example embed: tsc go run ./internal/generate-memfs diff --git a/_www/tsconfig.json b/_www/tsconfig.json index c6d9f8f..eb59bce 100644 --- a/_www/tsconfig.json +++ b/_www/tsconfig.json @@ -7,5 +7,6 @@ "moduleResolution": "node", "strict": true, "target": "es2015" - } + }, + "exclude": ["docs"] } diff --git a/_www/wui b/_www/wui index 1999427..665bda4 160000 --- a/_www/wui +++ b/_www/wui @@ -1 +1 @@ -Subproject commit 19994275a9f238dbbb2d73702bba355faaa12a0d +Subproject commit 665bda4fe5ccf0e12b74262309da39695dd69317 diff --git a/cmd/trunks-example/main.go b/cmd/trunks-example/main.go index 854cf69..9c340e5 100644 --- a/cmd/trunks-example/main.go +++ b/cmd/trunks-example/main.go @@ -12,8 +12,9 @@ import ( "os/signal" "syscall" - "git.sr.ht/~shulhan/trunks/example" "github.com/shuLhan/share/lib/mlog" + + "git.sr.ht/~shulhan/trunks/example" ) func main() { diff --git a/go.mod b/go.mod index 84560cb..34a0633 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,11 @@ module git.sr.ht/~shulhan/trunks go 1.15 require ( + git.sr.ht/~shulhan/ciigo v0.6.1-0.20210709052544-cd7bd3f1999a github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654 // indirect github.com/influxdata/tdigest v0.0.1 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/shuLhan/share v0.29.3-0.20210912173028-f8efb407cb46 + github.com/shuLhan/share v0.29.3-0.20210925141231-81f4c4593f54 github.com/tsenart/vegeta/v12 v12.8.4 ) diff --git a/go.sum b/go.sum index 95b5e19..1c6f5f8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,10 @@ +git.sr.ht/~shulhan/asciidoctor-go v0.1.1-0.20210406124504-3a5ca1ea9d09 h1:88aO0OKoM5ZNga/pCYYg4yUnSbqMO2xK6WtSLZj+avw= +git.sr.ht/~shulhan/asciidoctor-go v0.1.1-0.20210406124504-3a5ca1ea9d09/go.mod h1:es2jWkfgn3nOEXIhKX+i+Pb3pJIOsYhPq+DIfzhVDzU= +git.sr.ht/~shulhan/ciigo v0.6.1-0.20210709052544-cd7bd3f1999a h1:7lMaEfO0/eAPB3oSrTfq3vtznX9X8XFsTmxnpD7TH9g= +git.sr.ht/~shulhan/ciigo v0.6.1-0.20210709052544-cd7bd3f1999a/go.mod h1:1gF5yW1c2pejBVunPxMy7dvMnlHHdQhx66EVvy3pXiE= github.com/alecthomas/jsonschema v0.0.0-20180308105923-f2c93856175a/go.mod h1:qpebaTNSsyUn5rPSJMsfqEtDw71TTggXM6stUDI16HA= github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b h1:AP/Y7sqYicnjGDfD5VcY4CIfh1hRXBUavxrvELjTiOE= github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q= -github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae h1:2Zmk+8cNvAGuY8AyvZuWpUdpQUAXwfom4ReVMe/CTIo= github.com/c2h5oh/datasize v0.0.0-20171227191756-4eba002a5eae/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E= github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654 h1:XOPLOMn/zT4jIgxfxSsoXPxkrzz0FaCHwp33x5POJ+Q= @@ -27,16 +30,19 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/miekg/dns v1.1.17/go.mod h1:WgzbA6oji13JREwiNsRDNfl7jYdPnmz+VEuLrA+/48M= -github.com/shuLhan/share v0.29.3-0.20210912173028-f8efb407cb46 h1:mw4ZXkrUXRvMhWMFeLmxEBdJlyOr1g2Tt0HxzKdm/UI= -github.com/shuLhan/share v0.29.3-0.20210912173028-f8efb407cb46/go.mod h1:9gv+ID20OrJiXz0y+fZ9e9Ah4CIX2vJVVbcKiI3az5Y= +github.com/shuLhan/share v0.25.1/go.mod h1:G6T/vwf4RNLP6iJBhOfExDfAnPT8MuSDQ4Y81Ax9fDg= +github.com/shuLhan/share v0.28.1-0.20210709045022-0cd813b8ae8a/go.mod h1:mIi+vy+p2UOGZXna5Z9JDr0t8pxyl2ysJCTw/zZECAY= +github.com/shuLhan/share v0.29.3-0.20210925141231-81f4c4593f54 h1:YYIxUES3a7tW+bYi9vCWbGv9Wluz/WdVskzu5hXJa8M= +github.com/shuLhan/share v0.29.3-0.20210925141231-81f4c4593f54/go.mod h1:9gv+ID20OrJiXz0y+fZ9e9Ah4CIX2vJVVbcKiI3az5Y= github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25 h1:7z3LSn867ex6VSaahyKadf4WtSsJIgne6A1WLOAGM8A= github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU= -github.com/tsenart/go-tsz v0.0.0-20180814232043-cdeb9e1e981e h1:bB5SXzQmSUsJCmjPDN9fKYx3SSDER5diSjlN6TefTCc= github.com/tsenart/go-tsz v0.0.0-20180814232043-cdeb9e1e981e/go.mod h1:SWZznP1z5Ki7hDT2ioqiFKEse8K9tU2OUvaRI0NeGQo= github.com/tsenart/vegeta/v12 v12.8.4 h1:UQ7tG7WkDorKj0wjx78Z4/vsMBP8RJQMGJqRVrkvngg= github.com/tsenart/vegeta/v12 v12.8.4/go.mod h1:ZiJtwLn/9M4fTPdMY7bdbIeyNeFVE8/AHbWFqCsUuho= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de h1:xSjD6HQTqT0H/k60N5yYBtnN1OEkVy7WIo/DYyxKRO0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -44,6 +50,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg= golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -51,11 +59,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/internal/generate-memfs/main.go b/internal/generate-memfs/main.go index 838aef9..95c9ad5 100644 --- a/internal/generate-memfs/main.go +++ b/internal/generate-memfs/main.go @@ -18,6 +18,7 @@ func main() { opts := &memfs.Options{ Root: "_www", Excludes: []string{ + `.*\.adoc`, `.*\.ts`, `/wui/.*/example.js$`, `/wui/.*/index.html$`, diff --git a/trunks.go b/trunks.go index 4b61009..c41329b 100644 --- a/trunks.go +++ b/trunks.go @@ -13,13 +13,15 @@ import ( "strings" "time" + "git.sr.ht/~shulhan/ciigo" vegeta "github.com/tsenart/vegeta/v12/lib" - "github.com/shuLhan/share/lib/debug" liberrors "github.com/shuLhan/share/lib/errors" libhttp "github.com/shuLhan/share/lib/http" + "github.com/shuLhan/share/lib/io" "github.com/shuLhan/share/lib/memfs" "github.com/shuLhan/share/lib/mlog" + "github.com/shuLhan/share/lib/os/exec" ) const ( @@ -29,6 +31,10 @@ const ( DefaultListenAddress = "127.0.0.1:8217" DefaultMaxAttackDuration = 30 * time.Second DefaultMaxAttackRate = 3000 + + // Setting this environment variable will enable trunks development + // mode. + envDevelopment = "TRUNKS_DEV" ) // List of HTTP APIs provided by Trunks HTTP server. @@ -64,6 +70,8 @@ type Trunks struct { // New create and initialize new Trunks service. // func New(env *Environment) (trunks *Trunks, err error) { + isDevelopment := len(os.Getenv(envDevelopment)) > 0 + err = env.init() if err != nil { return nil, fmt.Errorf("New: %w", err) @@ -77,8 +85,11 @@ func New(env *Environment) (trunks *Trunks, err error) { httpdOpts := &libhttp.ServerOptions{ Options: memfs.Options{ - Root: "_www", - Development: debug.Value >= 2, + Root: "_www", + Includes: []string{ + `.*\.(js|png|html|ico)$`, + }, + Development: isDevelopment, }, Memfs: memfsWWW, Address: env.ListenAddress, @@ -94,6 +105,11 @@ func New(env *Environment) (trunks *Trunks, err error) { return nil, fmt.Errorf("New: %w", err) } + if isDevelopment { + go watchDocs() + go watchWww() + } + return trunks, nil } @@ -678,3 +694,60 @@ func (trunks *Trunks) workerAttackQueue() { trunks.Env.AttackRunning = nil } } + +// +// watchDocs a goroutine that watch any changes to .adoc files inside +// "_www/docs" directory and convert them into HTML files. +// +func watchDocs() { + logp := "watchDocs" + opts := &ciigo.ConvertOptions{ + Root: "_www/docs", + } + err := ciigo.Watch(opts) + if err != nil { + mlog.Errf("%s: %s", logp, err) + } +} + +// +// watchWww a goroutine that watch any changes to TypeScript, HTML, and +// tsconfig files inside the _www, and when there is an update it will execute +// "tsc -p" to recompile and "go run ./internal/generate-memfs" to embed them +// into Go source. +// +func watchWww() { + logp := "watchWww" + commands := []string{ + "tsc -p _www/tsconfig.json", + "go run ./internal/generate-memfs", + } + + dirWatcher := &io.DirWatcher{ + Options: memfs.Options{ + Root: "_www", + Includes: []string{ + `\.*.ts$`, + `_www/index.html$`, + `_www/tsconfig.json$`, + }, + Excludes: []string{ + `\.*.d.ts$`, + }, + }, + Callback: func(ns *io.NodeState) { + for _, cmd := range commands { + mlog.Outf("%s: %s\n", logp, cmd) + err := exec.Run(cmd, nil, nil) + if err != nil { + mlog.Errf("%s: %s", logp, err) + return + } + } + }, + } + err := dirWatcher.Start() + if err != nil { + mlog.Errf("%s: %s", logp, err) + } +} -- cgit v1.3