add ent for sql

some improvements on killing the running process on reboot
This commit is contained in:
maddalax 2024-09-17 10:41:29 -05:00
parent 45d8e58faa
commit 16cdb66e0d
17 changed files with 226 additions and 19 deletions

24
cli/logger.go Normal file
View file

@ -0,0 +1,24 @@
package main
import (
"log/slog"
"os"
)
func getLogLevel() slog.Level {
// Get the log level from the environment variable
logLevel := os.Getenv("LOG_LEVEL")
switch logLevel {
case "DEBUG":
return slog.LevelDebug
case "INFO":
return slog.LevelInfo
case "WARN":
return slog.LevelWarn
case "ERROR":
return slog.LevelError
default:
// Default to INFO if no valid log level is set
return slog.LevelInfo
}
}

View file

@ -7,8 +7,10 @@ import (
"github.com/maddalax/htmgo/cli/tasks/astgen"
"github.com/maddalax/htmgo/cli/tasks/css"
"github.com/maddalax/htmgo/cli/tasks/downloadtemplate"
"github.com/maddalax/htmgo/cli/tasks/process"
"github.com/maddalax/htmgo/cli/tasks/reloader"
"github.com/maddalax/htmgo/cli/tasks/run"
"log/slog"
"os"
"strings"
)
@ -17,7 +19,7 @@ func main() {
done := RegisterSignals()
commandMap := make(map[string]*flag.FlagSet)
commands := []string{"template", "run", "watch", "build", "setup", "css"}
commands := []string{"template", "run", "watch", "build", "setup", "css", "schema"}
for _, command := range commands {
commandMap[command] = flag.NewFlagSet(command, flag.ExitOnError)
@ -44,16 +46,35 @@ func main() {
return
}
slog.SetLogLoggerLevel(getLogLevel())
taskName := os.Args[1]
slog.Debug("Running task: %s", taskName)
slog.Debug("working dir %s", process.GetWorkingDir())
if taskName == "watch" {
os.Setenv("ENV", "development")
os.Setenv("WATCH_MODE", "true")
astgen.GenAst(true)
css.GenerateCss(true)
run.EntGenerate()
go func() {
_ = run.Server(true)
}()
startWatcher(reloader.OnFileChange)
} else {
if taskName == "schema" {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter entity name:")
text, _ := reader.ReadString('\n')
text = strings.TrimSuffix(text, "\n")
run.EntNewSchema(text)
}
if taskName == "generate" {
run.EntGenerate()
astgen.GenAst(true)
}
if taskName == "setup" {
run.Setup()
} else if taskName == "css" {

View file

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"log"
"log/slog"
"os"
"os/exec"
"path/filepath"
@ -16,6 +17,7 @@ var workingDir string
var commands = make([]*exec.Cmd, 0)
func AppendRunning(cmd *exec.Cmd) {
slog.Info("running", slog.String("command", strings.Join(cmd.Args, " ")))
commands = append(commands, cmd)
}
@ -154,15 +156,18 @@ func Run(command string, exitOnError bool) error {
AppendRunning(cmd)
err := cmd.Run()
if err != nil {
if strings.Contains(err.Error(), "signal: killed") {
return nil
}
if exitOnError {
log.Println(fmt.Sprintf("error: %v", err))
os.Exit(1)
}
return err
if err == nil {
return nil
}
return nil
if exitOnError {
log.Println(fmt.Sprintf("error: %v", err))
os.Exit(1)
}
if strings.Contains(err.Error(), "signal: killed") {
return nil
}
return err
}

View file

@ -7,6 +7,7 @@ import (
"github.com/maddalax/htmgo/cli/tasks/css"
"github.com/maddalax/htmgo/cli/tasks/process"
"github.com/maddalax/htmgo/cli/tasks/run"
"log/slog"
"strings"
"sync"
)
@ -53,6 +54,7 @@ type Tasks struct {
AstGen bool
Css bool
Run bool
Ent bool
}
func OnFileChange(events []*fsnotify.Event) {
@ -61,6 +63,8 @@ func OnFileChange(events []*fsnotify.Event) {
for _, event := range events {
c := NewChange(event.Name)
slog.Debug("file changed", slog.String("file", c.Name()))
if c.IsGenerated() {
continue
}
@ -77,6 +81,10 @@ func OnFileChange(events []*fsnotify.Event) {
if c.HasAnySuffix("tailwind.config.js", ".css") {
tasks.Css = true
}
if c.HasAnyPrefix("ent/schema") {
tasks.Ent = true
}
}
deps := make([]func() any, 0)
@ -93,6 +101,13 @@ func OnFileChange(events []*fsnotify.Event) {
})
}
if tasks.Ent {
deps = append(deps, func() any {
run.EntGenerate()
return nil
})
}
wg := sync.WaitGroup{}
for _, dep := range deps {

View file

@ -0,0 +1,11 @@
package run
import "github.com/maddalax/htmgo/cli/tasks/process"
func EntNewSchema(name string) {
process.RunOrExit("GOWORK=off go run -mod=mod entgo.io/ent/cmd/ent new " + name)
}
func EntGenerate() {
process.RunOrExit("GOWORK=off go generate ./ent")
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/fsnotify/fsnotify"
"log"
"log/slog"
"os"
"path/filepath"
)
@ -11,7 +12,6 @@ import (
var ignoredDirs = []string{".git", ".idea", "node_modules", "vendor"}
func startWatcher(cb func(file []*fsnotify.Event)) {
//debouncer := NewDebouncer(time.Millisecond * 100)
events := make([]*fsnotify.Event, 0)
defer func() {
@ -43,7 +43,7 @@ func startWatcher(cb func(file []*fsnotify.Event)) {
if !ok {
return
}
log.Println("error:", err)
slog.Error("error:", err.Error())
}
}
}()

View file

@ -1,6 +1,8 @@
package ui
import "github.com/maddalax/htmgo/framework/h"
import (
"github.com/maddalax/htmgo/framework/h"
)
type InputProps struct {
Id string
@ -13,7 +15,6 @@ type InputProps struct {
}
func Input(props InputProps) h.Renderable {
validation := h.If(props.ValidationPath != "", h.Children(
h.Post(props.ValidationPath),
h.Trigger("change"),

View file

@ -1,7 +1,11 @@
package h
import (
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/maddalax/htmgo/framework/util/process"
"log/slog"
"time"
)
type App struct {
@ -31,10 +35,23 @@ func (a App) start(app *fiber.App) {
AddLiveReloadHandler("/livereload", a.Fiber)
}
err := a.Fiber.Listen(":3000")
port := ":3000"
err := a.Fiber.Listen(port)
if err != nil {
panic(err)
// If we are in watch mode, just try to kill any processes holding that port
// and try again
if IsDevelopment() && IsWatchMode() {
slog.Info("Port already in use, trying to kill the process and start again")
process.RunOrExit(fmt.Sprintf("kill -9 $(lsof -t -i%s)", port))
time.Sleep(time.Millisecond * 50)
err = a.Fiber.Listen(port)
if err != nil {
panic(err)
}
} else {
panic(err)
}
}
}

15
framework/h/env.go Normal file
View file

@ -0,0 +1,15 @@
package h
import "os"
func IsWatchMode() bool {
return os.Getenv("WATCH_MODE") == "true"
}
func IsDevelopment() bool {
return os.Getenv("ENV") == "development"
}
func IsProduction() bool {
return os.Getenv("ENV") == "production"
}

View file

@ -0,0 +1,18 @@
package process
import (
"log/slog"
"os"
"os/exec"
)
func RunOrExit(command string) {
cmd := exec.Command("bash", "-c", command)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
slog.Error("Error running command: ", slog.String("command", command))
os.Exit(1)
}
}

2
notes.md Normal file
View file

@ -0,0 +1,2 @@
structured logging - https://go.dev/blog/slog

View file

@ -1,5 +1,7 @@
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@ -17,6 +19,7 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=

View file

@ -1,2 +1 @@
go install github.com/maddalax/htmgo/framework/tooling/htmgo@latest
go run htmgo -task template
go run github.com/maddalax/cli/htmgo@latest template

View file

@ -0,0 +1,3 @@
package ent
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema

View file

@ -0,0 +1,42 @@
package schema
import (
"entgo.io/ent"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema/field"
"time"
)
// User holds the schema definition for the User entity.
type User struct {
ent.Schema
}
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.Int("age").
Positive(),
field.String("name").
Default("unknown"),
field.String("occupation").Optional(),
field.String("email").Optional(),
field.String("password").Sensitive().Optional(),
field.String("test").Optional(),
field.String("test2").Optional(),
field.String("test4").Optional(),
field.Time("created_at").
Default(time.Now).Annotations(
entsql.Default("CURRENT_TIMESTAMP"),
),
field.Time("updated_at").
Default(time.Now).Annotations(
entsql.Default("CURRENT_TIMESTAMP"),
),
}
}
// Edges of the User.
func (User) Edges() []ent.Edge {
return nil
}

View file

@ -3,20 +3,38 @@ module starter-template
go 1.23.0
require (
entgo.io/ent v0.14.1
github.com/gofiber/fiber/v2 v2.52.5
github.com/maddalax/htmgo/framework v0.0.0-20240916224719-9e5d8edada65
)
require (
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
github.com/agext/levenshtein v1.2.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/zclconf/go-cty v1.8.0 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)

View file

@ -1,9 +1,12 @@
package main
import (
"context"
"github.com/gofiber/fiber/v2"
"github.com/maddalax/htmgo/framework/h"
_ "github.com/mattn/go-sqlite3"
"log"
"starter-template/ent"
"starter-template/pages"
"starter-template/partials/load"
"time"
@ -30,6 +33,16 @@ func main() {
load.RegisterPartials(f)
pages.RegisterPages(f)
client, err := ent.Open("sqlite3", "file:ent.db?cache=shared&_fk=1")
if err != nil {
log.Fatalf("failed opening connection to sqlite: %v", err)
}
defer client.Close()
// Run the auto migration tool.
if err := client.Schema.Create(context.Background()); err != nil {
log.Fatalf("failed schema resources: %v", err)
}
h.Start(f, h.App{
LiveReload: true,
})