Things I did while unable to commit
- Log rotation - Execution cancellation - HTTP redirect, error functions - Changed naming of document parsing/loading functions
This commit is contained in:
		
							parent
							
								
									f112a2e564
								
							
						
					
					
						commit
						bf668b0cf7
					
				@ -15,6 +15,7 @@ import "git.tebibyte.media/sashakoshka/go-cli"
 | 
				
			|||||||
import "git.tebibyte.media/sashakoshka/step/providers"
 | 
					import "git.tebibyte.media/sashakoshka/step/providers"
 | 
				
			||||||
import "git.tebibyte.media/sashakoshka/goutil/container"
 | 
					import "git.tebibyte.media/sashakoshka/goutil/container"
 | 
				
			||||||
import "git.tebibyte.media/sashakoshka/go-service/daemon"
 | 
					import "git.tebibyte.media/sashakoshka/go-service/daemon"
 | 
				
			||||||
 | 
					import "git.tebibyte.media/sashakoshka/go-service/rotate"
 | 
				
			||||||
import stephttp"git.tebibyte.media/sashakoshka/step/http"
 | 
					import stephttp"git.tebibyte.media/sashakoshka/step/http"
 | 
				
			||||||
import "git.tebibyte.media/sashakoshka/go-service/routines"
 | 
					import "git.tebibyte.media/sashakoshka/go-service/routines"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -26,6 +27,10 @@ func main () {
 | 
				
			|||||||
		'p', "pid-file",
 | 
							'p', "pid-file",
 | 
				
			||||||
		"Write the PID to the specified file.",
 | 
							"Write the PID to the specified file.",
 | 
				
			||||||
		"", cli.ValString)
 | 
							"", cli.ValString)
 | 
				
			||||||
 | 
						flagLogDirectory := cli.NewInputFlag (
 | 
				
			||||||
 | 
							'l', "log-directory",
 | 
				
			||||||
 | 
							"Write logs to the specified directory.",
 | 
				
			||||||
 | 
							"", cli.ValString)
 | 
				
			||||||
	flagHTTPAddress := cli.NewInputFlag (
 | 
						flagHTTPAddress := cli.NewInputFlag (
 | 
				
			||||||
		'h', "http-address",
 | 
							'h', "http-address",
 | 
				
			||||||
		"The address to host the HTTP server on.",
 | 
							"The address to host the HTTP server on.",
 | 
				
			||||||
@ -47,6 +52,7 @@ func main () {
 | 
				
			|||||||
	cmd := cli.New (
 | 
						cmd := cli.New (
 | 
				
			||||||
		"Run an HTTP server that automaticaly executes STEP files.",
 | 
							"Run an HTTP server that automaticaly executes STEP files.",
 | 
				
			||||||
		flagPidFile,
 | 
							flagPidFile,
 | 
				
			||||||
 | 
							flagLogDirectory,
 | 
				
			||||||
		flagHTTPAddress,
 | 
							flagHTTPAddress,
 | 
				
			||||||
		flagHTTPErrorDocument,
 | 
							flagHTTPErrorDocument,
 | 
				
			||||||
		flagHTTPDirectoryDocument,
 | 
							flagHTTPDirectoryDocument,
 | 
				
			||||||
@ -68,7 +74,17 @@ func main () {
 | 
				
			|||||||
		pluginPath[index], _ = filepath.Abs(pat)
 | 
							pluginPath[index], _ = filepath.Abs(pat)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// log header for telling apart separate program runs
 | 
						// set up logging
 | 
				
			||||||
 | 
						if flagLogDirectory.Value != "" {
 | 
				
			||||||
 | 
							directory := flagLogDirectory.Value
 | 
				
			||||||
 | 
							log.Println("(i) logging to", directory)
 | 
				
			||||||
 | 
							directory, err := filepath.Abs(directory)
 | 
				
			||||||
 | 
							if err != nil { log.Fatalln("XXX", err) }
 | 
				
			||||||
 | 
							logger, err := rotate.New(directory)
 | 
				
			||||||
 | 
							if err != nil { log.Fatalln("XXX", err) }
 | 
				
			||||||
 | 
							defer logger.Close()
 | 
				
			||||||
 | 
							log.SetOutput(logger)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	log.Println(`==========| STEP |===========`)
 | 
						log.Println(`==========| STEP |===========`)
 | 
				
			||||||
	log.Println(`Scriptable Template Processor`)
 | 
						log.Println(`Scriptable Template Processor`)
 | 
				
			||||||
	log.Println(`... initializing`)
 | 
						log.Println(`... initializing`)
 | 
				
			||||||
 | 
				
			|||||||
@ -34,10 +34,12 @@ func (this *Document) Execute (output io.Writer, data ExecutionData) error {
 | 
				
			|||||||
	// TODO catch template errors here and offset their row number by the
 | 
						// TODO catch template errors here and offset their row number by the
 | 
				
			||||||
	// number of rows taken up by the front matter
 | 
						// number of rows taken up by the front matter
 | 
				
			||||||
	err := this.template.Execute(&outputBuilder, data)
 | 
						err := this.template.Execute(&outputBuilder, data)
 | 
				
			||||||
 | 
						// ignore ErrExecutionCanceled, because it's meant to gracefully stop
 | 
				
			||||||
 | 
						// the template execution
 | 
				
			||||||
	if err != nil { return err }
 | 
						if err != nil { return err }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// execute parent with this document's result
 | 
						// execute parent with this document's result
 | 
				
			||||||
	parent, err := this.environment.ParseRelative(this.Extends, this)
 | 
						parent, err := this.environment.LoadRelative(this.Extends, this)
 | 
				
			||||||
	if err != nil { return err }
 | 
						if err != nil { return err }
 | 
				
			||||||
	return parent.Execute(output, ExecutionData {
 | 
						return parent.Execute(output, ExecutionData {
 | 
				
			||||||
		Data:  data.Data,
 | 
							Data:  data.Data,
 | 
				
			||||||
 | 
				
			|||||||
@ -57,17 +57,17 @@ func (this *Environment) Init (ctx context.Context) error {
 | 
				
			|||||||
	return ctx.Err()
 | 
						return ctx.Err()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Parse parses the named document and returns it. The name is treated as a file
 | 
					// Load loads the named document and returns it. The name is treated as a file
 | 
				
			||||||
// path relative to the current working directory. Documents are cached into the
 | 
					// path relative to the current working directory. Documents are cached into the
 | 
				
			||||||
// environment once parsed, and are returned on subsequent calls that have the
 | 
					// environment once loaded, and are returned on subsequent calls that have the
 | 
				
			||||||
// same name. 
 | 
					// same name. 
 | 
				
			||||||
func (this *Environment) Parse (name string) (*Document, error) {
 | 
					func (this *Environment) Load (name string) (*Document, error) {
 | 
				
			||||||
	return this.ParseRelative(name, nil)
 | 
						return this.LoadRelative(name, nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParseRelative is like Parse, but treats the name as a path relative to the
 | 
					// LoadRelative is like Load, but treats the name as a path relative to the
 | 
				
			||||||
// given document.
 | 
					// given document.
 | 
				
			||||||
func (this *Environment) ParseRelative (name string, document *Document) (*Document, error) {
 | 
					func (this *Environment) LoadRelative (name string, document *Document) (*Document, error) {
 | 
				
			||||||
	if document == nil {
 | 
						if document == nil {
 | 
				
			||||||
		name = filepath.Clean(name)
 | 
							name = filepath.Clean(name)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -86,14 +86,14 @@ func (this *Environment) ParseRelative (name string, document *Document) (*Docum
 | 
				
			|||||||
	defer input.Close()
 | 
						defer input.Close()
 | 
				
			||||||
	info, err := input.Stat()
 | 
						info, err := input.Stat()
 | 
				
			||||||
	if err != nil { return nil, err }
 | 
						if err != nil { return nil, err }
 | 
				
			||||||
	return this.parse(name, info.ModTime(), input)
 | 
						return this.load(name, info.ModTime(), input)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParseReader is like Parse, but parses a reader and just takes your word for
 | 
					// Parse is like Load, but parses a reader and just takes your word for it that
 | 
				
			||||||
// it that it corresponds to the file of the given name. It always re-parses.
 | 
					// it corresponds to the file of the given name. It always re-parses.
 | 
				
			||||||
func (this *Environment) ParseReader (name string, input io.Reader) (*Document, error) {
 | 
					func (this *Environment) Parse (name string, input io.Reader) (*Document, error) {
 | 
				
			||||||
	name = filepath.Clean(name)
 | 
						name = filepath.Clean(name)
 | 
				
			||||||
	return this.parse(name, time.Now(), input)
 | 
						return this.load(name, time.Now(), input)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Unload removes a named document. It will be reloaded if necessary.
 | 
					// Unload removes a named document. It will be reloaded if necessary.
 | 
				
			||||||
@ -103,7 +103,7 @@ func (this *Environment) Unload (name string) {
 | 
				
			|||||||
	delete(documents, name)
 | 
						delete(documents, name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *Environment) parse (name string, modTime time.Time, input io.Reader) (*Document, error) {
 | 
					func (this *Environment) load (name string, modTime time.Time, input io.Reader) (*Document, error) {
 | 
				
			||||||
	documents, done := this.documents.Borrow()
 | 
						documents, done := this.documents.Borrow()
 | 
				
			||||||
	defer done()
 | 
						defer done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								error.go
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								error.go
									
									
									
									
									
								
							@ -3,6 +3,7 @@ package step
 | 
				
			|||||||
// Error enumerates errors common to this package.
 | 
					// Error enumerates errors common to this package.
 | 
				
			||||||
type Error string; const (
 | 
					type Error string; const (
 | 
				
			||||||
	ErrCircularInheritance  Error = "circular inheritance"
 | 
						ErrCircularInheritance  Error = "circular inheritance"
 | 
				
			||||||
 | 
						ErrExecutionCanceled    Error = "execution canceled"
 | 
				
			||||||
	ErrMetaMalformed        Error = "metadata is malformed"
 | 
						ErrMetaMalformed        Error = "metadata is malformed"
 | 
				
			||||||
	ErrMetaNeverClosed      Error = "metadata is never closed"
 | 
						ErrMetaNeverClosed      Error = "metadata is never closed"
 | 
				
			||||||
	ErrTypeMismatch         Error = "type mismatch"
 | 
						ErrTypeMismatch         Error = "type mismatch"
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ import "log"
 | 
				
			|||||||
import "fmt"
 | 
					import "fmt"
 | 
				
			||||||
import "path"
 | 
					import "path"
 | 
				
			||||||
import "io/fs"
 | 
					import "io/fs"
 | 
				
			||||||
 | 
					import "errors"
 | 
				
			||||||
import "strings"
 | 
					import "strings"
 | 
				
			||||||
import "strconv"
 | 
					import "strconv"
 | 
				
			||||||
import "net/http"
 | 
					import "net/http"
 | 
				
			||||||
@ -11,11 +12,6 @@ import "path/filepath"
 | 
				
			|||||||
import "git.tebibyte.media/sashakoshka/step"
 | 
					import "git.tebibyte.media/sashakoshka/step"
 | 
				
			||||||
import "git.tebibyte.media/sashakoshka/goutil/container"
 | 
					import "git.tebibyte.media/sashakoshka/goutil/container"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ErrorData struct {
 | 
					 | 
				
			||||||
	Status  int
 | 
					 | 
				
			||||||
	Message any
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type DirectoryData struct {
 | 
					type DirectoryData struct {
 | 
				
			||||||
	Name    string
 | 
						Name    string
 | 
				
			||||||
	Entries []fs.DirEntry
 | 
						Entries []fs.DirEntry
 | 
				
			||||||
@ -120,7 +116,7 @@ func (this *Handler) serveDirectory (
 | 
				
			|||||||
		this.serveFile(res, req, pat)
 | 
							this.serveFile(res, req, pat)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	document, err := this.Environment.Parse(this.DirectoryDocument)
 | 
						document, err := this.Environment.Load(this.DirectoryDocument)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
							this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@ -143,7 +139,7 @@ func (this *Handler) serveDocument (
 | 
				
			|||||||
	name string,
 | 
						name string,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
	// parse
 | 
						// parse
 | 
				
			||||||
	document, err := this.Environment.Parse(name)
 | 
						document, err := this.Environment.Load(name)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
							this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@ -177,8 +173,17 @@ func (this *Handler) serveDocument (
 | 
				
			|||||||
	err = document.Execute(&recorder, step.ExecutionData {
 | 
						err = document.Execute(&recorder, step.ExecutionData {
 | 
				
			||||||
		Data: data,
 | 
							Data: data,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						if errors.Is(err, step.ErrExecutionCanceled) { err = nil }
 | 
				
			||||||
 | 
						var httpError Error
 | 
				
			||||||
 | 
						if errors.As(err, &httpError) {
 | 
				
			||||||
 | 
							this.serveError (
 | 
				
			||||||
 | 
								res, req,
 | 
				
			||||||
 | 
								httpError.Status, httpError.Message, false)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.serveError(res, req, http.StatusInternalServerError, err, false)
 | 
							this.serveError (
 | 
				
			||||||
 | 
								res, req,
 | 
				
			||||||
 | 
								http.StatusInternalServerError, err, false)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -209,13 +214,13 @@ func (this *Handler) serveError (
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	document, err := this.Environment.Parse(this.ErrorDocument)
 | 
						document, err := this.Environment.Load(this.ErrorDocument)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.serveError(res, req, http.StatusInternalServerError, err, true)
 | 
							this.serveError(res, req, http.StatusInternalServerError, err, true)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = document.Execute(res, step.ExecutionData {
 | 
						err = document.Execute(res, step.ExecutionData {
 | 
				
			||||||
		Data: ErrorData {
 | 
							Data: Error {
 | 
				
			||||||
			Status:  status,
 | 
								Status:  status,
 | 
				
			||||||
			Message: message,
 | 
								Message: message,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								http/http.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								http/http.go
									
									
									
									
									
								
							@ -1,9 +1,27 @@
 | 
				
			|||||||
package http
 | 
					package http
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "io"
 | 
					import "io"
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
import "bytes"
 | 
					import "bytes"
 | 
				
			||||||
import "net/http"
 | 
					import "net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Error represents an HTTP error. It is passed to error documents as data.
 | 
				
			||||||
 | 
					// If returned from a template, the server will show the appropriate error page.
 | 
				
			||||||
 | 
					type Error struct {
 | 
				
			||||||
 | 
						Status  int
 | 
				
			||||||
 | 
						Message any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err Error) Error () string {
 | 
				
			||||||
 | 
						message := fmt.Sprint(err.Message)
 | 
				
			||||||
 | 
						text    := http.StatusText(err.Status)
 | 
				
			||||||
 | 
						if message == "" {
 | 
				
			||||||
 | 
							return fmt.Sprintf("%d: %s", err.Status, text)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return fmt.Sprintf("%d: %s: %s", err.Status, text, message)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HTTPData represents information about an ongoing HTTP request that is made
 | 
					// HTTPData represents information about an ongoing HTTP request that is made
 | 
				
			||||||
// available to templates as they are being executed.
 | 
					// available to templates as they are being executed.
 | 
				
			||||||
type HTTPData struct {
 | 
					type HTTPData struct {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,10 @@
 | 
				
			|||||||
package http
 | 
					package http
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "net/http"
 | 
					 | 
				
			||||||
import "net/url"
 | 
					import "net/url"
 | 
				
			||||||
 | 
					import "net/http"
 | 
				
			||||||
import "html/template"
 | 
					import "html/template"
 | 
				
			||||||
import "git.tebibyte.media/sashakoshka/step"
 | 
					import "git.tebibyte.media/sashakoshka/step"
 | 
				
			||||||
 | 
					import shttp "git.tebibyte.media/sashakoshka/step/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _ step.FuncProvider = new(Provider)
 | 
					var _ step.FuncProvider = new(Provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,6 +24,8 @@ func (this *Provider) FuncMap () template.FuncMap {
 | 
				
			|||||||
		"statusText": http.StatusText,
 | 
							"statusText": http.StatusText,
 | 
				
			||||||
		"parseQuery": funcParseQuery,
 | 
							"parseQuery": funcParseQuery,
 | 
				
			||||||
		"parseForm":  funcParseForm,
 | 
							"parseForm":  funcParseForm,
 | 
				
			||||||
 | 
							"error":      funcError,
 | 
				
			||||||
 | 
							"redirect":   funcRedirect,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,8 +38,22 @@ func funcParseQuery (query string) url.Values {
 | 
				
			|||||||
	return values
 | 
						return values
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func funcError (status int, message any) (string, error) {
 | 
				
			||||||
 | 
						return "", shttp.Error {
 | 
				
			||||||
 | 
							Status:  status,
 | 
				
			||||||
 | 
							Message: message,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func funcRedirect (res shttp.WrappedResponseWriter, status int, pat string) (string, error) {
 | 
				
			||||||
 | 
						// TODO remove parameters
 | 
				
			||||||
 | 
						res.Header.Add("Location", pat)
 | 
				
			||||||
 | 
						res.WriteHeader(status)
 | 
				
			||||||
 | 
						return "", step.ErrExecutionCanceled
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func funcParseForm (req *http.Request) url.Values {
 | 
					func funcParseForm (req *http.Request) url.Values {
 | 
				
			||||||
 | 
						// FIXME there is already a parse form method lol this can be removed
 | 
				
			||||||
	err := req.ParseForm()
 | 
						err := req.ParseForm()
 | 
				
			||||||
	if err != nil { return nil }
 | 
						if err != nil { return nil }
 | 
				
			||||||
	return req.Form
 | 
						return req.Form
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,9 @@ func (this *Provider) FuncMapFor (document *step.Document) template.FuncMap {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return template.FuncMap {
 | 
						return template.FuncMap {
 | 
				
			||||||
		"panic":       stat.funcPanic,
 | 
							"panic":       stat.funcPanic,
 | 
				
			||||||
 | 
							"cancel":      stat.funcCancel,
 | 
				
			||||||
 | 
							"create":      stat.funcCreate,
 | 
				
			||||||
 | 
							"createHTML":  stat.funcCreateHTML,
 | 
				
			||||||
		"execute":     stat.funcExecute,
 | 
							"execute":     stat.funcExecute,
 | 
				
			||||||
		"include":     stat.funcInclude,
 | 
							"include":     stat.funcInclude,
 | 
				
			||||||
		"includeHTML": stat.funcIncludeHTML,
 | 
							"includeHTML": stat.funcIncludeHTML,
 | 
				
			||||||
@ -43,10 +46,23 @@ func (this *state) funcPanic (message any) (string, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *state) funcCancel () (string, error) {
 | 
				
			||||||
 | 
						return "", step.ErrExecutionCanceled
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *state) funcCreate (name string, arguments ...any) (string, error) {
 | 
				
			||||||
 | 
						return this.funcInclude(name, arguments)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *state) funcCreateHTML (name string, arguments ...any) (template.HTML, error) {
 | 
				
			||||||
 | 
						return this.funcIncludeHTML(name, arguments)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *state) funcExecute (name string, data any) (step.ExecutionResult, error) {
 | 
					func (this *state) funcExecute (name string, data any) (step.ExecutionResult, error) {
 | 
				
			||||||
	name, err := this.document.Rel(name)
 | 
						name, err := this.document.Rel(name)
 | 
				
			||||||
	if err != nil { return step.ExecutionResult { }, err }
 | 
						if err != nil { return step.ExecutionResult { }, err }
 | 
				
			||||||
	document, err := this.document.Environment().Parse(name)
 | 
						document, err := this.document.Environment().LoadRelative (
 | 
				
			||||||
 | 
							name, this.document)
 | 
				
			||||||
	if err != nil { return step.ExecutionResult { }, err }
 | 
						if err != nil { return step.ExecutionResult { }, err }
 | 
				
			||||||
	builder := strings.Builder { }
 | 
						builder := strings.Builder { }
 | 
				
			||||||
	err = document.Execute(&builder, step.ExecutionData { Data: data })
 | 
						err = document.Execute(&builder, step.ExecutionData { Data: data })
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user