diff --git a/d2cli/main.go b/d2cli/main.go index 2f87fee80..67a9cb631 100644 --- a/d2cli/main.go +++ b/d2cli/main.go @@ -322,6 +322,7 @@ func compile(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, rende Ruler: ruler, ThemeID: renderOpts.ThemeID, FontFamily: fontFamily, + InputPath: inputPath, } if renderOpts.Sketch { opts.FontFamily = go2.Pointer(d2fonts.HandDrawn) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 90555380d..243ce14f4 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -28,7 +28,7 @@ type CompileOptions struct { FS fs.FS } -func Compile(path string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph, error) { +func Compile(p string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph, error) { if opts == nil { opts = &CompileOptions{} } @@ -36,7 +36,7 @@ func Compile(path string, r io.RuneReader, opts *CompileOptions) (*d2graph.Graph opts.FS = os.DirFS("/") } - ast, err := d2parser.Parse(path, r, &d2parser.ParseOptions{ + ast, err := d2parser.Parse(p, r, &d2parser.ParseOptions{ UTF16: opts.UTF16, }) if err != nil { diff --git a/d2ir/import.go b/d2ir/import.go index 91a6fb986..e269a0cfd 100644 --- a/d2ir/import.go +++ b/d2ir/import.go @@ -2,6 +2,7 @@ package d2ir import ( "bufio" + "os" "path" "strings" @@ -82,7 +83,25 @@ func (c *compiler) __import(imp *d2ast.Import) (*Map, bool) { return ir, true } - f, err := c.fs.Open(impPath) + p := path.Clean(impPath) + if path.IsAbs(p) { + // Path cannot be absolute. DirFS does not accept absolute paths. We strip off the leading + // slash to make it relative to the root. + p = p[1:] + } else if c.fs == os.DirFS("/") { + wd, err := os.Getwd() + if err != nil { + c.errorf(imp, "failed to import %q: %v", impPath, err) + return nil, false + } + p = path.Join(wd, p) + // See above explanation. + if path.IsAbs(p) { + p = p[1:] + } + } + + f, err := c.fs.Open(p) if err != nil { c.errorf(imp, "failed to import %q: %v", impPath, err) return nil, false diff --git a/d2lib/d2.go b/d2lib/d2.go index 10fbb02e7..ede144a0f 100644 --- a/d2lib/d2.go +++ b/d2lib/d2.go @@ -31,6 +31,8 @@ type CompileOptions struct { // - pre-measured (web setting) // TODO maybe some will want to configure code font too, but that's much lower priority FontFamily *d2fonts.FontFamily + + InputPath string } func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target.Diagram, *d2graph.Graph, error) { @@ -38,7 +40,7 @@ func Compile(ctx context.Context, input string, opts *CompileOptions) (*d2target opts = &CompileOptions{} } - g, err := d2compiler.Compile("", strings.NewReader(input), &d2compiler.CompileOptions{ + g, err := d2compiler.Compile(opts.InputPath, strings.NewReader(input), &d2compiler.CompileOptions{ UTF16: opts.UTF16, }) if err != nil {