diff --git a/document.go b/document.go index f70ed96..31225b1 100644 --- a/document.go +++ b/document.go @@ -3,6 +3,7 @@ package step import "io" import "time" import "strings" +import "path/filepath" import "html/template" // Document represents a STEP file. @@ -54,6 +55,26 @@ func (this *Document) Environment () *Environment { return this.environment } +// Abs returns an absolute representation of the given path. If the path is an +// absolute path already, it is returned as-is. If the path is a relative path, +// it is treated as relative to the current working directory. If the path is an +// absolute path beginning with "." or "..", it is treated as relative to this +// document. The result is cleaned. +func (this *Document) Abs (name string) (string, error) { + if filepath.IsAbs(name) { + return filepath.Clean(name), nil + } + if strings.HasPrefix(name, ".") { + directory := this.name + ext := filepath.Ext(directory) + if ext != "" { + directory = filepath.Dir(directory) + } + return filepath.Abs(filepath.Join(directory, name)) + } + return filepath.Abs(name) +} + // ExecutionData is data made available to documents as they are being exeucted. type ExecutionData struct { Data any // Custom data diff --git a/document_test.go b/document_test.go new file mode 100644 index 0000000..e5fc025 --- /dev/null +++ b/document_test.go @@ -0,0 +1,33 @@ +package step + +import "os" +import "testing" +import "path/filepath" + +func TestDocumentAbs (test *testing.T) { + document := Document { + name: "foo/bar.step", + } + cwd, err := os.Getwd() + if err != nil { test.Fatal(err) } + path1, err := document.Abs("thing.step") + if err != nil { test.Fatal(err) } + path2, err := document.Abs("thing/other.step") + if err != nil { test.Fatal(err) } + path3, err := document.Abs("./thing/other.step") + if err != nil { test.Fatal(err) } + path4, err := document.Abs("../thing/other.step") + if err != nil { test.Fatal(err) } + path5, err := document.Abs("/something/thing") + if err != nil { test.Fatal(err) } + test.Log(path1) + if path1 != filepath.Join(cwd, "thing.step") { test.Fatal("incorrect path") } + test.Log(path2) + if path2 != filepath.Join(cwd, "thing/other.step") { test.Fatal("incorrect path") } + test.Log(path3) + if path3 != filepath.Join(cwd, "foo/thing/other.step") { test.Fatal("incorrect path") } + test.Log(path4) + if path4 != filepath.Join(cwd, "thing/other.step") { test.Fatal("incorrect path") } + test.Log(path5) + if path5 != "/something/thing" { test.Fatal("incorrect path") } +}