pkg/path: fix problems with path->pkg
and case or nonexistent
The `path->pkg` funciton shouldn't return the name of a package that isn't installed, including a case-folded version of a package that is installed. On Windows, where we match case-normalized paths, we have to work a little harder to map a case-normalized path element to the installed package name, given that package names are case-sensitive. Closes PR 14861
This commit is contained in:
parent
195a46a23e
commit
885d2125b9
|
@ -80,13 +80,12 @@
|
|||
(raise-argument-error who "(or/c #f (and/c hash? (not/c immutable?)))" cache))
|
||||
(define (explode p)
|
||||
(explode-path
|
||||
(normal-case-path
|
||||
(simplify-path (path->complete-path p)))))
|
||||
(simplify-path (path->complete-path p))))
|
||||
(define (sub-path? < p d)
|
||||
(and ((length d) . < . (length p))
|
||||
(for/and ([de (in-list d)]
|
||||
[pe (in-list p)])
|
||||
(equal? de pe))))
|
||||
(equal? (normal-case-path de) (normal-case-path pe)))))
|
||||
(define p (explode given-p))
|
||||
(define (build-path* l)
|
||||
(if (null? l) 'same (apply build-path l)))
|
||||
|
@ -105,6 +104,15 @@
|
|||
(let ([db (read-pkgs-db scope)])
|
||||
(when cache (hash-set! cache `(db ,scope) db))
|
||||
db)))
|
||||
(define (normal-case-mapping/cached db)
|
||||
(if (eq? 'windows (system-path-convention-type))
|
||||
(or (and cache
|
||||
(hash-ref cache `(normal-case ,scope) #f))
|
||||
(let ([ht (for/hash ([n (in-hash-keys db)])
|
||||
(values (normal-case-path n) n))])
|
||||
(when cache (hash-set! cache `(normal-case ,scope) ht))
|
||||
ht))
|
||||
#hash()))
|
||||
(cond
|
||||
[(sub-path? < p d)
|
||||
;; Under the installation mode's package directory.
|
||||
|
@ -116,14 +124,26 @@
|
|||
(if (or (regexp-match? #rx"pkgs[.]rktd" pkg-name)
|
||||
(regexp-match? #rx"[.]trash" pkg-name))
|
||||
(values #f #f #f #f) ; don't count the database or trash can as a package
|
||||
(values (if (regexp-match? #rx"[+]" pkg-name) ; +<n> used as an alternate path, sometimes
|
||||
(regexp-replace #rx"[+].*$" pkg-name "")
|
||||
pkg-name)
|
||||
(build-path* (list-tail p (add1 len)))
|
||||
(and want-collect?
|
||||
(let ([i (hash-ref (read-pkg-db/cached) pkg-name #f)])
|
||||
(and i (sc-pkg-info? i) (sc-pkg-info-collect i))))
|
||||
scope))]
|
||||
(let* ([pkg-name
|
||||
(if (regexp-match? #rx"[+]" pkg-name) ; +<n> used as an alternate path, sometimes
|
||||
(regexp-replace #rx"[+].*$" pkg-name "")
|
||||
pkg-name)]
|
||||
[db (read-pkg-db/cached)]
|
||||
;; Double-check that such a package is installed, in case
|
||||
;; there's a junk directory or the path case is wrong:
|
||||
[pkg-name (if (hash-ref db pkg-name #f)
|
||||
pkg-name
|
||||
(hash-ref (normal-case-mapping/cached db)
|
||||
(normal-case-path pkg-name)
|
||||
#f))])
|
||||
(if pkg-name
|
||||
(values pkg-name
|
||||
(build-path* (list-tail p (add1 len)))
|
||||
(and want-collect?
|
||||
(let ([i (hash-ref (read-pkg-db/cached) pkg-name #f)])
|
||||
(and i (sc-pkg-info? i) (sc-pkg-info-collect i))))
|
||||
scope)
|
||||
(values #f #f #f #f))))]
|
||||
[else
|
||||
;; Maybe it's a linked package
|
||||
(define pkgs-dir (get-pkgs-dir scope))
|
||||
|
|
Loading…
Reference in New Issue
Block a user