95 lines
1.9 KiB
Go
95 lines
1.9 KiB
Go
package internal
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os/exec"
|
|
)
|
|
|
|
// Generator provides the ability to generate a diagram.
|
|
type Generator interface {
|
|
// Generate generates the given diagram.
|
|
Generate(diagram *Diagram) error
|
|
}
|
|
|
|
func NewGenerator(cache DiagramCache, mermaidCLIPath string, inPath string, outPath string) Generator {
|
|
return &cachingGenerator{
|
|
cache: cache,
|
|
mermaidCLIPath: mermaidCLIPath,
|
|
inPath: inPath,
|
|
outPath: outPath,
|
|
}
|
|
}
|
|
|
|
// cachingGenerator is an implementation of Generator.
|
|
type cachingGenerator struct {
|
|
cache DiagramCache
|
|
mermaidCLIPath string
|
|
inPath string
|
|
outPath string
|
|
}
|
|
|
|
// Generate generates the given diagram.
|
|
func (c cachingGenerator) Generate(diagram *Diagram) error {
|
|
has, err := c.cache.Has(diagram)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if has {
|
|
cached, err := c.cache.Get(diagram)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*diagram = *cached
|
|
return nil
|
|
}
|
|
if err := c.generate(diagram); err != nil {
|
|
return err
|
|
}
|
|
if err := c.cache.Store(diagram); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// generate does the actual file generation.
|
|
func (c cachingGenerator) generate(diagram *Diagram) error {
|
|
id, err := diagram.ID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
has, err := c.cache.Has(diagram)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if has {
|
|
cached, err := c.cache.Get(diagram)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*diagram = *cached
|
|
return nil
|
|
}
|
|
|
|
inPath := fmt.Sprintf("%s/%s.mmd", c.inPath, id)
|
|
outPath := fmt.Sprintf("%s/%s.svg", c.outPath, id)
|
|
|
|
if err := ioutil.WriteFile(inPath, diagram.description, 0644); err != nil {
|
|
return err
|
|
}
|
|
|
|
cmd := exec.Command(c.mermaidCLIPath, "-i", inPath, "-o", outPath)
|
|
var stdOut bytes.Buffer
|
|
cmd.Stdout = bufio.NewWriter(&stdOut)
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("%w: %s", err, string(stdOut.Bytes()))
|
|
}
|
|
|
|
diagram.Output = outPath
|
|
|
|
return nil
|
|
}
|