package main import ( "fmt" html2 "gitlab.schukai.com/oss/bob/html" 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"` Verbose bool `short:"v" long:"verbose" description:"Show verbose debug information"` 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"` Version struct { } `command:"version" description:"Prints the version" call:"PrintVersion"` } func (d *Definition) PrintVersion(s *xflags.Settings[Definition]) { fmt.Println(GetMnemonic() + " " + GetVersion() + " (" + GetBuild() + ")") } 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) } } if d.Verbose { fmt.Printf("Loaded data file %s\n", i) } } 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 } if d.Verbose { fmt.Printf("Prepare %s\n", 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 { if d.Verbose { fmt.Printf("Delete %s\n", 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) } if d.Verbose { fmt.Printf("Saved data file %s\n", 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()) }