error-pages/internal/cli/build/command.go

156 lines
3.6 KiB
Go
Raw Normal View History

2021-09-29 15:38:50 +00:00
package build
import (
"os"
"path"
"github.com/pkg/errors"
2023-01-29 10:54:56 +00:00
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"gh.tarampamp.am/error-pages/internal/cli/shared"
"gh.tarampamp.am/error-pages/internal/config"
"gh.tarampamp.am/error-pages/internal/tpl"
2021-09-29 15:38:50 +00:00
)
2023-01-29 10:54:56 +00:00
type command struct {
c *cli.Command
}
2021-09-29 15:38:50 +00:00
// NewCommand creates `build` command.
2023-01-29 10:54:56 +00:00
func NewCommand(log *zap.Logger) *cli.Command {
var cmd = command{}
const (
generateIndexFlagName = "index"
disableL10nFlagName = "disable-l10n"
2021-09-29 15:38:50 +00:00
)
2023-01-29 10:54:56 +00:00
cmd.c = &cli.Command{
Name: "build",
Aliases: []string{"b"},
Usage: "build <output-directory>",
Description: "Build the error pages",
Action: func(c *cli.Context) error {
cfg, cfgErr := config.FromYamlFile(c.String(shared.ConfigFileFlag.Name))
if cfgErr != nil {
return cfgErr
2021-09-29 15:38:50 +00:00
}
2023-01-29 10:54:56 +00:00
if c.Args().Len() != 1 {
2021-09-29 15:38:50 +00:00
return errors.New("wrong arguments count")
}
2023-01-29 10:54:56 +00:00
return cmd.Run(log, cfg, c.Args().First(), c.Bool(generateIndexFlagName), c.Bool(disableL10nFlagName))
},
Flags: []cli.Flag{ // global flags
&cli.BoolFlag{
Name: generateIndexFlagName,
Aliases: []string{"i"},
Usage: "generate index page",
},
&cli.BoolFlag{
Name: disableL10nFlagName,
Usage: "disable error pages localization",
},
shared.ConfigFileFlag,
},
}
2021-09-29 15:38:50 +00:00
2023-01-29 10:54:56 +00:00
return cmd.c
}
2021-09-29 15:38:50 +00:00
const (
outHTMLFileExt = ".html"
outIndexFileName = "index"
outFilePerm = os.FileMode(0664)
outDirPerm = os.FileMode(0775)
)
2021-09-29 15:38:50 +00:00
2023-01-29 10:54:56 +00:00
func (cmd *command) Run(log *zap.Logger, cfg *config.Config, outDirectoryPath string, generateIndex, disableL10n bool) error { //nolint:funlen,lll
if len(cfg.Templates) == 0 {
return errors.New("no loaded templates")
}
2021-09-29 15:38:50 +00:00
log.Info("output directory preparing", zap.String("path", outDirectoryPath))
2021-09-29 15:38:50 +00:00
2023-01-29 10:54:56 +00:00
if err := cmd.createDirectory(outDirectoryPath, outDirPerm); err != nil {
return errors.Wrap(err, "cannot prepare output directory")
}
2021-09-29 15:38:50 +00:00
history, renderer := newBuildingHistory(), tpl.NewTemplateRenderer()
defer func() { _ = renderer.Close() }()
2021-09-29 15:38:50 +00:00
for _, template := range cfg.Templates {
log.Debug("template processing", zap.String("name", template.Name()))
2021-09-29 15:38:50 +00:00
for _, page := range cfg.Pages {
2023-01-29 10:54:56 +00:00
if err := cmd.createDirectory(path.Join(outDirectoryPath, template.Name()), outDirPerm); err != nil {
2021-10-06 17:38:00 +00:00
return err
2021-09-29 15:38:50 +00:00
}
var (
fileName = page.Code() + outHTMLFileExt
filePath = path.Join(outDirectoryPath, template.Name(), fileName)
)
content, renderingErr := renderer.Render(template.Content(), tpl.Properties{
Code: page.Code(),
Message: page.Message(),
Description: page.Description(),
ShowRequestDetails: false,
L10nDisabled: disableL10n,
})
if renderingErr != nil {
return renderingErr
}
2021-10-15 06:06:10 +00:00
if err := os.WriteFile(filePath, content, outFilePerm); err != nil {
return err
}
2021-09-29 15:38:50 +00:00
log.Debug("page rendered", zap.String("path", filePath))
2021-09-29 15:38:50 +00:00
if generateIndex {
history.Append(
template.Name(),
page.Code(),
page.Message(),
path.Join(template.Name(), fileName),
)
2021-09-29 15:38:50 +00:00
}
}
}
2021-09-29 15:38:50 +00:00
if generateIndex {
var filepath = path.Join(outDirectoryPath, outIndexFileName+outHTMLFileExt)
log.Info("index file generation", zap.String("path", filepath))
if err := history.WriteIndexFile(filepath, outFilePerm); err != nil {
return err
}
2021-09-29 15:38:50 +00:00
}
log.Info("job is done")
2021-09-29 15:38:50 +00:00
return nil
2021-09-29 15:38:50 +00:00
}
2023-01-29 10:54:56 +00:00
func (cmd *command) createDirectory(path string, perm os.FileMode) error {
2021-09-29 15:38:50 +00:00
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return os.MkdirAll(path, perm)
2021-09-29 15:38:50 +00:00
}
return err
}
if !stat.IsDir() {
return errors.New("is not a directory")
}
return nil
}