add support for ignoring specific files for automatic page/partial routing

This commit is contained in:
maddalax 2024-10-21 10:06:18 -05:00
parent 245d63c7b2
commit 635b17dd7f
7 changed files with 114 additions and 36 deletions

View file

@ -2,7 +2,9 @@ package astgen
import (
"fmt"
"github.com/maddalax/htmgo/cli/htmgo/internal/dirutil"
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
"github.com/maddalax/htmgo/framework/h"
"go/ast"
"go/parser"
"go/token"
@ -24,6 +26,7 @@ type Partial struct {
FuncName string
Package string
Import string
Path string
}
const GeneratedDirName = "__htmgo"
@ -103,6 +106,7 @@ func findPublicFuncsReturningHPartial(dir string, predicate func(partial Partial
if selectorExpr.Sel.Name == "Partial" {
p := Partial{
Package: node.Name.Name,
Path: sliceCommonPrefix(cwd, path),
Import: sliceCommonPrefix(cwd, strings.ReplaceAll(filepath.Dir(path), `\`, `/`)),
FuncName: funcDecl.Name.Name,
}
@ -254,12 +258,18 @@ func buildGetPartialFromContext(builder *CodeBuilder, partials []Partial) {
}
func writePartialsFile() {
config := dirutil.GetConfig()
cwd := process.GetWorkingDir()
partialPath := filepath.Join(cwd, "partials")
partials, err := findPublicFuncsReturningHPartial(partialPath, func(partial Partial) bool {
return partial.FuncName != "GetPartialFromContext"
})
partials = h.Filter(partials, func(partial Partial) bool {
return !dirutil.IsGlobExclude(partial.Path, config.AutomaticPartialRoutingIgnore)
})
if err != nil {
fmt.Println(err)
return
@ -317,6 +327,7 @@ func formatRoute(path string) string {
}
func writePagesFile() {
config := dirutil.GetConfig()
builder := NewCodeBuilder(nil)
builder.AppendLine(GeneratedFileLine)
@ -326,6 +337,10 @@ func writePagesFile() {
pages, _ := findPublicFuncsReturningHPage("pages")
pages = h.Filter(pages, func(page Page) bool {
return !dirutil.IsGlobExclude(page.Path, config.AutomaticPageRoutingIgnore)
})
if len(pages) > 0 {
builder.AddImport(ModuleName)
}

View file

@ -5,12 +5,15 @@ import (
"log/slog"
"os"
"path"
"strings"
)
type ProjectConfig struct {
Tailwind bool `yaml:"tailwind"`
WatchIgnore []string `yaml:"watch_ignore"`
WatchFiles []string `yaml:"watch_files"`
Tailwind bool `yaml:"tailwind"`
WatchIgnore []string `yaml:"watch_ignore"`
WatchFiles []string `yaml:"watch_files"`
AutomaticPageRoutingIgnore []string `yaml:"automatic_page_routing_ignore"`
AutomaticPartialRoutingIgnore []string `yaml:"automatic_partial_routing_ignore"`
}
func DefaultProjectConfig() *ProjectConfig {
@ -25,7 +28,7 @@ func DefaultProjectConfig() *ProjectConfig {
}
}
func (cfg *ProjectConfig) EnhanceWithDefaults() *ProjectConfig {
func (cfg *ProjectConfig) Enhance() *ProjectConfig {
defaultCfg := DefaultProjectConfig()
if len(cfg.WatchFiles) == 0 {
cfg.WatchFiles = defaultCfg.WatchFiles
@ -33,6 +36,27 @@ func (cfg *ProjectConfig) EnhanceWithDefaults() *ProjectConfig {
if len(cfg.WatchIgnore) == 0 {
cfg.WatchIgnore = defaultCfg.WatchIgnore
}
for i, s := range cfg.AutomaticPartialRoutingIgnore {
parts := strings.Split(s, string(os.PathSeparator))
if len(parts) == 0 {
continue
}
if parts[0] != "partials" {
cfg.AutomaticPartialRoutingIgnore[i] = path.Join("partials", s)
}
}
for i, s := range cfg.AutomaticPageRoutingIgnore {
parts := strings.Split(s, string(os.PathSeparator))
if len(parts) == 0 {
continue
}
if parts[0] != "pages" {
cfg.AutomaticPageRoutingIgnore[i] = path.Join("pages", s)
}
}
return cfg
}
@ -50,7 +74,7 @@ func FromConfigFile(workingDir string) *ProjectConfig {
slog.Error("Error parsing config file", slog.String("file", filePath), slog.String("error", err.Error()))
os.Exit(1)
}
return cfg.EnhanceWithDefaults()
return cfg.Enhance()
}
}
}

View file

@ -41,6 +41,38 @@ func TestShouldNotSetTailwindTrue(t *testing.T) {
assert.Equal(t, 8, len(cfg.WatchFiles))
}
func TestShouldPrefixAutomaticPageRoutingIgnore(t *testing.T) {
t.Parallel()
cfg := DefaultProjectConfig()
cfg.AutomaticPageRoutingIgnore = []string{"somefile"}
cfg.Enhance()
assert.Equal(t, []string{"pages/somefile"}, cfg.AutomaticPageRoutingIgnore)
}
func TestShouldPrefixAutomaticPageRoutingIgnore_1(t *testing.T) {
t.Parallel()
cfg := DefaultProjectConfig()
cfg.AutomaticPageRoutingIgnore = []string{"pages/somefile/*"}
cfg.Enhance()
assert.Equal(t, []string{"pages/somefile/*"}, cfg.AutomaticPageRoutingIgnore)
}
func TestShouldPrefixAutomaticPartialRoutingIgnore(t *testing.T) {
t.Parallel()
cfg := DefaultProjectConfig()
cfg.AutomaticPartialRoutingIgnore = []string{"somefile/*"}
cfg.Enhance()
assert.Equal(t, []string{"partials/somefile/*"}, cfg.AutomaticPartialRoutingIgnore)
}
func TestShouldPrefixAutomaticPartialRoutingIgnore_1(t *testing.T) {
t.Parallel()
cfg := DefaultProjectConfig()
cfg.AutomaticPartialRoutingIgnore = []string{"partials/somefile/*"}
cfg.Enhance()
assert.Equal(t, []string{"partials/somefile/*"}, cfg.AutomaticPartialRoutingIgnore)
}
func writeConfigFile(t *testing.T, content string) string {
temp := os.TempDir()
os.Mkdir(temp, 0755)

View file

@ -30,7 +30,6 @@ func validateCommands(cmds []Command) {
panic(fmt.Sprintf("element is not allowed in lifecycle events. Got: %v", t))
default:
panic(fmt.Sprintf("type is not allowed in lifecycle events. Got: %v", t))
}
}
}

View file

@ -8,3 +8,11 @@ watch_ignore: [".git", "node_modules", "dist/*"]
# files to watch for changes, supports glob patterns through https://github.com/bmatcuk/doublestar
watch_files: ["**/*.go", "**/*.css", "**/*.md"]
# files or directories to ignore when automatically registering routes for pages
# supports glob patterns through https://github.com/bmatcuk/doublestar
automatic_page_routing_ignore: ["root.go"]
# files or directories to ignore when automatically registering routes for partials
# supports glob patterns through https://github.com/bmatcuk/doublestar
automatic_partial_routing_ignore: []

View file

@ -6,15 +6,13 @@ import (
)
func IndexPage(ctx *h.RequestContext) *h.Page {
return h.NewPage(
RootPage(
return RootPage(
h.Div(
h.Class("flex flex-col gap-4 items-center pt-24 min-h-screen bg-neutral-100"),
h.H3(h.Id("intro-text"), h.Text("hello htmgo"), h.Class("text-5xl")),
h.Div(
h.Class("flex flex-col gap-4 items-center pt-24 min-h-screen bg-neutral-100"),
h.H3(h.Id("intro-text"), h.Text("hello htmgo"), h.Class("text-5xl")),
h.Div(
h.Class("mt-3"),
partials.CounterForm(0),
),
h.Class("mt-3"),
partials.CounterForm(0),
),
),
)

View file

@ -4,28 +4,30 @@ import (
"github.com/maddalax/htmgo/framework/h"
)
func RootPage(children ...h.Ren) h.Ren {
return h.Html(
h.HxExtensions(h.BaseExtensions()),
h.Head(
h.Meta("viewport", "width=device-width, initial-scale=1"),
h.Link("/public/favicon.ico", "icon"),
h.Link("/public/apple-touch-icon.png", "apple-touch-icon"),
h.Meta("title", "htmgo template"),
h.Meta("charset", "utf-8"),
h.Meta("author", "htmgo"),
h.Meta("description", "this is a template"),
h.Meta("og:title", "htmgo template"),
h.Meta("og:url", "https://htmgo.dev"),
h.Link("canonical", "https://htmgo.dev"),
h.Meta("og:description", "this is a template"),
h.Link("/public/main.css", "stylesheet"),
h.Script("/public/htmgo.js"),
),
h.Body(
h.Div(
h.Class("flex flex-col gap-2 bg-white h-full"),
h.Fragment(children...),
func RootPage(children ...h.Ren) *h.Page {
return h.NewPage(
h.Html(
h.HxExtensions(h.BaseExtensions()),
h.Head(
h.Meta("viewport", "width=device-width, initial-scale=1"),
h.Link("/public/favicon.ico", "icon"),
h.Link("/public/apple-touch-icon.png", "apple-touch-icon"),
h.Meta("title", "htmgo template"),
h.Meta("charset", "utf-8"),
h.Meta("author", "htmgo"),
h.Meta("description", "this is a template"),
h.Meta("og:title", "htmgo template"),
h.Meta("og:url", "https://htmgo.dev"),
h.Link("canonical", "https://htmgo.dev"),
h.Meta("og:description", "this is a template"),
h.Link("/public/main.css", "stylesheet"),
h.Script("/public/htmgo.js"),
),
h.Body(
h.Div(
h.Class("flex flex-col gap-2 bg-white h-full"),
h.Fragment(children...),
),
),
),
)