Refactor and fix argument handling

- Move all Typst arguments into the respective Args methods the Options* types
- Simplify the logic in the Caller implementations
- Add docker volume handling for other commands than compile
- Get rid of options_test.go as its test got replaced with the TestCLI_FontsWithFontPaths test
This commit is contained in:
David Vogel 2025-11-16 16:07:00 +00:00
parent e8620ad02b
commit b985940483
4 changed files with 51 additions and 68 deletions

19
cli.go
View File

@ -64,12 +64,11 @@ func (c CLI) Fonts(options *OptionsFonts) ([]string, error) {
return nil, fmt.Errorf("not supported on this platform")
}
args := []string{"fonts"}
if options != nil {
args = append(args, options.Args()...)
if options == nil {
options = new(OptionsFonts)
}
cmd := exec.Command(execPath, args...)
cmd := exec.Command(execPath, options.Args()...)
cmd.Dir = c.WorkingDirectory
var output, errBuffer bytes.Buffer
@ -97,12 +96,6 @@ func (c CLI) Fonts(options *OptionsFonts) ([]string, error) {
// Compile takes a Typst document from input, and renders it into the output writer.
// The options parameter is optional, and can be nil.
func (c CLI) Compile(input io.Reader, output io.Writer, options *OptionsCompile) error {
args := []string{"c"}
if options != nil {
args = append(args, options.Args()...)
}
args = append(args, "--diagnostic-format", "human", "-", "-") // TODO: Move these default arguments into OptionsCompile
// Get path of executable.
execPath := ExecutablePath
if c.ExecutablePath != "" {
@ -112,7 +105,11 @@ func (c CLI) Compile(input io.Reader, output io.Writer, options *OptionsCompile)
return fmt.Errorf("not supported on this platform")
}
cmd := exec.Command(execPath, args...)
if options == nil {
options = new(OptionsCompile)
}
cmd := exec.Command(execPath, options.Args()...)
cmd.Dir = c.WorkingDirectory
cmd.Stdin = input
cmd.Stdout = output

View File

@ -38,14 +38,32 @@ type Docker struct {
// Ensure that Docker implements the Caller interface.
var _ Caller = Docker{}
// VersionString returns the Typst version as a string.
func (d Docker) VersionString() (string, error) {
// args returns docker related arguments.
func (d Docker) args() []string {
image := DockerDefaultImage
if d.Image != "" {
image = d.Image
}
cmd := exec.Command("docker", "run", "-i", image, "--version")
// Argument -i is needed for stdio to work.
args := []string{"run", "-i"}
// Add mounts.
for _, volume := range d.Volumes {
args = append(args, "-v", volume)
}
// Which docker image to use.
args = append(args, image)
return args
}
// VersionString returns the Typst version as a string.
func (d Docker) VersionString() (string, error) {
args := append(d.args(), "--version")
cmd := exec.Command("docker", args...)
var output, errBuffer bytes.Buffer
cmd.Stdout = &output
@ -66,15 +84,12 @@ func (d Docker) VersionString() (string, error) {
// Fonts returns all fonts that are available to Typst.
// The options parameter is optional, and can be nil.
func (d Docker) Fonts(options *OptionsFonts) ([]string, error) {
image := DockerDefaultImage
if d.Image != "" {
image = d.Image
}
args := d.args()
args := []string{"run", "-i", image, "fonts"}
if options != nil {
args = append(args, options.Args()...)
if options == nil {
options = new(OptionsFonts)
}
args = append(args, options.Args()...)
cmd := exec.Command("docker", args...)
@ -103,28 +118,14 @@ func (d Docker) Fonts(options *OptionsFonts) ([]string, error) {
// Compile takes a Typst document from input, and renders it into the output writer.
// The options parameter is optional, and can be nil.
func (d Docker) Compile(input io.Reader, output io.Writer, options *OptionsCompile) error {
image := DockerDefaultImage
if d.Image != "" {
image = d.Image
}
// Argument -i is needed for stdio to work.
args := []string{"run", "-i"}
// Add mounts.
for _, volume := range d.Volumes {
args = append(args, "-v", volume)
}
args = append(args, image)
args := d.args()
// From here on come Typst arguments.
args = append(args, "c")
if options != nil {
args = append(args, options.Args()...)
if options == nil {
options = new(OptionsCompile)
}
args = append(args, "--diagnostic-format", "human", "-", "-") // TODO: Move these default arguments into Options
args = append(args, options.Args()...)
cmd := exec.Command("docker", args...)
cmd.Dir = d.WorkingDirectory

View File

@ -57,6 +57,9 @@ type OptionsFonts struct {
// Args returns a list of CLI arguments that should be passed to the executable.
func (o *OptionsFonts) Args() (result []string) {
// The first argument is the command we want to run.
result = []string{"fonts"}
if len(o.FontPaths) > 0 {
var paths string
for i, path := range o.FontPaths {
@ -118,6 +121,9 @@ type OptionsCompile struct {
// Args returns a list of CLI arguments that should be passed to the executable.
func (o *OptionsCompile) Args() (result []string) {
// The first argument is the command we want to run.
result = []string{"c"}
if o.Root != "" {
result = append(result, "--root", o.Root)
}
@ -194,7 +200,15 @@ func (o *OptionsCompile) Args() (result []string) {
result = append(result, "--pdf-standard", standards)
}
// Use human diagnostic format, as that's the format that we support right now.
// TODO: Switch to a different diagnostic format in the future
result = append(result, "--diagnostic-format", "human")
result = append(result, o.Custom...)
// Use stdio for input and output.
// TODO: Add Args parameters for when we want to use files instead
result = append(result, "-", "-")
return
}

View File

@ -1,29 +0,0 @@
// Copyright (c) 2025 David Vogel
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
package typst_test
import (
"os"
"testing"
"github.com/Dadido3/go-typst"
)
func TestOptions(t *testing.T) {
o := typst.OptionsCompile{
FontPaths: []string{"somepath/to/somewhere", "another/to/somewhere"},
}
args := o.Args()
if len(args) != 2 {
t.Errorf("wrong number of arguments, expected 2, got %d", len(args))
}
if args[0] != "--font-path" {
t.Error("wrong font path option, expected --font-path, got", args[0])
}
if args[1] != "somepath/to/somewhere"+string(os.PathListSeparator)+"another/to/somewhere" {
t.Error("wrong font path option, expected my two paths concatenated, got", args[1])
}
}