large changes
This commit is contained in:
@@ -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
19
Makefile
Normal 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
|
||||
@@ -1,4 +1,4 @@
|
||||
local std = require("core.std")
|
||||
local std = require("lib.std")
|
||||
|
||||
local M = {}
|
||||
M.__index = M
|
||||
@@ -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
24
main.go
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
@@ -1,7 +1,7 @@
|
||||
package doc
|
||||
|
||||
import (
|
||||
"fes/src/config"
|
||||
"fes/modules/config"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -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
45
modules/server/util.go
Normal 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))
|
||||
}
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"fes/src/config"
|
||||
"fes/src/version"
|
||||
"fes/modules/config"
|
||||
"fes/modules/version"
|
||||
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user