summaryrefslogtreecommitdiff
path: root/internal/cmd/trunks-example/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cmd/trunks-example/main.go')
-rw-r--r--internal/cmd/trunks-example/main.go180
1 files changed, 180 insertions, 0 deletions
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
+}