Skip to content
Snippets Groups Projects
command.go 4.21 KiB
Newer Older
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 data file to use, default is 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"`
		} `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"`
}

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]) {

	err := filepath.Walk(d.HTML.Generate.Input, 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.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())
}