Skip to content

Commit

Permalink
config vars
Browse files Browse the repository at this point in the history
  • Loading branch information
alixander committed Jul 20, 2023
1 parent 4adfb22 commit 0def0b3
Show file tree
Hide file tree
Showing 31 changed files with 2,042 additions and 227 deletions.
2 changes: 1 addition & 1 deletion d2chaos/d2chaos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func test(t *testing.T, textPath, text string) {
t.Fatal(err)
}

g, err := d2compiler.Compile("", strings.NewReader(text), nil)
g, _, err := d2compiler.Compile("", strings.NewReader(text), nil)
if err != nil {
t.Fatal(err)
}
Expand Down
132 changes: 88 additions & 44 deletions d2cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"oss.terrastruct.com/util-go/go2"
"oss.terrastruct.com/util-go/xmain"

"oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2lib"
"oss.terrastruct.com/d2/d2parser"
"oss.terrastruct.com/d2/d2plugin"
Expand Down Expand Up @@ -117,11 +118,11 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
fontBoldFlag := ms.Opts.String("D2_FONT_BOLD", "font-bold", "", "", "path to .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used.")
fontSemiboldFlag := ms.Opts.String("D2_FONT_SEMIBOLD", "font-semibold", "", "", "path to .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used.")

ps, err := d2plugin.ListPlugins(ctx)
plugins, err := d2plugin.ListPlugins(ctx)
if err != nil {
return err
}
err = populateLayoutOpts(ctx, ms, ps)
err = populateLayoutOpts(ctx, ms, plugins)
if err != nil {
return err
}
Expand All @@ -146,7 +147,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
case "init-playwright":
return initPlaywright()
case "layout":
return layoutCmd(ctx, ms, ps)
return layoutCmd(ctx, ms, plugins)
case "themes":
themesCmd(ctx, ms)
return nil
Expand Down Expand Up @@ -226,6 +227,38 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
}
ms.Log.Debug.Printf("using theme %s (ID: %d)", match.Name, *themeFlag)

// If flag is not explicitly set by user, set to nil.
// Later, configs from D2 code will only overwrite if they weren't explicitly set by user
flagSet := make(map[string]struct{})
ms.Opts.Flags.Visit(func(f *pflag.Flag) {
flagSet[f.Name] = struct{}{}
})
if ms.Env.Getenv("D2_LAYOUT") == "" {
if _, ok := flagSet["layout"]; !ok {
layoutFlag = nil
}
}
if ms.Env.Getenv("D2_THEME") == "" {
if _, ok := flagSet["theme"]; !ok {
themeFlag = nil
}
}
if ms.Env.Getenv("D2_SKETCH") == "" {
if _, ok := flagSet["sketch"]; !ok {
sketchFlag = nil
}
}
if ms.Env.Getenv("D2_PAD") == "" {
if _, ok := flagSet["pad"]; !ok {
padFlag = nil
}
}
if ms.Env.Getenv("D2_CENTER") == "" {
if _, ok := flagSet["center"]; !ok {
centerFlag = nil
}
}

if *darkThemeFlag == -1 {
darkThemeFlag = nil // TODO this is a temporary solution: https://github.com/terrastruct/util-go/issues/7
}
Expand All @@ -241,29 +274,6 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
scale = scaleFlag
}

plugin, err := d2plugin.FindPlugin(ctx, ps, *layoutFlag)
if err != nil {
if errors.Is(err, exec.ErrNotFound) {
return layoutNotFound(ctx, ps, *layoutFlag)
}
return err
}

err = d2plugin.HydratePluginOpts(ctx, ms, plugin)
if err != nil {
return err
}

pinfo, err := plugin.Info(ctx)
if err != nil {
return err
}
plocation := pinfo.Type
if pinfo.Type == "binary" {
plocation = fmt.Sprintf("executable plugin at %s", humanPath(pinfo.Path))
}
ms.Log.Debug.Printf("using layout plugin %s (%s)", *layoutFlag, plocation)

