fix build step
This commit is contained in:
parent
08337c9e8a
commit
8c51c5227e
14 changed files with 168 additions and 115 deletions
67
cli/htmgo/internal/dirutil/dir.go
Normal file
67
cli/htmgo/internal/dirutil/dir.go
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
package dirutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func CopyDir(srcDir, dstDir string, predicate func(path string, exists bool) bool) error {
|
||||
// Walk the source directory tree.
|
||||
return filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Construct the corresponding destination path.
|
||||
relPath, err := filepath.Rel(srcDir, srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dstPath := filepath.Join(dstDir, relPath)
|
||||
if info.IsDir() {
|
||||
// If it's a directory, create the corresponding directory in the destination.
|
||||
err := os.MkdirAll(dstPath, 0700)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create directory: %v", err)
|
||||
}
|
||||
} else {
|
||||
exists := true
|
||||
if _, err := os.Stat(dstPath); errors.Is(err, os.ErrNotExist) {
|
||||
exists = false
|
||||
}
|
||||
if predicate(srcPath, exists) {
|
||||
err := CopyFile(srcPath, dstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// If it's a file, copy the file.
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CopyFile(src, dst string) error {
|
||||
slog.Debug("copying file", slog.String("src", src), slog.String("dst", dst))
|
||||
// Open the source file for reading.
|
||||
srcFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open source file: %v", err)
|
||||
}
|
||||
defer srcFile.Close()
|
||||
// Create the destination file.
|
||||
dstFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create destination file: %v", err)
|
||||
}
|
||||
defer dstFile.Close()
|
||||
// Copy the content from srcFile to dstFile.
|
||||
_, err = io.Copy(dstFile, srcFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy file contents: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -2,14 +2,13 @@ package copyassets
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/maddalax/htmgo/cli/htmgo/internal/dirutil"
|
||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/module"
|
||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
||||
"golang.org/x/mod/modfile"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -36,60 +35,6 @@ func getModuleVersion(modulePath string) (string, error) {
|
|||
return "", fmt.Errorf("module %s not found in go.mod", modulePath)
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
// Open the source file for reading.
|
||||
srcFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open source file: %v", err)
|
||||
}
|
||||
defer srcFile.Close()
|
||||
// Create the destination file.
|
||||
dstFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create destination file: %v", err)
|
||||
}
|
||||
defer dstFile.Close()
|
||||
// Copy the content from srcFile to dstFile.
|
||||
_, err = io.Copy(dstFile, srcFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to copy file contents: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// copyDir copies a directory recursively from src to dst.
|
||||
func copyDir(srcDir, dstDir string, skip func(path string) bool) error {
|
||||
// Walk the source directory tree.
|
||||
return filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Construct the corresponding destination path.
|
||||
relPath, err := filepath.Rel(srcDir, srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dstPath := filepath.Join(dstDir, relPath)
|
||||
if info.IsDir() {
|
||||
// If it's a directory, create the corresponding directory in the destination.
|
||||
err := os.MkdirAll(dstPath, 0700)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create directory: %v", err)
|
||||
}
|
||||
} else {
|
||||
if skip != nil && skip(srcPath) {
|
||||
return nil
|
||||
}
|
||||
// If it's a file, copy the file.
|
||||
err := copyFile(srcPath, dstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func CopyAssets() {
|
||||
moduleName := "github.com/maddalax/htmgo/framework"
|
||||
modulePath := module.GetDependencyPath(moduleName)
|
||||
|
|
@ -119,14 +64,14 @@ func CopyAssets() {
|
|||
destDirDist := fmt.Sprintf("%s/dist", destDir)
|
||||
destDirCss := fmt.Sprintf("%s/css", destDir)
|
||||
|
||||
err := copyDir(assetDistDir, destDirDist, func(path string) bool {
|
||||
return false
|
||||
err := dirutil.CopyDir(assetDistDir, destDirDist, func(path string, exists bool) bool {
|
||||
return true
|
||||
})
|
||||
err = copyDir(assetCssDir, destDirCss, func(path string) bool {
|
||||
if strings.HasSuffix(path, "tailwind.config.js") {
|
||||
return true
|
||||
err = dirutil.CopyDir(assetCssDir, destDirCss, func(path string, exists bool) bool {
|
||||
if exists {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
return true
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ var workingDir string
|
|||
var commands = make([]CmdWithFlags, 0)
|
||||
|
||||
func AppendRunning(cmd *exec.Cmd, flags ...RunFlag) {
|
||||
slog.Debug("running", slog.String("command", strings.Join(cmd.Args, " ")))
|
||||
slog.Debug("running", slog.String("command", strings.Join(cmd.Args, " ")),
|
||||
slog.String("dir", cmd.Dir),
|
||||
slog.String("cwd", GetWorkingDir()))
|
||||
commands = append(commands, CmdWithFlags{flags: flags, cmd: cmd})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,18 @@ func Build() {
|
|||
astgen.GenAst(process.ExitOnError)
|
||||
css.GenerateCss(process.ExitOnError)
|
||||
process.RunOrExit("rm -rf ./dist")
|
||||
process.RunOrExit("mkdir -p ./dist/assets/dist")
|
||||
process.RunOrExit("cp -r ./assets/dist/* ./dist/assets/dist/")
|
||||
process.RunOrExit("go build -o \"./dist\" .")
|
||||
process.RunOrExit("mkdir -p ./dist")
|
||||
|
||||
//process.RunOrExit("mkdir -p ./dist/assets/dist")
|
||||
|
||||
//dirutil.CopyDir(
|
||||
// "./assets/dist",
|
||||
// "./dist/assets/dist",
|
||||
// func(path string, exists bool) bool {
|
||||
// return true
|
||||
// },
|
||||
//)
|
||||
|
||||
process.RunOrExit("go build -o ./dist .")
|
||||
process.RunOrExit("echo \"Build successful\"")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ func Start(opts AppOpts) {
|
|||
|
||||
func (a App) start() {
|
||||
|
||||
if a.Opts.Register != nil {
|
||||
a.Opts.Register(a.Echo)
|
||||
}
|
||||
|
||||
a.Echo.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
cc := &RequestContext{
|
||||
|
|
@ -59,10 +63,6 @@ func (a App) start() {
|
|||
}
|
||||
})
|
||||
|
||||
if a.Opts.Register != nil {
|
||||
a.Opts.Register(a.Echo)
|
||||
}
|
||||
|
||||
if a.Opts.LiveReload {
|
||||
AddLiveReloadHandler("/dev/livereload", a.Echo)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package dirwalk
|
|||
|
||||
import (
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -13,14 +13,14 @@ type Page struct {
|
|||
Parts []string
|
||||
}
|
||||
|
||||
func WalkPages(dir string) []Page {
|
||||
func WalkPages(dir string, system fs.FS) []Page {
|
||||
pages := make([]Page, 0)
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
fs.WalkDir(system, dir, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := info.Name()
|
||||
if !info.IsDir() && (strings.HasSuffix(name, ".md") || strings.HasSuffix(name, ".go")) {
|
||||
name := d.Name()
|
||||
if !d.IsDir() && (strings.HasSuffix(name, ".md") || strings.HasSuffix(name, ".go")) {
|
||||
fullPath := strings.Replace(path, dir, "", 1)
|
||||
fullPath = strings.TrimSuffix(fullPath, ".md")
|
||||
pages = append(pages, Page{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/renderer/html"
|
||||
"io"
|
||||
"os"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
type Renderer struct {
|
||||
|
|
@ -19,15 +19,13 @@ func NewRenderer() *Renderer {
|
|||
return &Renderer{cache: make(map[string]string)}
|
||||
}
|
||||
|
||||
func (r *Renderer) RenderFile(source string) string {
|
||||
func (r *Renderer) RenderFile(source string, system fs.FS) string {
|
||||
if val, ok := r.cache[source]; ok {
|
||||
return val
|
||||
}
|
||||
|
||||
o, err := os.Open(source)
|
||||
defer func(o *os.File) {
|
||||
_ = o.Close()
|
||||
}(o)
|
||||
o, err := system.Open(source)
|
||||
defer o.Close()
|
||||
|
||||
if err != nil {
|
||||
return ""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
|
|
@ -8,21 +9,42 @@ import (
|
|||
"htmgo-site/internal/markdown"
|
||||
"htmgo-site/pages"
|
||||
"htmgo-site/partials/load"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
//go:embed assets/dist/*
|
||||
var StaticAssets embed.FS
|
||||
|
||||
//go:embed md/*
|
||||
var MarkdownAssets embed.FS
|
||||
|
||||
func main() {
|
||||
locator := service.NewLocator()
|
||||
|
||||
service.Set(locator, service.Singleton, markdown.NewRenderer)
|
||||
|
||||
sub, err := fs.Sub(StaticAssets, "assets/dist")
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
h.Start(h.AppOpts{
|
||||
ServiceLocator: locator,
|
||||
LiveReload: true,
|
||||
Register: func(e *echo.Echo) {
|
||||
e.Static("/public", "./assets/dist")
|
||||
e.StaticFS("/public", sub)
|
||||
|
||||
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
c.Set("embeddedMarkdown", &MarkdownAssets)
|
||||
return next(c)
|
||||
}
|
||||
})
|
||||
|
||||
load.RegisterPartials(e)
|
||||
pages.RegisterPages(e)
|
||||
pages.RegisterMarkdown(e, "md", func(ctx echo.Context, path string) error {
|
||||
pages.RegisterMarkdown(e, "md", MarkdownAssets, func(ctx echo.Context, path string) error {
|
||||
return pages.MarkdownHandler(ctx.(*h.RequestContext), path)
|
||||
})
|
||||
},
|
||||
|
|
|
|||
1
htmgo-site/md/examples.md
Normal file
1
htmgo-site/md/examples.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
Coming soon
|
||||
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
**introduction:**
|
||||
|
||||
htmgo is a lightweight pure go way to build interactive websites / web applications using go & htmx.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"htmgo-site/internal/dirwalk"
|
||||
"htmgo-site/pages/base"
|
||||
)
|
||||
|
||||
func DocsPage(ctx *h.RequestContext) *h.Page {
|
||||
pages := dirwalk.WalkPages("md/docs")
|
||||
assets := ctx.Get("embeddedMarkdown").(*embed.FS)
|
||||
pages := dirwalk.WalkPages("md/docs", assets)
|
||||
|
||||
return h.NewPage(base.RootPage(
|
||||
h.Div(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||
"htmgo-site/internal/markdown"
|
||||
|
|
@ -24,11 +25,12 @@ func MarkdownPage(ctx *h.RequestContext, path string) *h.Element {
|
|||
}
|
||||
|
||||
func MarkdownContent(ctx *h.RequestContext, path string) *h.Element {
|
||||
embeddedMd := ctx.Get("embeddedMarkdown").(*embed.FS)
|
||||
renderer := service.Get[markdown.Renderer](ctx.ServiceLocator())
|
||||
return h.Div(
|
||||
h.Article(
|
||||
h.Class("prose max-w-sm pt-3 p-4 md:p-4 md:max-w-2xl prose-code:text-black"),
|
||||
h.Raw(renderer.RenderFile(path)),
|
||||
h.Raw(renderer.RenderFile(path, embeddedMd)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ package pages
|
|||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"htmgo-site/internal/dirwalk"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
func RegisterMarkdown(app *echo.Echo, dir string, handler func(ctx echo.Context, path string) error) {
|
||||
for _, page := range dirwalk.WalkPages(dir) {
|
||||
func RegisterMarkdown(app *echo.Echo, dir string, system fs.FS, handler func(ctx echo.Context, path string) error) {
|
||||
for _, page := range dirwalk.WalkPages(dir, system) {
|
||||
app.GET(page.RoutePath, func(ctx echo.Context) error {
|
||||
return handler(ctx, page.FilePath)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -25,34 +25,39 @@ func NavBar() *h.Element {
|
|||
{Name: "Examples", Url: "/examples"},
|
||||
}
|
||||
|
||||
return h.Nav(
|
||||
h.Class("bg-neutral-100 border border-b-slate-300 p-4 md:p-3"),
|
||||
h.Div(
|
||||
h.Class("max-w-[95%] md:max-w-prose mx-auto"),
|
||||
prelease := h.Div(h.Class("bg-yellow-200 text-yellow-800 text-center p-2"),
|
||||
h.Text("This is a prerelease version and generally should not be used at this time. Watch on github for the stable release!"),
|
||||
)
|
||||
|
||||
return h.Div(
|
||||
prelease,
|
||||
h.Nav(
|
||||
h.Class("bg-neutral-100 border border-b-slate-300 p-4 md:p-3"),
|
||||
h.Div(
|
||||
h.Class("flex justify-between items-center"),
|
||||
h.Class("max-w-[95%] md:max-w-prose mx-auto"),
|
||||
h.Div(
|
||||
h.Class("flex items-center"),
|
||||
h.A(
|
||||
h.Boost(),
|
||||
h.Class("text-2xl"),
|
||||
h.Href("/"),
|
||||
h.Text("htmgo"),
|
||||
)),
|
||||
h.Div(
|
||||
h.Class("flex gap-4 items-center"),
|
||||
h.List(navItems, func(item NavItem, index int) *h.Element {
|
||||
return h.Div(
|
||||
h.Class("flex items-center"),
|
||||
h.A(
|
||||
h.Boost(),
|
||||
h.Class(""),
|
||||
h.Href(item.Url),
|
||||
h.Text(item.Name),
|
||||
),
|
||||
)
|
||||
}),
|
||||
h.Div(h.Class("ml-2"), star),
|
||||
h.Class("flex justify-between items-center"),
|
||||
h.Div(
|
||||
h.Class("flex items-center"),
|
||||
h.A(
|
||||
h.Class("text-2xl"),
|
||||
h.Href("/"),
|
||||
h.Text("htmgo (prerelease)"),
|
||||
)),
|
||||
h.Div(
|
||||
h.Class("flex gap-4 items-center"),
|
||||
h.List(navItems, func(item NavItem, index int) *h.Element {
|
||||
return h.Div(
|
||||
h.Class("flex items-center"),
|
||||
h.A(
|
||||
h.Class(""),
|
||||
h.Href(item.Url),
|
||||
h.Text(item.Name),
|
||||
),
|
||||
)
|
||||
}),
|
||||
h.Div(h.Class("ml-2"), star),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue