215 lines
4.7 KiB
Go
215 lines
4.7 KiB
Go
//go:build dev
|
|
|
|
/*
|
|
Package cmd
|
|
Copyright © 2024 Shane C. <shane@scaffoe.com>
|
|
*/
|
|
package cmd
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/a-h/templ/parser/v2"
|
|
"github.com/evanw/esbuild/pkg/api"
|
|
"github.com/kr/pretty"
|
|
"github.com/spf13/cobra"
|
|
"io"
|
|
"io/fs"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
var ignoredAssetExtensions = []string{
|
|
".css",
|
|
".js",
|
|
".ts",
|
|
}
|
|
|
|
var ignoredDirectories = []string{
|
|
"svg",
|
|
"dist",
|
|
}
|
|
var foundIcons []string
|
|
|
|
// assetsCmd represents the assets command
|
|
var assetsCmd = &cobra.Command{
|
|
Use: "assets",
|
|
Short: "Generates assets needed for webserver",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
err := filepath.Walk("./web/assets", func(path string, info os.FileInfo, err error) error {
|
|
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
relPath, _ := strings.CutPrefix(path, "web/assets/")
|
|
|
|
for _, dir := range ignoredDirectories {
|
|
if strings.HasPrefix(relPath, dir) {
|
|
return filepath.SkipDir
|
|
}
|
|
}
|
|
|
|
for _, ext := range ignoredAssetExtensions {
|
|
if strings.HasSuffix(info.Name(), ext) {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
distFolder, _ := strings.CutSuffix(relPath, info.Name())
|
|
|
|
if err := os.MkdirAll("web/assets/dist/"+distFolder, 0700); err != nil && !errors.Is(err, fs.ErrExist) {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
copyFile(path, filepath.Join("web/assets/dist/"+distFolder, info.Name()))
|
|
|
|
return nil
|
|
|
|
})
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
result := api.Build(api.BuildOptions{
|
|
Format: api.FormatESModule,
|
|
EntryPoints: []string{"./web/assets/js/*.ts", "./web/assets/js/**/*.ts"},
|
|
Outdir: "./web/assets/dist/js",
|
|
Sourcemap: api.SourceMapLinked,
|
|
MinifyWhitespace: true,
|
|
MinifyIdentifiers: true,
|
|
MinifySyntax: true,
|
|
Splitting: true,
|
|
Write: true,
|
|
TreeShaking: api.TreeShakingTrue,
|
|
Bundle: true,
|
|
})
|
|
if len(result.Errors) != 0 {
|
|
pretty.Println(result.Errors)
|
|
os.Exit(1)
|
|
}
|
|
|
|
tmplFile, err := parser.Parse("./web/views/auth/register/show.templ")
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
for _, node := range tmplFile.Nodes {
|
|
templateNode, ok := node.(parser.HTMLTemplate)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
for _, htmlTemplChild := range templateNode.Children {
|
|
if elExpress, ok := htmlTemplChild.(parser.TemplElementExpression); ok {
|
|
for _, htmlNode := range elExpress.Children {
|
|
if htmlNodeEl, ok := htmlNode.(parser.Element); ok {
|
|
parseHtmlNode(htmlNodeEl)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
err = filepath.Walk("./web/views/", func(path string, info os.FileInfo, err error) error {
|
|
if info.IsDir() || filepath.Ext(info.Name()) != ".templ" {
|
|
return nil
|
|
}
|
|
|
|
tmplFile, err := parser.Parse(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, node := range tmplFile.Nodes {
|
|
templateNode, ok := node.(parser.HTMLTemplate)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
for _, htmlTemplChild := range templateNode.Children {
|
|
if elExpress, ok := htmlTemplChild.(parser.TemplElementExpression); ok {
|
|
for _, htmlNode := range elExpress.Children {
|
|
if htmlNodeEl, ok := htmlNode.(parser.Element); ok {
|
|
parseHtmlNode(htmlNodeEl)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
for _, icon := range foundIcons {
|
|
copyFile(filepath.Join("web/assets/icons", icon+".svg"), filepath.Join("web/assets/dist/svg/", icon+".svg"))
|
|
}
|
|
|
|
},
|
|
}
|
|
|
|
func parseHtmlNode(node parser.Element) {
|
|
if node.Children != nil {
|
|
for _, nodeChild := range node.Children {
|
|
if nodeChildEl, ok := nodeChild.(parser.Element); ok {
|
|
parseHtmlNode(nodeChildEl)
|
|
}
|
|
}
|
|
}
|
|
|
|
if node.Name == "ion-icon" {
|
|
for _, attr := range node.Attributes {
|
|
if constAttr, ok := attr.(parser.ConstantAttribute); ok {
|
|
if constAttr.Name == "name" {
|
|
for _, icon := range foundIcons {
|
|
if constAttr.Value == icon {
|
|
return
|
|
}
|
|
}
|
|
foundIcons = append(foundIcons, constAttr.Value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
generateCmd.AddCommand(assetsCmd)
|
|
}
|
|
|
|
func copyFile(sourcePath, destinationPath string) {
|
|
sourcePath = filepath.Clean(sourcePath)
|
|
sourceFile, err := os.Open(sourcePath)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
defer sourceFile.Close()
|
|
|
|
destinationPath = filepath.Clean(destinationPath)
|
|
if _, err := os.Stat(filepath.Dir(destinationPath)); errors.Is(err, fs.ErrNotExist) {
|
|
if err := os.MkdirAll(filepath.Dir(destinationPath), 0700); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
}
|
|
|
|
destinationFile, err := os.Create(destinationPath)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
defer destinationFile.Close()
|
|
|
|
_, err = io.Copy(destinationFile, sourceFile)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
if err := sourceFile.Close(); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
if err := destinationFile.Close(); err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
}
|