Compare commits
91 Commits
prototype
...
refactor/l
| Author | SHA1 | Date | |
|---|---|---|---|
|
242559acc9
|
|||
|
c2bddbf32c
|
|||
|
c5043a3527
|
|||
|
1351cd0cde
|
|||
|
51bb55816c
|
|||
|
f13dc0fe0f
|
|||
|
7b6796e2c1
|
|||
|
4875f47f94
|
|||
|
fafd7f76bf
|
|||
|
489a696e82
|
|||
|
d2308b5a1b
|
|||
|
1edc9c6ff0
|
|||
|
4063a6fb0d
|
|||
|
e16e57f387
|
|||
| f1e9468f09 | |||
| 0af4ea3074 | |||
| 67230ba75d | |||
| c2bbd80dce | |||
| 23ac6d6220 | |||
| 5b5de7b206 | |||
| b14b0be66b | |||
| a7b5ab174b | |||
| 478dd0216e | |||
| c27b0a4e12 | |||
| 11312ef5fe | |||
| d74d71dfa3 | |||
| 6ceef9664a | |||
| 19cf6e13cc | |||
| dd1d67207d | |||
| 6372b20a0b | |||
| f27784a0b2 | |||
| c05086a93e | |||
| 3ae232a779 | |||
| 535b7aa975 | |||
| 218b991caa | |||
| 0e96046259 | |||
| 013ed1002a | |||
| 0ed5f27f92 | |||
| e769a59b57 | |||
| 7d49a0fd81 | |||
| 012d0b3137 | |||
| 1e00971f62 | |||
| 853c86af0a | |||
| 96dc9ce119 | |||
| 3ace8799e2 | |||
| ea22eedd0e | |||
| 409cb86070 | |||
| 1034cc4906 | |||
| 390774600f | |||
| 5448517b67 | |||
| 50e0ee7bcb | |||
| 6a561f7d6f | |||
| fbbbb39fc8 | |||
| d65abd3e6f | |||
| 27f29990f5 | |||
| c12db37dc2 | |||
| a72b2d0482 | |||
| f80dd84784 | |||
| 2219de640d | |||
| d3bb613252 | |||
| fb97c490a8 | |||
| d74a13bfd6 | |||
| c55a516a3d | |||
| f3f060ddc8 | |||
| 65e34b4e29 | |||
| 5157deda2a | |||
| 35dbf51fb0 | |||
| 8a44e0821d | |||
| bfd24e0dc7 | |||
| a183a5a069 | |||
| 8a4a7f06ad | |||
| 0222d191e9 | |||
| 4ffe2f4e9e | |||
| 8388e2763e | |||
| 36ab51b337 | |||
| cfac969a12 | |||
| 09e1a0ce1e | |||
| d9eb24b9cd | |||
| 78718c29bf | |||
| e70e18aee5 | |||
| 518c712038 | |||
| fe427c0394 | |||
| a01742828e | |||
| 34c6b7ccb4 | |||
| f1d312bfce | |||
| 32d393c1da | |||
| 4f423794a3 | |||
| 47c570855f | |||
| 1c7131c216 | |||
| bb0c4b371a | |||
| 9cd1e1b1e9 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.dist
|
||||
wind.css
|
||||
.tmp
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "x"]
|
||||
path = x
|
||||
url = https://forge.capytal.company/loreddev/x
|
||||
20
.golangci.yml
Normal file
20
.golangci.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
modules-download-mode: readonly
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- errcheck
|
||||
- goimports
|
||||
- gofumpt
|
||||
- revive # golint
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch APP",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/main.go"
|
||||
},
|
||||
{
|
||||
"name": "Launch APP (Dev)",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/main.go",
|
||||
"args": [ "-dev" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
77
cmd/cmd.go
Normal file
77
cmd/cmd.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/router"
|
||||
"forge.capytal.company/loreddev/x/tinyssert"
|
||||
)
|
||||
|
||||
var (
|
||||
host = flag.String("host", "localhost", "Host to listen to")
|
||||
port = flag.Uint("port", 8080, "Port to be used for the server.")
|
||||
templatesDir = flag.String("templates", "", "Templates directory to be used instead of built-in ones.")
|
||||
verbose = flag.Bool("verbose", false, "Print debug information on logs")
|
||||
dev = flag.Bool("dev", false, "Run the server in debug mode.")
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
ctx := context.Background()
|
||||
|
||||
assertions := tinyssert.NewDisabledAssertions()
|
||||
if *dev {
|
||||
assertions = tinyssert.NewAssertions()
|
||||
}
|
||||
|
||||
level := slog.LevelError
|
||||
if *dev {
|
||||
level = slog.LevelDebug
|
||||
} else if *verbose {
|
||||
level = slog.LevelInfo
|
||||
}
|
||||
log := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: level}))
|
||||
|
||||
app := router.New(assertions, log, *dev)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", *host, *port),
|
||||
Handler: app,
|
||||
}
|
||||
|
||||
c, stop := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
go func() {
|
||||
log.Info("Starting application",
|
||||
slog.String("host", *host),
|
||||
slog.Uint64("port", uint64(*port)),
|
||||
slog.Bool("verbose", *verbose),
|
||||
slog.Bool("development", *dev))
|
||||
|
||||
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
log.Error("Failed to start application", slog.String("error", err.Error()))
|
||||
}
|
||||
}()
|
||||
|
||||
<-c.Done()
|
||||
|
||||
log.Info("Stopping application gracefully")
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
log.Error("Failed to stop application gracefully", slog.String("error", err.Error()))
|
||||
}
|
||||
|
||||
log.Info("FINAL")
|
||||
os.Exit(0)
|
||||
}
|
||||
25
flake.nix
25
flake.nix
@@ -3,10 +3,7 @@
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
};
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
}: let
|
||||
outputs = {nixpkgs, ...}: let
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
@@ -21,11 +18,23 @@
|
||||
in {
|
||||
devShells = forAllSystems (system: pkgs: {
|
||||
default = pkgs.mkShell {
|
||||
CGO_ENABLED = "0";
|
||||
hardeningDisable = ["all"];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
eslint
|
||||
nodejs_22
|
||||
nodePackages_latest.prettier
|
||||
bun
|
||||
# Go tools
|
||||
go
|
||||
golangci-lint
|
||||
gofumpt
|
||||
gotools
|
||||
delve
|
||||
|
||||
# TailwindCSS
|
||||
tailwindcss
|
||||
|
||||
# Sqlite tools
|
||||
sqlite
|
||||
lazysql
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
7
go.mod
Normal file
7
go.mod
Normal file
@@ -0,0 +1,7 @@
|
||||
module forge.capytal.company/capytalcode/project-comicverse
|
||||
|
||||
go 1.23.3
|
||||
|
||||
toolchain go1.23.6
|
||||
|
||||
require forge.capytal.company/loreddev/x v0.0.0-20250227192157-90a5169f1bef
|
||||
2
go.sum
Normal file
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
||||
forge.capytal.company/loreddev/x v0.0.0-20250227192157-90a5169f1bef h1:IJ9z7otITB5hhjZ+bmU0yOVsa8K1RWYIZ+cQj9XF6NY=
|
||||
forge.capytal.company/loreddev/x v0.0.0-20250227192157-90a5169f1bef/go.mod h1:MnU08vmXvYIQlQutVcC6o6Xq1KHZuXGXO78bbHseCFo=
|
||||
7
main.go
Normal file
7
main.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
import "forge.capytal.company/capytalcode/project-comicverse/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
}
|
||||
42
makefile
Normal file
42
makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
PORT?=8080
|
||||
|
||||
lint:
|
||||
golangci-lint run .
|
||||
|
||||
fmt:
|
||||
go fmt .
|
||||
golangci-lint run --fix .
|
||||
|
||||
dev/server:
|
||||
go run github.com/joho/godotenv/cmd/godotenv@v1.5.1 \
|
||||
go run github.com/air-verse/air@v1.52.2 \
|
||||
--build.cmd "go build -o .tmp/bin/main ." \
|
||||
--build.bin ".tmp/bin/main" \
|
||||
--build.exclude_dir "node_modules" \
|
||||
--build.include_ext "go,html" \
|
||||
--build.stop_on_error "false" \
|
||||
--proxy.enabled true \
|
||||
--proxy.proxy_port $(PORT) \
|
||||
--proxy.app_port $$(($(PORT) + 1)) \
|
||||
--misc.clean_on_exit true \
|
||||
-- -dev -port $$(($(PORT) + 1))
|
||||
|
||||
dev/assets:
|
||||
tailwindcss -o ./static/css/wind.css -w
|
||||
|
||||
dev:
|
||||
$(MAKE) -j2 dev/server dev/assets
|
||||
|
||||
|
||||
build:
|
||||
go generate
|
||||
go build -o ./.dist/app .
|
||||
|
||||
run: build
|
||||
./.dist/app
|
||||
|
||||
clean:
|
||||
# Remove generated directories
|
||||
if [[ -d ".dist" ]]; then rm -r ./.dist; fi
|
||||
if [[ -d "tmp" ]]; then rm -r ./tmp; fi
|
||||
if [[ -d "bin" ]]; then rm -r ./bin; fi
|
||||
52
router/router.go
Normal file
52
router/router.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"forge.capytal.company/capytalcode/project-comicverse/templates"
|
||||
"forge.capytal.company/loreddev/x/smalltrip"
|
||||
"forge.capytal.company/loreddev/x/smalltrip/exception"
|
||||
"forge.capytal.company/loreddev/x/smalltrip/middleware"
|
||||
"forge.capytal.company/loreddev/x/tinyssert"
|
||||
)
|
||||
|
||||
func New(assertions tinyssert.Assertions, log *slog.Logger, dev bool) http.Handler {
|
||||
r := smalltrip.NewRouter(
|
||||
smalltrip.WithAssertions(assertions),
|
||||
smalltrip.WithLogger(log.WithGroup("smalltrip")),
|
||||
)
|
||||
|
||||
r.Use(middleware.Logger(log.WithGroup("requests")))
|
||||
if dev {
|
||||
log.Debug("Development mode activated, using development middleware")
|
||||
r.Use(middleware.Dev)
|
||||
} else {
|
||||
r.Use(middleware.PersistentCache())
|
||||
}
|
||||
r.Use(exception.PanicMiddleware())
|
||||
r.Use(exception.Middleware())
|
||||
|
||||
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
err := templates.Templates().ExecuteTemplate(w, "index.html", nil)
|
||||
if err != nil {
|
||||
exception.InternalServerError(err).ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
r.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
|
||||
r.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
|
||||
exception.InternalServerError(errors.New("TEST ERROR"),
|
||||
exception.WithData("test-data", "test-value"),
|
||||
).ServeHTTP(w, r)
|
||||
})
|
||||
r.HandleFunc("/panic", func(w http.ResponseWriter, r *http.Request) {
|
||||
panic("TEST PANIC")
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func dashboard(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
0
static/css/.gitkeep
Normal file
0
static/css/.gitkeep
Normal file
24
static/static.go
Normal file
24
static/static.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
//go:generate tailwindcss -o static/css/wind.css
|
||||
|
||||
//go:embed css/*.css
|
||||
var staticFiles embed.FS
|
||||
|
||||
func Files(local ...bool) fs.FS {
|
||||
var l bool
|
||||
if len(local) > 0 {
|
||||
l = local[0]
|
||||
}
|
||||
|
||||
if !l {
|
||||
return staticFiles
|
||||
}
|
||||
|
||||
return staticFiles
|
||||
}
|
||||
1077
tailwind.config.js
Normal file
1077
tailwind.config.js
Normal file
File diff suppressed because it is too large
Load Diff
12
templates/index.html
Normal file
12
templates/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="/static/css/wind.css">
|
||||
</head>
|
||||
|
||||
<body class="text-red-600">
|
||||
<h1>Hello, world</h1>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
18
templates/templates.go
Normal file
18
templates/templates.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"html/template"
|
||||
)
|
||||
|
||||
//go:embed *.html test/*.html
|
||||
var embedded embed.FS
|
||||
|
||||
var temps = template.Must(template.ParseFS(embedded,
|
||||
"*.html",
|
||||
"test/*.html",
|
||||
))
|
||||
|
||||
func Templates() *template.Template {
|
||||
return temps
|
||||
}
|
||||
12
templates/test/test.html
Normal file
12
templates/test/test.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Hello, world 2</h1>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
x
Submodule
1
x
Submodule
Submodule x added at 0ccb26ab78
Reference in New Issue
Block a user