diff --git a/document.go b/document.go index 31225b1..92c1cca 100644 --- a/document.go +++ b/document.go @@ -1,5 +1,6 @@ package step +import "os" import "io" import "time" import "strings" @@ -57,24 +58,46 @@ func (this *Document) Environment () *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 +// it is treated as relative to the current working directory. If the path is a +// relative 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) - } + directory := this.dir() return filepath.Abs(filepath.Join(directory, name)) } return filepath.Abs(name) } +// Rel returns the given path relative to the current working directory. As a +// special case, any relative path beginning with "." or ".." is treated as +// being relative to this document before it is made relative to the current +// working directory. The result is cleaned. +func (this *Document) Rel (name string) (string, error) { + if filepath.IsAbs(name) { + cwd, err := os.Getwd() + if err != nil { return "", err } + return filepath.Rel(cwd, name) + } + if strings.HasPrefix(name, ".") { + directory := this.dir() + return filepath.Join(directory, name), nil + } + return name, nil +} + +func (this *Document) dir () string { + directory := this.name + ext := filepath.Ext(directory) + if ext != "" { + directory = filepath.Dir(directory) + } + return directory +} + // 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 index e5fc025..4abcf6f 100644 --- a/document_test.go +++ b/document_test.go @@ -31,3 +31,29 @@ func TestDocumentAbs (test *testing.T) { test.Log(path5) if path5 != "/something/thing" { test.Fatal("incorrect path") } } + +func TestDocumentRel (test *testing.T) { + document := Document { + name: "foo/bar.step", + } + path1, err := document.Rel("thing.step") + if err != nil { test.Fatal(err) } + path2, err := document.Rel("thing/other.step") + if err != nil { test.Fatal(err) } + path3, err := document.Rel("./thing/other.step") + if err != nil { test.Fatal(err) } + path4, err := document.Rel("../thing/other.step") + if err != nil { test.Fatal(err) } + path5, err := document.Rel("/something/thing") + if err != nil { test.Fatal(err) } + test.Log(path1) + if path1 != filepath.Join("thing.step") { test.Fatal("incorrect path") } + test.Log(path2) + if path2 != filepath.Join("thing/other.step") { test.Fatal("incorrect path") } + test.Log(path3) + if path3 != filepath.Join("foo/thing/other.step") { test.Fatal("incorrect path") } + test.Log(path4) + if path4 != filepath.Join("thing/other.step") { test.Fatal("incorrect path") } + test.Log(path5) + if path5 == "/something/thing" { test.Fatal("incorrect path") } +}