summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-10-17 23:56:02 +0700
committerShulhan <ms@kilabit.info>2021-10-17 23:56:02 +0700
commitcf6100a626ea17a808a1bc96471c759b27c7c03b (patch)
tree83226ba51c2600c0beb169c2406ae47d75d04138
parent4707e8dcce49a56a04c4869c8042979fef616189 (diff)
downloadgorankusu-cf6100a626ea17a808a1bc96471c759b27c7c03b.tar.xz
all: merge all workers for related to development to internal/cmd
Previously, we have a workers to recompile TypeScript and regenerate HTML files from adoc inside the Trunks type. The workers will run if the environment variable TRUNKS_DEV set to non-zero. This changes move those workers to the internal/cmd/trunks-example, because those workers are related for development only not for running Trunks server.
-rw-r--r--Makefile9
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--internal/cmd/trunks-example/main.go180
-rw-r--r--internal/memfs-embed/main.go46
-rw-r--r--trunks.go107
6 files changed, 187 insertions, 161 deletions
diff --git a/Makefile b/Makefile
index 13c16a3..017f5a4 100644
--- a/Makefile
+++ b/Makefile
@@ -4,14 +4,9 @@
.PHONY: all run embed tsc
-all: embed
+all:
+ go run ./internal/cmd/trunks-example build
go test -v -race ./...
run:
go run ./internal/cmd/trunks-example
-
-embed: tsc
- go run ./internal/memfs-embed
-
-tsc:
- tsc -p _www/tsconfig.json
diff --git a/go.mod b/go.mod
index 84e59ee..ae55a26 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module git.sr.ht/~shulhan/trunks
go 1.16
require (
- git.sr.ht/~shulhan/ciigo v0.6.1-0.20211010143228-56488e32c04c
+ git.sr.ht/~shulhan/ciigo v0.6.1-0.20211017121420-36d729c71dd0
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
diff --git a/go.sum b/go.sum
index 5d98f3c..6ae6c4b 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,7 @@
git.sr.ht/~shulhan/asciidoctor-go v0.1.1-0.20211004182124-1c48dfa11a1b h1:LrKeNE5urwiAZcuv1ACKwStbXpxWIaXNKrL4aCsN2EE=
git.sr.ht/~shulhan/asciidoctor-go v0.1.1-0.20211004182124-1c48dfa11a1b/go.mod h1:fGzLvcEmRkdfo9mg7sp7fQHQHquCUJ4+6nRfWi6I7B0=
-git.sr.ht/~shulhan/ciigo v0.6.1-0.20211010143228-56488e32c04c h1:+XHHQitIznJFH9vQJMfR/+DQfVFED/ls1p81FExlJAg=
-git.sr.ht/~shulhan/ciigo v0.6.1-0.20211010143228-56488e32c04c/go.mod h1:mmvVAFWJ14Y3qrI0MPNrslAf6QKxtEiXpmERaBYk7LY=
+git.sr.ht/~shulhan/ciigo v0.6.1-0.20211017121420-36d729c71dd0 h1:aScDnq5u5DnQ2XGwGXCmcdZzfpyyPFvGZxnkFbWtMCM=
+git.sr.ht/~shulhan/ciigo v0.6.1-0.20211017121420-36d729c71dd0/go.mod h1:mmvVAFWJ14Y3qrI0MPNrslAf6QKxtEiXpmERaBYk7LY=
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=
diff --git a/internal/cmd/trunks-example/main.go b/internal/cmd/trunks-example/main.go
index 9c340e5..1746209 100644
--- a/internal/cmd/trunks-example/main.go
+++ b/internal/cmd/trunks-example/main.go
@@ -8,21 +8,50 @@
package main
import (
+ "flag"
"os"
"os/signal"
+ "strings"
"syscall"
+ "time"
+ "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"
+ "git.sr.ht/~shulhan/ciigo"
+ "git.sr.ht/~shulhan/trunks"
"git.sr.ht/~shulhan/trunks/example"
)
+const (
+ subCommandBuild = "build"
+ cmdTsc = "tsc -b _www"
+)
+
func main() {
+ flag.Parse()
+ subcmd := strings.ToLower(flag.Arg(0))
+
+ if subcmd == subCommandBuild {
+ workerBuild(true)
+ return
+ }
+
+ err := os.Setenv(trunks.EnvDevelopment, "1")
+ if err != nil {
+ mlog.Fatalf("%s\n", err)
+ }
+
ex, err := example.New()
if err != nil {
mlog.Fatalf("%s\n", err)
}
+ go workerBuild(false)
+ go workerDocs()
+
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
@@ -35,3 +64,154 @@ func main() {
mlog.Fatalf("%s\n", err)
}
}
+
+//
+// workerBuild watch update on .ts and .js files inside _www directory.
+//
+// Every 5 seconds, it will recompile TypeScript to JavaScript, by running
+// tsc, if only if there is at least one .ts file being.
+// After that, if there is an update to .js files, it will run scripts that
+// embed them into Go source code.
+//
+// If oneTime parameter is true, it will recompile the .ts and embed the .js
+// files only, without watching updates.
+//
+func workerBuild(oneTime bool) {
+ var (
+ logp = "workerBuild"
+ tsCount = 0
+ embedCount = 0
+ changeq = make(chan *io.NodeState, 64)
+ )
+
+ mfsOpts := &memfs.Options{
+ Root: "_www",
+ Includes: []string{
+ `.*\.(js|ico|png|html)$`,
+ },
+ Excludes: []string{
+ `.*\.adoc`,
+ `.*\.git`,
+ `.*\.ts`,
+ `/wui/.*/example.js$`,
+ `/wui/.*/index.html$`,
+ `/wui/index\.html$`,
+ `/wui\.bak`,
+ `/wui\.local`,
+ },
+ }
+
+ mfsWww, err := memfs.New(mfsOpts)
+ if err != nil {
+ mlog.Fatalf("%s: %s", logp, err)
+ }
+
+ if oneTime {
+ err = doRunTsc(logp)
+ if err != nil {
+ os.Exit(1)
+ }
+ err = doGoEmbed(logp, mfsWww)
+ if err != nil {
+ os.Exit(1)
+ }
+ return
+ }
+
+ dirWatchWww := io.DirWatcher{
+ Options: memfs.Options{
+ Root: "_www",
+ Includes: []string{
+ `.*\.(js|ts)$`,
+ `_www/tsconfig.json`,
+ },
+ Excludes: []string{
+ `.*\.d\.ts$`,
+ `.*\.git/.*`,
+ `docs`,
+ `wui\.bak`,
+ `wui\.local`,
+ },
+ },
+ Callback: func(ns *io.NodeState) {
+ changeq <- ns
+ },
+ }
+
+ err = dirWatchWww.Start()
+ if err != nil {
+ mlog.Fatalf("%s: %s", logp, err)
+ }
+
+ mlog.Outf("%s: started ...\n", logp)
+
+ ticker := time.NewTicker(5 * time.Second)
+ for {
+ select {
+ case ns := <-changeq:
+ if strings.HasSuffix(ns.Node.SysPath, ".ts") {
+ mlog.Outf("%s: update %s\n", logp, ns.Node.SysPath)
+ tsCount++
+ } else if strings.HasSuffix(ns.Node.SysPath, ".json") {
+ mlog.Outf("%s: update %s\n", logp, ns.Node.SysPath)
+ tsCount++
+ } else if strings.HasSuffix(ns.Node.SysPath, ".js") {
+ embedCount++
+ mlog.Outf("%s: update %s\n", logp, ns.Node.SysPath)
+ err = ns.Node.Update(nil, 0)
+ if err != nil {
+ mlog.Errf("%s: %s", logp, err)
+ }
+ } else {
+ mlog.Outf("%s: unknown file updated %s\n", logp, ns.Node.SysPath)
+ }
+ case <-ticker.C:
+ if tsCount > 0 {
+ tsCount = 0
+ _ = doRunTsc(logp)
+ }
+ if embedCount > 0 {
+ embedCount = 0
+ _ = doGoEmbed(logp, mfsWww)
+ }
+ }
+ }
+}
+
+//
+// workerDocs a goroutine that watch any changes to .adoc files inside
+// "_www/docs" directory and convert them into HTML files.
+//
+func workerDocs() {
+ logp := "workerDocs"
+
+ mlog.Outf("%s: started ...\n", logp)
+
+ opts := &ciigo.ConvertOptions{
+ Root: "_www/docs",
+ }
+ err := ciigo.Watch(opts)
+ if err != nil {
+ mlog.Errf("%s: %s", logp, err)
+ }
+}
+
+func doRunTsc(logp string) (err error) {
+ mlog.Outf("%s: execute %s\n", logp, cmdTsc)
+ err = exec.Run(cmdTsc, nil, nil)
+ if err != nil {
+ mlog.Errf("%s: %s", logp, err)
+ return err
+ }
+ return nil
+}
+
+func doGoEmbed(logp string, mfs *memfs.MemFS) (err error) {
+ mlog.Outf("%s: generate memfs_www_embed.go\n", logp)
+ err = mfs.GoEmbed("trunks", "memfsWWW", "memfs_www_embed.go", "")
+ if err != nil {
+ mlog.Errf("%s: %s", logp, err)
+ return err
+ }
+ return nil
+}
diff --git a/internal/memfs-embed/main.go b/internal/memfs-embed/main.go
deleted file mode 100644
index 04de67f..0000000
--- a/internal/memfs-embed/main.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "log"
- "os"
-
- "github.com/shuLhan/share/lib/memfs"
- "github.com/shuLhan/share/lib/mlog"
-)
-
-func main() {
- log.SetPrefix(os.Args[0])
-
- opts := &memfs.Options{
- Root: "_www",
- Excludes: []string{
- `.*\.adoc`,
- `.*\.git`,
- `.*\.ts`,
- `/wui/.*/example.js$`,
- `/wui/.*/index.html$`,
- `/wui/LICENSE$`,
- `/wui/Makefile$`,
- `/wui/NOTES$`,
- `/wui/README.adoc$`,
- `/wui/index\.html$`,
- `/wui/tsconfig\.json$`,
- `/wui\.bak`,
- `/wui\.local`,
- },
- }
-
- mfs, err := memfs.New(opts)
- if err != nil {
- log.Fatalf("%s\n", err)
- }
-
- err = mfs.GoEmbed("trunks", "memfsWWW", "memfs_www_embed.go", "")
- if err != nil {
- mlog.Fatalf("%s\n", err)
- }
-}
diff --git a/trunks.go b/trunks.go
index 1bf982c..2e5bcd5 100644
--- a/trunks.go
+++ b/trunks.go
@@ -11,15 +11,11 @@ import (
"strings"
"time"
- "git.sr.ht/~shulhan/ciigo"
vegeta "github.com/tsenart/vegeta/v12/lib"
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"
"github.com/shuLhan/share/lib/websocket"
)
@@ -35,7 +31,7 @@ const (
// Setting this environment variable will enable trunks development
// mode.
- envDevelopment = "TRUNKS_DEV"
+ EnvDevelopment = "TRUNKS_DEV"
// List of HTTP parameters.
paramNameName = "name"
@@ -66,7 +62,7 @@ type Trunks struct {
func New(env *Environment) (trunks *Trunks, err error) {
var (
logp = "trunks.New"
- isDevelopment = len(os.Getenv(envDevelopment)) > 0
+ isDevelopment = len(os.Getenv(EnvDevelopment)) > 0
)
err = env.init()
@@ -90,11 +86,6 @@ func New(env *Environment) (trunks *Trunks, err error) {
return nil, fmt.Errorf("%s: %w", logp, err)
}
- if isDevelopment {
- go watchDocs()
- go watchWww()
- }
-
return trunks, nil
}
@@ -503,97 +494,3 @@ 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() {
- var (
- logp = "watchWww"
- changeq = make(chan struct{}, 64)
- )
-
- go recompile(changeq)
-
- dirWatcher := &io.DirWatcher{
- Options: memfs.Options{
- Root: "_www",
- Includes: []string{
- `\.*.ts$`,
- `_www/index.html$`,
- `_www/tsconfig.json$`,
- },
- Excludes: []string{
- `\.*.d.ts$`,
- `\.git`,
- `\.wui.bak`,
- `\.wui.local`,
- },
- },
- Callback: func(ns *io.NodeState) {
- mlog.Outf("--- %s: %s: %d\n", logp, ns.Node.SysPath, ns.State)
- changeq <- struct{}{}
- },
- }
- err := dirWatcher.Start()
- if err != nil {
- mlog.Errf("%s: %s", logp, err)
- }
-}
-
-func recompile(changeq chan struct{}) {
- var (
- logp = "recompile"
- count int
- changeTicker = time.NewTicker(3 * time.Second)
- commands = []string{
- "tsc -p _www/tsconfig.json",
- "go run ./internal/generate-memfs",
- }
- draining bool
- )
- for range changeTicker.C {
- draining = true
- for draining {
- select {
- case <-changeq:
- count++
- default:
- if count == 0 {
- // No changes.
- draining = false
- } else {
- // All changes has been drained, execute all
- // commands.
- 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)
- }
- }
- count = 0
- draining = false
- }
- }
- }
- }
-}