44 "fmt"
55 "os"
66 "path"
7+ "path/filepath"
78 "strconv"
89 "strings"
910
@@ -88,6 +89,7 @@ func permToString(val interface{}) (string, error) {
8889}
8990
9091// UnmarshalYAML sets in some sane defaults when unmarshaling the data from yaml
92+
9193func (u * UploadFile ) UnmarshalYAML (unmarshal func (interface {}) error ) error {
9294 type uploadFile UploadFile
9395 yu := (* uploadFile )(u )
@@ -108,7 +110,7 @@ func (u *UploadFile) UnmarshalYAML(unmarshal func(interface{}) error) error {
108110 }
109111 u .DirPermString = dp
110112
111- return u . resolve ()
113+ return nil
112114}
113115
114116// String returns the file bundle name or if it is empty, the source.
@@ -129,8 +131,8 @@ func isGlob(s string) bool {
129131 return strings .ContainsAny (s , "*%?[]{}" )
130132}
131133
132- // sets the destination and resolves any globs/local paths into u.Sources
133- func (u * UploadFile ) resolve ( ) error {
134+ // ResolveRelativeTo sets the destination and resolves globs/local paths relative to baseDir.
135+ func (u * UploadFile ) ResolveRelativeTo ( baseDir string ) error {
134136 if u .IsURL () {
135137 if u .DestinationFile == "" {
136138 if u .DestinationDir != "" {
@@ -146,27 +148,42 @@ func (u *UploadFile) resolve() error {
146148 return nil
147149 }
148150
151+ u .Base = ""
152+ u .Sources = nil
153+
154+ src := filepath .ToSlash (u .Source )
155+ if src == "" {
156+ return fmt .Errorf ("failed to resolve local path for %s: empty source" , u )
157+ }
158+ if ! path .IsAbs (src ) {
159+ if baseDir != "" {
160+ src = path .Join (baseDir , src )
161+ }
162+ }
163+ src = path .Clean (src )
164+
149165 if isGlob (u .Source ) {
150- return u .glob (u . Source )
166+ return u .glob (src )
151167 }
152168
153- stat , err := os .Stat (u .Source )
169+ fsPath := filepath .FromSlash (src )
170+ stat , err := os .Stat (fsPath )
154171 if err != nil {
155172 return fmt .Errorf ("failed to stat local path for %s: %w" , u , err )
156173 }
157174
158175 if stat .IsDir () {
159- log .Tracef ("source %s is a directory, assuming %s/**/*" , u . Source , u . Source )
160- return u .glob (path .Join (u . Source , "**/*" ))
176+ log .Tracef ("source %s is a directory, assuming %s/**/*" , src , src )
177+ return u .glob (path .Join (src , "**/*" ))
161178 }
162179
163180 perm := u .PermString
164181 if perm == "" {
165182 perm = fmt .Sprintf ("%o" , stat .Mode ())
166183 }
167- u .Base = path .Dir (u . Source )
184+ u .Base = path .Dir (src )
168185 u .Sources = []* LocalFile {
169- {Path : path .Base (u . Source ), PermMode : perm },
186+ {Path : path .Base (src ), PermMode : perm },
170187 }
171188
172189 return nil
@@ -176,7 +193,7 @@ func (u *UploadFile) resolve() error {
176193func (u * UploadFile ) glob (src string ) error {
177194 base , pattern := doublestar .SplitPattern (src )
178195 u .Base = base
179- fsys := os .DirFS (base )
196+ fsys := os .DirFS (filepath . FromSlash ( base ) )
180197 sources , err := doublestar .Glob (fsys , pattern )
181198 if err != nil {
182199 return err
@@ -185,7 +202,7 @@ func (u *UploadFile) glob(src string) error {
185202 for _ , s := range sources {
186203 abs := path .Join (base , s )
187204 log .Tracef ("glob %s found: %s" , abs , s )
188- stat , err := os .Stat (abs )
205+ stat , err := os .Stat (filepath . FromSlash ( abs ) )
189206 if err != nil {
190207 return fmt .Errorf ("failed to stat file %s: %w" , u , err )
191208 }
0 commit comments