parent
167321bf1f
commit
56b9321382
@ -0,0 +1,29 @@ |
|||||||
|
# ---> Vim |
||||||
|
# Swap |
||||||
|
[._]*.s[a-v][a-z] |
||||||
|
!*.svg # comment out if you don't need vector files |
||||||
|
[._]*.sw[a-p] |
||||||
|
[._]s[a-rt-v][a-z] |
||||||
|
[._]ss[a-gi-z] |
||||||
|
[._]sw[a-p] |
||||||
|
|
||||||
|
# Session |
||||||
|
Session.vim |
||||||
|
Sessionx.vim |
||||||
|
|
||||||
|
# Temporary |
||||||
|
.netrwhist |
||||||
|
*~ |
||||||
|
# Auto-generated tag files |
||||||
|
tags |
||||||
|
# Persistent undo |
||||||
|
[._]*.un~ |
||||||
|
|
||||||
|
backup |
||||||
|
*.exe |
||||||
|
*.dll |
||||||
|
coverage |
||||||
|
coverage/* |
||||||
|
.venv |
||||||
|
*.gz |
||||||
|
public |
@ -0,0 +1,26 @@ |
|||||||
|
GO_IS_STUPID_EXE=
|
||||||
|
|
||||||
|
ifeq '$(OS)' 'Windows_NT' |
||||||
|
GO_IS_STUPID_EXE=.exe
|
||||||
|
endif |
||||||
|
|
||||||
|
build: |
||||||
|
go build .
|
||||||
|
|
||||||
|
test: |
||||||
|
go test zedshaw.games/ssgod/tests -c -o runtests$(GO_IS_STUPID_EXE)
|
||||||
|
./runtests$(GO_IS_STUPID_EXE)
|
||||||
|
|
||||||
|
docs: |
||||||
|
go tool pkgsite --open
|
||||||
|
|
||||||
|
coverage: |
||||||
|
go build -cover -o webapp
|
||||||
|
mkdir -p .coverage
|
||||||
|
echo "GOCOVERDIR=.coverage ./webapp"
|
||||||
|
|
||||||
|
cover_report: |
||||||
|
go tool covdata textfmt -i=.coverage -o coverage.txt
|
||||||
|
go tool cover -func=coverage.txt
|
||||||
|
go tool cover -html=coverage.txt -o coverage.html
|
||||||
|
open coverage.html
|
@ -0,0 +1,27 @@ |
|||||||
|
package config |
||||||
|
|
||||||
|
import ( |
||||||
|
"log" |
||||||
|
"github.com/BurntSushi/toml" |
||||||
|
) |
||||||
|
|
||||||
|
type config struct { |
||||||
|
Views string `toml:"views"` |
||||||
|
Layouts string `toml:"layouts"` |
||||||
|
} |
||||||
|
|
||||||
|
var Settings config |
||||||
|
|
||||||
|
func Load(path string) { |
||||||
|
metadata, err := toml.DecodeFile(path, &Settings) |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
log.Fatalf("error loading config.toml: %v", err) |
||||||
|
} |
||||||
|
|
||||||
|
bad_keys := metadata.Undecoded() |
||||||
|
|
||||||
|
if len(bad_keys) > 0 { |
||||||
|
log.Fatalf("unknown configuration keys: %v", bad_keys); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
module zedshaw.games/ssgod |
||||||
|
|
||||||
|
go 1.24.2 |
||||||
|
|
||||||
|
require ( |
||||||
|
github.com/BurntSushi/toml v1.5.0 |
||||||
|
github.com/gofiber/fiber/v2 v2.52.9 |
||||||
|
github.com/gofiber/template/html/v2 v2.1.3 |
||||||
|
github.com/stretchr/testify v1.10.0 |
||||||
|
) |
||||||
|
|
||||||
|
require ( |
||||||
|
github.com/andybalholm/brotli v1.1.0 // indirect |
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect |
||||||
|
github.com/gofiber/template v1.8.3 // indirect |
||||||
|
github.com/gofiber/utils v1.1.0 // indirect |
||||||
|
github.com/google/uuid v1.6.0 // indirect |
||||||
|
github.com/klauspost/compress v1.17.9 // 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.16 // indirect |
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect |
||||||
|
github.com/rivo/uniseg v0.2.0 // 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 |
||||||
|
golang.org/x/sys v0.28.0 // indirect |
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect |
||||||
|
) |
@ -0,0 +1,45 @@ |
|||||||
|
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= |
||||||
|
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= |
||||||
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= |
||||||
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= |
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||||
|
github.com/gofiber/fiber/v2 v2.52.9 h1:YjKl5DOiyP3j0mO61u3NTmK7or8GzzWzCFzkboyP5cw= |
||||||
|
github.com/gofiber/fiber/v2 v2.52.9/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= |
||||||
|
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= |
||||||
|
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= |
||||||
|
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o= |
||||||
|
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE= |
||||||
|
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= |
||||||
|
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= |
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= |
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
||||||
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= |
||||||
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= |
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= |
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= |
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= |
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= |
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= |
||||||
|
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= |
||||||
|
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= |
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||||
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= |
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= |
||||||
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= |
||||||
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= |
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= |
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= |
||||||
|
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= |
||||||
|
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= |
||||||
|
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= |
||||||
|
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= |
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||||
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= |
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= |
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= |
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
@ -0,0 +1,77 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"log" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
"io/fs" |
||||||
|
"path/filepath" |
||||||
|
"os" |
||||||
|
"github.com/gofiber/fiber/v2" |
||||||
|
"github.com/gofiber/template/html/v2" |
||||||
|
"zedshaw.games/ssgod/config" |
||||||
|
) |
||||||
|
|
||||||
|
func Fail(err error, format string, v ...any) error { |
||||||
|
err_format := fmt.Sprintf("ERROR: %v; %s", err, format) |
||||||
|
log.Printf(err_format, v...) |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
func RenderPages(pages_path string, target string, layout string) { |
||||||
|
engine := html.New(pages_path, ".html") |
||||||
|
engine.Load() |
||||||
|
|
||||||
|
err := filepath.WalkDir(pages_path, |
||||||
|
func(path string, d fs.DirEntry, err error) error { |
||||||
|
if !d.IsDir() { |
||||||
|
if err != nil { return Fail(err, "path: %s", path); } |
||||||
|
|
||||||
|
dir := filepath.Dir(path) |
||||||
|
err = os.MkdirAll(dir, 0750) |
||||||
|
if err != nil { |
||||||
|
return Fail(err, "making dir %s", dir); |
||||||
|
} |
||||||
|
|
||||||
|
split_path := strings.Split(path, string(os.PathSeparator))[1:] |
||||||
|
source_name := strings.Join(split_path, "/") // Render wants / even on windows
|
||||||
|
ext := filepath.Ext(source_name) |
||||||
|
template_name, found := strings.CutSuffix(source_name, ext) |
||||||
|
|
||||||
|
if found && ext == ".html" && template_name != layout { |
||||||
|
prefixed_path := append([]string{target}, split_path...) |
||||||
|
|
||||||
|
target_path := filepath.Join(prefixed_path...) |
||||||
|
_, err := os.Stat(target_path) |
||||||
|
|
||||||
|
if os.IsNotExist(err) { |
||||||
|
target_dir := filepath.Dir(target_path) |
||||||
|
log.Println("MAKING: ", target_dir) |
||||||
|
os.MkdirAll(target_dir, 0750) |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: compare time stamps and skip if not newer
|
||||||
|
|
||||||
|
out, err := os.OpenFile(target_path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) |
||||||
|
if err != nil { return Fail(err, "writing file %s", target_path) } |
||||||
|
|
||||||
|
// generate a data-testid for all pages based on template name
|
||||||
|
page_id := strings.ReplaceAll(template_name, "/", "-") + "-page" |
||||||
|
err = engine.Render(out, template_name, fiber.Map{"PageId": page_id}, layout) |
||||||
|
if err != nil { return Fail(err, "failed to render %s", path) } |
||||||
|
|
||||||
|
log.Printf("RENDER: %s -> %s", template_name, target_path) |
||||||
|
out.Close() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
}) |
||||||
|
|
||||||
|
if err != nil { log.Fatalf("can't walk content") } |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
config.Load("ssgod.toml") |
||||||
|
log.Printf("views=%s, layouts=%s", config.Settings.Views, config.Settings.Layouts) |
||||||
|
} |
@ -0,0 +1,2 @@ |
|||||||
|
views = "./views" |
||||||
|
layouts = "layouts/main" |
@ -0,0 +1,12 @@ |
|||||||
|
package tests |
||||||
|
|
||||||
|
import ( |
||||||
|
"testing" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
func TestBasic(t *testing.T) { |
||||||
|
assert := require.New(t) |
||||||
|
assert.Equal(100, 100) |
||||||
|
} |
Loading…
Reference in new issue