large changes

This commit is contained in:
2025-12-26 10:06:23 -05:00
parent 9d7dbc31ca
commit e4eb7d62e4
15 changed files with 119 additions and 90 deletions

View File

@@ -1,9 +0,0 @@
FROM alpine:3.20
ARG SITE
RUN echo "https://git.vxserver.dev/api/packages/fSD/alpine/main/fports" >> /etc/apk/repositories
&& apk update \
&& apk add --no-cache fes
ENTRYPOINT ["fes", "run", ${SITE}]

19
Makefile Normal file
View File

@@ -0,0 +1,19 @@
GO ?= go
.PHONY: build deps lint install
all: build
deps:
$(GO) mod download
build: deps
$(GO) build -ldflags "-X fes/modules/version.gitCommit=$(shell git rev-parse --short HEAD)" -o fes
@echo "Fes is now built to ./fes"
lint:
$(GO) vet ./...
$(GO) fmt ./...
install:
$(GO) install fes

View File

@@ -1,4 +1,4 @@
local std = require("core.std")
local std = require("lib.std")
local M = {}
M.__index = M

View File

@@ -1,5 +1,5 @@
local std = require("core.std")
local symbol = require("core.symbol")
local std = require("lib.std")
local symbol = require("lib.symbol")
local M = {}

24
main.go
View File

@@ -9,15 +9,15 @@ import (
"github.com/fatih/color"
"fes/src/config"
"fes/src/doc"
"fes/src/new"
"fes/src/server"
"fes/src/version"
"fes/modules/config"
"fes/modules/doc"
"fes/modules/new"
"fes/modules/server"
"fes/modules/version"
)
//go:embed core/*
var core embed.FS
//go:embed lib/*
var lib embed.FS
//go:embed index.html
var documentation string
@@ -25,7 +25,8 @@ var documentation string
func init() {
config.Port = flag.Int("p", 3000, "Set the server port")
config.Color = flag.Bool("no-color", false, "Disable color output")
config.Core = core
config.Static = flag.Bool("static", false, "Render and save all pages.")
config.Lib = lib
config.Doc = documentation
}
@@ -38,15 +39,22 @@ func main() {
fmt.Println(" run <project_dir> Start the server")
fmt.Println("Options:")
flag.PrintDefaults()
fmt.Println("For bug reports, contact a developer and describe the issue. Provide the output of the `-V1` flag.")
}
showVersion := flag.Bool("version", false, "Show version and exit")
showFullVersion := flag.Bool("V1", false, "Show extended version information and exit")
flag.Parse()
if *showVersion {
version.Version()
}
if *showFullVersion {
version.FullVersion()
}
if *config.Color {
color.NoColor = true
}

View File