if !outputFormat.supportsDarkTheme() {
if darkThemeFlag != nil {
ms.Log.Warn.Printf("--dark-theme cannot be used while exporting to another format other than .svg")
Expand All @@ -285,10 +295,10 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
}

renderOpts := d2svg.RenderOpts{
Pad: int(*padFlag),
Sketch: *sketchFlag,
Center: *centerFlag,
ThemeID: *themeFlag,
Pad: padFlag,
Sketch: sketchFlag,
Center: centerFlag,
ThemeID: themeFlag,
DarkThemeID: darkThemeFlag,
Scale: scale,
}
Expand All @@ -298,7 +308,8 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
return xmain.UsageErrorf("-w[atch] cannot be combined with reading input from stdin")
}
w, err := newWatcher(ctx, ms, watcherOpts{
layoutPlugin: plugin,
plugins: plugins,
layout: layoutFlag,
renderOpts: renderOpts,
animateInterval: *animateIntervalFlag,
host: *hostFlag,
Expand All @@ -319,7 +330,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
ctx, cancel := timelib.WithTimeout(ctx, time.Minute*2)
defer cancel()

_, written, err := compile(ctx, ms, plugin, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, *bundleFlag, *forceAppendixFlag, pw.Page)
_, written, err := compile(ctx, ms, plugins, layoutFlag, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, *bundleFlag, *forceAppendixFlag, pw.Page)
if err != nil {
if written {
return fmt.Errorf("failed to fully compile (partial render written): %w", err)
Expand All @@ -329,7 +340,32 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
return nil
}

func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
func LayoutResolver(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin) func(engine string) (d2graph.LayoutGraph, error) {
cached := make(map[string]d2graph.LayoutGraph)
return func(engine string) (d2graph.LayoutGraph, error) {
if c, ok := cached[engine]; ok {
return c, nil
}

plugin, err := d2plugin.FindPlugin(ctx, plugins, engine)
if err != nil {
if errors.Is(err, exec.ErrNotFound) {
return nil, layoutNotFound(ctx, plugins, engine)
}
return nil, err
}

err = d2plugin.HydratePluginOpts(ctx, ms, plugin)
if err != nil {
return nil, err
}

cached[engine] = plugin.Layout
return plugin.Layout, nil
}
}

func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, layout *string, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
start := time.Now()
input, err := ms.ReadPath(inputPath)
if err != nil {
Expand All @@ -341,29 +377,27 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
return nil, false, err
}

layout := plugin.Layout
opts := &d2lib.CompileOptions{
Layout: layout,
Ruler: ruler,
ThemeID: renderOpts.ThemeID,
FontFamily: fontFamily,
InputPath: inputPath,
}
if renderOpts.Sketch {
opts.FontFamily = go2.Pointer(d2fonts.HandDrawn)
Ruler: ruler,
FontFamily: fontFamily,
InputPath: inputPath,
LayoutResolver: LayoutResolver(ctx, ms, plugins),
Layout: layout,
}

cancel := background.Repeat(func() {
ms.Log.Info.Printf("compiling & running layout algorithms...")
}, time.Second*5)
defer cancel()

diagram, g, err := d2lib.Compile(ctx, string(input), opts)
diagram, g, err := d2lib.Compile(ctx, string(input), opts, &renderOpts)
if err != nil {
return nil, false, err
}
cancel()

plugin, _ := d2plugin.FindPlugin(ctx, plugins, *opts.Layout)

if animateInterval > 0 {
masterID, err := diagram.HashID()
if err != nil {
Expand All @@ -372,6 +406,16 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende
renderOpts.MasterID = masterID
}

pinfo, err := plugin.Info(ctx)
if err != nil {
return nil, false, err
}
plocation := pinfo.Type
if pinfo.Type == "binary" {
plocation = fmt.Sprintf("executable plugin at %s", humanPath(pinfo.Path))
}
ms.Log.Debug.Printf("using layout plugin %s (%s)", *opts.Layout, plocation)

pluginInfo, err := plugin.Info(ctx)
if err != nil {
return nil, false, err
Expand Down Expand Up @@ -805,7 +849,7 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
if err != nil {
return svg, err
}
err = doc.AddPDFPage(pngImg, boardPath, opts.ThemeID, rootFill, diagram.Shapes, int64(opts.Pad), viewboxX, viewboxY, pageMap)
err = doc.AddPDFPage(pngImg, boardPath, *opts.ThemeID, rootFill, diagram.Shapes, *opts.Pad, viewboxX, viewboxY, pageMap)
if err != nil {
return svg, err
}
Expand Down
5 changes: 3 additions & 2 deletions d2cli/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ var devMode = false
var staticFS embed.FS

type watcherOpts struct {
layoutPlugin d2plugin.Plugin
layout *string
plugins []d2plugin.Plugin
renderOpts d2svg.RenderOpts
animateInterval int64
host string
Expand Down Expand Up @@ -361,7 +362,7 @@ func (w *watcher) compileLoop(ctx context.Context) error {
w.pw = newPW
}

svg, _, err := compile(ctx, w.ms, w.layoutPlugin, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, w.bundle, w.forceAppendix, w.pw.Page)
svg, _, err := compile(ctx, w.ms, w.plugins, w.layout, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, w.bundle, w.forceAppendix, w.pw.Page)
errs := ""
if err != nil {
if len(svg) > 0 {
Expand Down
52 changes: 47 additions & 5 deletions d2compiler/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type CompileOptions struct {
FS fs.FS
}

func Compile(p string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph, error) {
func Compile(p string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph, *d2target.Config, error) {
if opts == nil {
opts = &CompileOptions{}
}
Expand All @@ -36,24 +36,24 @@ func Compile(p string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph, e
UTF16: opts.UTF16,
})
if err != nil {
return nil, err
return nil, nil, err
}

ir, err := d2ir.Compile(ast, &d2ir.CompileOptions{
UTF16: opts.UTF16,
FS: opts.FS,
})
if err != nil {
return nil, err
return nil, nil, err
}

g, err := compileIR(ast, ir)
if err != nil {
return nil, err
return nil, nil, err
}
g.SortObjectsByAST()
g.SortEdgesByAST()
return g, nil
return g, compileConfig(ir), nil
}

func compileIR(ast *d2ast.Map, m *d2ir.Map) (*d2graph.Graph, error) {
Expand Down Expand Up @@ -1285,3 +1285,45 @@ func parentSeqDiagram(n d2ir.Node) *d2ir.Map {
n = m
}
}

func compileConfig(ir *d2ir.Map) *d2target.Config {
f := ir.GetField("vars", "d2-config")
if f == nil || f.Map() == nil {
return nil
}

configMap := f.Map()

config := &d2target.Config{}

f = configMap.GetField("sketch")
if f != nil {
val, _ := strconv.ParseBool(f.Primary().Value.ScalarString())
config.Sketch = &val
}

f = configMap.GetField("theme-id")
if f != nil {
val, _ := strconv.Atoi(f.Primary().Value.ScalarString())
config.ThemeID = go2.Pointer(int64(val))
}

f = configMap.GetField("dark-theme-id")
if f != nil {
val, _ := strconv.Atoi(f.Primary().Value.ScalarString())
config.DarkThemeID = go2.Pointer(int64(val))
}

f = configMap.GetField("pad")
if f != nil {
val, _ := strconv.Atoi(f.Primary().Value.ScalarString())
config.Pad = go2.Pointer(int64(val))
}

f = configMap.GetField("layout-engine")
if f != nil {
config.LayoutEngine = go2.Pointer(f.Primary().Value.ScalarString())
}

return config
}
Loading

0 comments on commit 0def0b3

Please sign in to comment.