Skip to content

Commit efc60b7

Browse files
committed
fix: defer to os.Open for windows
See: golang/go#44279
1 parent f5efa42 commit efc60b7

File tree

2 files changed

+109
-14
lines changed

2 files changed

+109
-14
lines changed

merge.go

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,38 @@ func MergeDir(dir string, conditions Conditions, opts *MergeDirOptions) ([]*File
187187
if opts.AcceptFile == nil {
188188
opts.AcceptFile = DefaultFileAcceptor
189189
}
190-
if opts.FS == nil {
191-
opts.FS = os.DirFS(dir)
192-
dir = "."
193-
}
190+
// fmt.Printf("BEFORE: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
191+
// if runtime.GOOS == "windows" {
192+
// // Go running on windows does not support os.DirFS properly
193+
// // See: https://github.com/golang/go/issues/44279
194+
// fmt.Println(" windows") //nolint:forbidigo
195+
// opts.FS = &osFilesystem{}
196+
// dir = filepath.Join(filepath.VolumeName(dir), dir)
197+
// fmt.Printf("MIDDLE2: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
198+
// }
199+
// if opts.FS == nil {
200+
// fmt.Println("opts.FS == nil") //nolint:forbidigo
201+
// opts.FS = os.DirFS(dir)
202+
// fmt.Printf("MIDDLE1: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
203+
// } else {
204+
// var err error
205+
// fmt.Printf("MIDDLE2A: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
206+
// opts.FS, err = fs.Sub(opts.FS, dir)
207+
// if err != nil {
208+
// return nil, fmt.Errorf("fs.Sub of %v and %v failed: %w", opts.FS, dir, err)
209+
// }
210+
// // if runtime.GOOS == "windows" {
211+
// // dir = ""
212+
// // } else {
213+
// // dir = "."
214+
// // }
215+
// fmt.Printf("MIDDLE2B: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
216+
// }
217+
// fmt.Printf("AFTER: dir=%v opts.FS=%#v\n", dir, opts.FS) //nolint:forbidigo
218+
219+
// dir + sub: "C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\TestMergeDir_SubFS959700692\\001\\a\\b\\c"
220+
// BEFORE: dir="a\\b\\c" opts.FS="C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\TestMergeDir_SubFS959700692\\001"
221+
// AFTER: dir="a\\b\\c" opts.FS="C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\TestMergeDir_SubFS959700692\\001"
194222

195223
sorted := &outFile{}
196224
var setup sync.Once
@@ -278,15 +306,39 @@ func MergeDir(dir string, conditions Conditions, opts *MergeDirOptions) ([]*File
278306
return convertToFiles(sorted, conditions)
279307
}
280308

309+
// osFilesystem is an io/fs.FS which defers to the os package for opening files
310+
// See: https://github.com/golang/go/issues/44279
311+
type osFilesystem struct{}
312+
313+
func (*osFilesystem) Open(name string) (fs.File, error) {
314+
fmt.Printf("osFilesystem.Open(%v)\n", name) //nolint:forbidigo
315+
return os.Open(name)
316+
}
317+
318+
var _ fs.FS = new(osFilesystem)
319+
281320
func walkDir(fsys fs.FS, dir string, discoveredPaths chan string) error {
282-
reader, ok := fsys.(fs.ReadDirFS)
283-
if !ok {
284-
return fmt.Errorf("unexpected %T wanted fs.ReadDirFS", fsys)
285-
}
321+
fmt.Printf("walkDir: dir=%v fsys=%#v\n", dir, fsys) //nolint:forbidigo
286322

287-
items, err := reader.ReadDir(dir)
323+
var items []fs.DirEntry
324+
var err error
325+
326+
if fsys != nil {
327+
fmt.Printf("walkDir: A\n") //nolint:forbidigo
328+
if rr, ok := fsys.(fs.ReadDirFS); ok {
329+
fmt.Printf("walkDir: B\n") //nolint:forbidigo
330+
items, err = rr.ReadDir(dir)
331+
}
332+
}
333+
if err != nil {
334+
return fmt.Errorf("fs.readdir %s failed: %w", dir, err)
335+
}
336+
if len(items) == 0 {
337+
fmt.Printf("walkDir: C\n") //nolint:forbidigo
338+
items, err = os.ReadDir(dir)
339+
}
288340
if err != nil {
289-
return fmt.Errorf("listing %s failed: %w", dir, err)
341+
return fmt.Errorf("os.readdir %s failed: %w", dir, err)
290342
}
291343

292344
for i := range items {
@@ -356,7 +408,14 @@ func readValidateOptsFromFile(path string, opts *MergeDirOptions) *ValidateOpts
356408
if opts.ValidateOptsExtension != "" {
357409
where := strings.TrimSuffix(path, filepath.Ext(path)) + opts.ValidateOptsExtension
358410

359-
fd, err := opts.FS.Open(where)
411+
var fd fs.File
412+
var err error
413+
414+
if opts.FS != nil {
415+
fd, err = opts.FS.Open(where)
416+
} else {
417+
fd, err = os.Open(where)
418+
}
360419
if err != nil {
361420
return nil
362421
}
@@ -369,12 +428,18 @@ func readValidateOptsFromFile(path string, opts *MergeDirOptions) *ValidateOpts
369428
return nil
370429
}
371430

372-
func readFile(fs fs.FS, path string, as FileAcceptance, validateOpts *ValidateOpts) (*File, error) {
431+
func readFile(fsys fs.FS, path string, as FileAcceptance, validateOpts *ValidateOpts) (*File, error) {
373432
if as == SkipFile {
374433
return nil, nil
375434
}
376435

377-
fd, err := fs.Open(path)
436+
var fd fs.File
437+
var err error
438+
if fsys != nil {
439+
fd, err = fsys.Open(path)
440+
} else {
441+
fd, err = os.Open(path)
442+
}
378443
if err != nil {
379444
return nil, fmt.Errorf("opening %s failed: %w", path, err)
380445
}

merge_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,30 @@ func TestMergeDir__DefaultFileAcceptor(t *testing.T) {
585585
require.Equal(t, SkipFile, output)
586586
}
587587

588-
func TestMergeDir_SubFS(t *testing.T) {
588+
func TestMergeDir(t *testing.T) {
589+
dir := t.TempDir()
590+
591+
src, err := os.Open(filepath.Join("test", "testdata", "ppd-debit.ach"))
592+
require.NoError(t, err)
593+
t.Cleanup(func() { src.Close() })
594+
595+
dst, err := os.Create(filepath.Join(dir, "input.ach"))
596+
require.NoError(t, err)
597+
598+
_, err = io.Copy(dst, src)
599+
require.NoError(t, err)
600+
require.NoError(t, dst.Close())
601+
602+
var conditions Conditions
603+
merged, err := MergeDir(dir, conditions, nil)
604+
require.NoError(t, err)
605+
require.Len(t, merged, 1)
606+
}
607+
608+
func TestMergeDir_WithFS(t *testing.T) {
589609
dir := t.TempDir()
590610
sub := filepath.Join("a", "b", "c")
611+
fmt.Printf("dir + sub: %v\n", filepath.Join(dir, sub)) //nolint:forbidigo
591612
require.NoError(t, os.MkdirAll(filepath.Join(dir, sub), 0777))
592613

593614
src, err := os.Open(filepath.Join("test", "testdata", "ppd-debit.ach"))
@@ -602,11 +623,20 @@ func TestMergeDir_SubFS(t *testing.T) {
602623
require.NoError(t, dst.Close())
603624

604625
var conditions Conditions
626+
627+
// partial dir + sub
605628
merged, err := MergeDir(sub, conditions, &MergeDirOptions{
606629
FS: os.DirFS(dir),
607630
})
608631
require.NoError(t, err)
609632
require.Len(t, merged, 1)
633+
634+
// full dir
635+
merged, err = MergeDir(".", conditions, &MergeDirOptions{
636+
FS: os.DirFS(filepath.Join(dir, sub)),
637+
})
638+
require.NoError(t, err)
639+
require.Len(t, merged, 1)
610640
}
611641

612642
func TestMergeDirHelpers(t *testing.T) {

0 commit comments

Comments
 (0)