package main import ( "fmt" "github.com/charmbracelet/log" html2 "gitlab.schukai.com/oss/bob/html" "gitlab.schukai.com/oss/bob/release" "gitlab.schukai.com/oss/bob/style" template2 "gitlab.schukai.com/oss/bob/template" "gitlab.schukai.com/oss/bob/types" "gitlab.schukai.com/oss/libraries/go/application/xflags" "gopkg.in/yaml.v3" "os" "path" "path/filepath" ) type Definition struct { Help struct { } `command:"help" call:"PrintHelp" description:"Prints this help message"` Template struct { Prepare struct { Input string `short:"i" long:"input" description:"Directory with html files to prepare" required:"true"` Output string `short:"o" long:"output" description:"Directory to save prepared html files" required:"true"` DataFile string `short:"d" long:"data-file" description:"Name of the main data file" default:"data.yaml"` } `command:"prepare" description:"Prepare content from a file" call:"PrepareTemplate"` } `command:"template" description:"Template commands"` HTML struct { Generate struct { Input string `short:"i" long:"input" description:"Directory with prepared html files" required:"true"` Output string `short:"o" long:"output" description:"Directory to save generated template files" required:"true"` DataFiles string `short:"d" long:"data-files" description:"Directory with data files" required:"true"` } `command:"generate" description:"Generate html files from a file" call:"GenerateHTML"` Sync struct { Specification string `short:"s" long:"specification" description:"Specification file" required:"true"` } `command:"sync" description:"Sync html" call:"SyncHTML"` Cut struct { Specification string `short:"s" long:"specification" description:"Specification file" required:"true"` } `command:"cut" description:"Cut html" call:"CutHTML"` } `command:"html" description:"HTML related commands"` CSS struct { Generate struct { Input string `short:"i" long:"input" description:"Directory with prepared html files" required:"true"` Output string `short:"o" long:"output" description:"File to save generated css file" required:"true"` } `command:"generate" description:"Generate css files from a file" call:"GenerateCSS"` } `command:"css" description:"CSS related commands"` Version struct { } `command:"version" description:"Prints the version" call:"PrintVersion"` } func (d *Definition) GenerateCSS(s *xflags.Settings[Definition]) { err := style.GenerateCSS(d.CSS.Generate.Input, d.CSS.Generate.Output) if err != nil { s.AddError(err) } } func (d *Definition) PrintVersion(s *xflags.Settings[Definition]) { fmt.Println(release.GetMnemonic() + " " + release.GetVersion() + " (" + release.GetCommit() + ")") } func (d *Definition) CutHTML(s *xflags.Settings[Definition]) { err := html2.CutHtml(d.HTML.Cut.Specification) if err != nil { s.AddError(err) } } func (d *Definition) SyncHTML(s *xflags.Settings[Definition]) { err := html2.SyncHtml(d.HTML.Sync.Specification) if err != nil { s.AddError(err) } } func (d *Definition) GenerateHTML(s *xflags.Settings[Definition]) { if d.HTML.Generate.DataFiles == "" { d.HTML.Generate.DataFiles = d.HTML.Generate.Input } err := filepath.Walk(d.HTML.Generate.DataFiles, func(p string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } ext := filepath.Ext(p) if ext != ".yaml" { return nil } return html2.GenerateFiles(p, d.HTML.Generate.Input, d.HTML.Generate.Output) }) if err != nil { s.AddError(err) } } func (d *Definition) PrepareTemplate(s *xflags.Settings[Definition]) { storage := types.NewPageDataStorage() i := d.GetDataFile() // unmarshal data file yaml to page data storage if _, err := os.Stat(i); err == nil { data, err := os.ReadFile(i) if err != nil { s.AddError(err) } else { err = yaml.Unmarshal(data, storage) if err != nil { s.AddError(err) } } log.Info("Loaded data file " + i) // reset all content entries storage.ResetContent() } toDelete := []string{} for page, _ := range storage { toDelete = append(toDelete, page) } err := filepath.Walk(d.Template.Prepare.Input, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { return nil } ext := filepath.Ext(path) if ext != ".html" && ext != ".htm" { return nil } log.Info("Prepare " + path) key, err := template2.PrepareHtmlFile(path, d.Template.Prepare.Output, storage) if err != nil { return err } for i, v := range toDelete { if v == key { toDelete = append(toDelete[:i], toDelete[i+1:]...) break } } return nil }) for _, v := range toDelete { log.Info("Delete " + v) delete(storage, v) } if err != nil { s.AddError(err) } data, err := yaml.Marshal(storage) if err != nil { s.AddError(err) } else { o := d.GetDataFile() err = os.WriteFile(o, data, os.ModePerm) if err != nil { s.AddError(err) } log.Info("Saved data file " + o) } } func (d *Definition) GetDataFile() string { o := d.Template.Prepare.DataFile if o == "" { o = "data.yaml" } if !path.IsAbs(o) { o = path.Join(d.Template.Prepare.Output, o) } return o } func (d *Definition) PrintHelp(s *xflags.Settings[Definition]) { fmt.Println(s.Help()) }