40 lines
1.3 KiB
Racket
40 lines
1.3 KiB
Racket
#lang racket/base
|
|
|
|
(require racket/list
|
|
racket/path
|
|
"util.rkt")
|
|
|
|
(provide find-flac-files
|
|
find-regular-files)
|
|
|
|
(define (directory-list/quiet dir)
|
|
(with-handlers ([exn:fail? (lambda (_) '())])
|
|
(directory-list dir #:build? #t)))
|
|
|
|
(define (directory-exists?/quiet p)
|
|
(with-handlers ([exn:fail? (lambda (_) #f)])
|
|
(directory-exists? p)))
|
|
|
|
(define (file-exists?/quiet p)
|
|
(with-handlers ([exn:fail? (lambda (_) #f)])
|
|
(file-exists? p)))
|
|
|
|
(define (sort-paths paths)
|
|
(sort paths string<? #:key path->string))
|
|
|
|
(define (find-regular-files base-dir)
|
|
;; Do not use racket/file:find-files here. On Windows UNC trees, especially
|
|
;; with long paths, fold-files can raise "path disappeared" for a single
|
|
;; entry and abort the whole scan. This walker treats entries that disappear,
|
|
;; are inaccessible, or cannot be represented by the platform path layer as a
|
|
;; skipped entry and continues the scan.
|
|
(define root (filesystem-path base-dir))
|
|
(let loop ([dir root] [acc '()])
|
|
(for/fold ([acc acc]) ([p (in-list (sort-paths (directory-list/quiet dir)))])
|
|
(cond [(directory-exists?/quiet p) (loop p acc)]
|
|
[(file-exists?/quiet p) (cons p acc)]
|
|
[else acc]))))
|
|
|
|
(define (find-flac-files base-dir)
|
|
(sort-paths (filter flac-path? (find-regular-files base-dir))))
|