@@ -5,12 +5,13 @@ import (
"errors"
)
var Core embed.FS
var Lib embed.FS
var Doc string
var Port *int
var Color *bool
var Static *bool
type MyConfig struct {
type AppConfig struct {
App struct {
Name string `toml:"name"`
Version string `toml:"version"`

View File

@@ -1,7 +1,7 @@
package doc
import (
"fes/src/config"
"fes/modules/config"
"fmt"
"os"
"path/filepath"

View File

@@ -1,26 +1,20 @@
package server
import (
"fes/modules/config"
"fes/modules/ui"
"fmt"
"github.com/pelletier/go-toml/v2"
lua "github.com/yuin/gopher-lua"
"html/template"
"io/fs"
"net/http"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
"fes/src/config"
"fes/src/ui"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
"github.com/pelletier/go-toml/v2"
lua "github.com/yuin/gopher-lua"
)
type reqData struct {
@@ -28,42 +22,6 @@ type reqData struct {
params map[string]string
}
func joinBase(base, name string) string {
if base == "" {
return "/" + name
}
return base + "/" + name
}
func basePath(base string) string {
if base == "" || base == "." {
return "/"
}
return base
}
func fixMalformedToml(content string) string {
re := regexp.MustCompile(`(?m)^(\s*\w+\s*=\s*)$`)
return re.ReplaceAllStringFunc(content, func(match string) string {
parts := strings.Split(strings.TrimSpace(match), "=")
if len(parts) == 2 && strings.TrimSpace(parts[1]) == "" {
key := strings.TrimSpace(parts[0])
return key + " = \"\""
}
return match
})
}
func markdownToHTML(mdText string) string {
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
p := parser.NewWithExtensions(extensions)
doc := p.Parse([]byte(mdText))
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{Flags: htmlFlags}
renderer := html.NewRenderer(opts)
return string(markdown.Render(doc, renderer))
}
func handleDir(entries []os.DirEntry, dir string, routes map[string]string, base string, isStatic bool) error {
for _, entry := range entries {
path := filepath.Join(dir, entry.Name())
@@ -136,18 +94,18 @@ func loadIncludeModules(L *lua.LState, includeDir string) *lua.LTable {
return app
}
func loadLua(entry string, cfg *config.MyConfig, requestData reqData) ([]byte, error) {
func loadLua(entry string, cfg *config.AppConfig, requestData reqData) ([]byte, error) {
L := lua.NewState()
defer L.Close()
coreFiles, err := fs.ReadDir(config.Core, "core")
libFiles, err := fs.ReadDir(config.Lib, "lib")
if err == nil {
for _, de := range coreFiles {
for _, de := range libFiles {
if de.IsDir() || !strings.HasSuffix(de.Name(), ".lua") {
continue
}
path := filepath.Join("core", de.Name())
fileData, err := config.Core.ReadFile(path)
path := filepath.Join("lib", de.Name())
fileData, err := config.Lib.ReadFile(path)
if err != nil {
continue
}
@@ -157,7 +115,7 @@ func loadLua(entry string, cfg *config.MyConfig, requestData reqData) ([]byte, e
preloadLuaModule := func(name, path string) {
L.PreloadModule(name, func(L *lua.LState) int {
fileData, err := config.Core.ReadFile(path)
fileData, err := config.Lib.ReadFile(path)
if err != nil {
panic(err)
}
@@ -169,24 +127,24 @@ func loadLua(entry string, cfg *config.MyConfig, requestData reqData) ([]byte, e
})
}
preloadLuaModule("core.std", "core/std.lua")
preloadLuaModule("core.symbol", "core/symbol.lua")
preloadLuaModule("core.util", "core/util.lua")
preloadLuaModule("lib.std", "lib/std.lua")
preloadLuaModule("lib.symbol", "lib/symbol.lua")
preloadLuaModule("lib.util", "lib/util.lua")
L.PreloadModule("fes", func(L *lua.LState) int {
mod := L.NewTable()
coreModules := []string{}
if ents, err := fs.ReadDir(config.Core, "core"); err == nil {
libModules := []string{}
if ents, err := fs.ReadDir(config.Lib, "lib"); err == nil {
for _, e := range ents {
if e.IsDir() || !strings.HasSuffix(e.Name(), ".lua") {
continue
}
coreModules = append(coreModules, strings.TrimSuffix(e.Name(), ".lua"))
libModules = append(libModules, strings.TrimSuffix(e.Name(), ".lua"))
}
}
for _, modName := range coreModules {
path := filepath.Join("core", modName+".lua")
fileData, err := config.Core.ReadFile(path)
for _, modName := range libModules {
path := filepath.Join("lib", modName+".lua")
fileData, err := config.Lib.ReadFile(path)
if err != nil {
continue
}
@@ -199,7 +157,7 @@ func loadLua(entry string, cfg *config.MyConfig, requestData reqData) ([]byte, e
if !ok || tbl == nil {
tbl = L.NewTable()
}
if modName == "builtin" {
if modName == "fes" {
tbl.ForEach(func(k, v lua.LValue) { mod.RawSet(k, v) })
} else {
mod.RawSetString(modName, tbl)
@@ -351,7 +309,7 @@ func generateArchiveIndex(fsPath string, urlPath string) (string, error) {
return b.String(), nil
}
func generateNotFoundData(cfg *config.MyConfig) []byte {
func generateNotFoundData(cfg *config.AppConfig) []byte {
notFoundData := []byte(`
<html>
<head><title>404 Not Found</title></head>
@@ -397,14 +355,14 @@ func loadDirs() map[string]string {
return routes
}
func parseConfig() config.MyConfig {
func parseConfig() config.AppConfig {
tomlDocument, err := os.ReadFile("Fes.toml")
if err != nil {
ui.Error("failed to read Fes.toml", err)
os.Exit(1)
}
docStr := fixMalformedToml(string(tomlDocument))
var cfg config.MyConfig
var cfg config.AppConfig
if err := toml.Unmarshal([]byte(docStr), &cfg); err != nil {
ui.Warning("failed to parse Fes.toml", err)
cfg.App.Authors = []string{"unknown"}

45
modules/server/util.go Normal file
View File

@@ -0,0 +1,45 @@
package server
import (
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
"regexp"
"strings"
)
func joinBase(base, name string) string {
if base == "" {
return "/" + name
}
return base + "/" + name
}
func basePath(base string) string {
if base == "" || base == "." {
return "/"
}
return base
}
func fixMalformedToml(content string) string {
re := regexp.MustCompile(`(?m)^(\s*\w+\s*=\s*)$`)
return re.ReplaceAllStringFunc(content, func(match string) string {
parts := strings.Split(strings.TrimSpace(match), "=")
if len(parts) == 2 && strings.TrimSpace(parts[1]) == "" {
key := strings.TrimSpace(parts[0])
return key + " = \"\""
}
return match
})
}
func markdownToHTML(mdText string) string {
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
p := parser.NewWithExtensions(extensions)
doc := p.Parse([]byte(mdText))
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{Flags: htmlFlags}
renderer := html.NewRenderer(opts)
return string(markdown.Render(doc, renderer))
}

View File

@@ -5,8 +5,8 @@ import (
"fmt"
"strings"
"fes/src/config"
"fes/src/version"
"fes/modules/config"
"fes/modules/version"
"github.com/fatih/color"
)

View File

@@ -5,6 +5,8 @@ import (
"os"
)
var gitCommit string = "devel"
const PROGRAM_NAME string = "fes"
const PROGRAM_NAME_LONG string = "fes/fSD"
const VERSION string = "beta"
@@ -13,3 +15,8 @@ func Version() {
fmt.Printf("%s version %s\n", PROGRAM_NAME_LONG, VERSION)
os.Exit(0)
}
func FullVersion() {
fmt.Printf("%s+%s\n", VERSION, gitCommit)
os.Exit(0)
}