main.go の記述
fujiwara-san のlambroll のコード眺めて、
func main(){ os.Exit(_main()) } func _main() int { return 0 }
としてるの見て真似しようとなった。
サブプロセスの起動
設定ファイルからコマンドライン指定を受け取って並列実行する。WaitGroup
の存在を忘れていた。
golang で構造体にマーシャリング時のマッピング情報をタグ付けするのいつも概念を忘れていて、「おおそうだった」となってしまう。フィールド名大文字じゃないといけないのは、マーシャル処理するパッケージからアクセスできないからか。それはそうか。
func subexec(title, command string, wg *sync.WaitGroup) { defer wg.Done() cmd := exec.Command("sh", "-c", command) output, err := cmd.CombinedOutput() if err != nil { log.Fatalf("[%v] failed: %v", title, err) } fmt.Printf("[%v] output:\n%s\n", title, string(output)) fmt.Printf("[%v] ret value: %v\n", title, cmd.ProcessState) } type Shells struct { Shells map[string]string `yaml:"shells"` } func main() { data, err := os.ReadFile("./sample.yml") if err != nil { panic(err) } var s Shells if err := yaml.Unmarshal(data, &s); err != nil { panic(err) } var wg sync.WaitGroup for key, command := range s.Shells { fmt.Printf("%s: %s\n", key, command) wg.Add(1) go subexec(key, command, &wg) } wg.Wait() }
こうして、sample.yml
にこんな感じのことを書くと並行実行できる。はい。
shells: frontend: cd frontend | npm run build -- --watch server: cd backend | go run cmd/apps/main.go
web
ginを少し使ってみる。素朴だがコードを見て戸惑うことは少ない。
ルーティング周りの仕様がわかりづらくコードを読んでもやっぱりわかりづらい。パスの処理をめっちゃストレートに実装していて、いかにも高速でフットプリント軽そうではあるけど、ワイルドカード周りの扱いめちゃわかりづらくないですかこれ。脳内で「こういうルーティングを簡単に設定して〜」って思ったことがうまくいかなくてギギギと何度かなった。
例えば、router.StaticFile("/*.html", "./public/index.html")
みたいなのが定義できないとか細かい挙動。いや静的ファイルで可変パラメータ関係ないでしょ、というのは思想そのものはわかるとして、では動的な処理としてマッピングできるかというとできない。/:any.html
だといけないもんな。any.html
ってパラメータにマッピングされてしまう...。いや今時 *.html
みたいなの流行らないというのも理解しているんですが...。うっうっ。
ホットリロードの仕組みがないのもイマドキ感が薄い。そういうのはサーバの外でやれ、というのもわかるんだけど。
コマンドライン引数処理
flag
パッケージがシンプルでよかった。
ちょっと癖はある。
func main() { var n int flag.IntVar(&n, "n", 1234, "help message for flag n") flag.Parse() // Parseを呼ばないと初期値(1234)が設定されたまま fmt.Printf("n = %v\n", n) fmt.Printf("args = %v\n", flag.Args()) }