raco pkg: change --scope-dir
search-path handling
Formerly, `--scope-dir` would include only the specified directory in the search path for already installed packages, etc., which means that it would only work right as a kind of installation scope that is a step beyond "installation" on the "user"-to-"installation" spectrum. The `'pkgs-search-dirs` confiugration entry, meanwhile, provides more control over search ordering in installation scope. Make `--scope-dir` work more consistently with that search-path configration. This change also makes "instllation"-scope operations use the search path more consistently, since some actions used to use the whole search list while others pruned any prefix before the main installation directory in the search list.
This commit is contained in:
parent
292dac4e51
commit
0e2ad7d596
|
@ -398,9 +398,13 @@ all users of the Racket installation.
|
|||
|
||||
A directory path can be used as a @tech{package scope}, in which case
|
||||
package operations affect the set of packages installations in the
|
||||
directory. An installation can be configured to include the
|
||||
directory in its search path for installed packages (see
|
||||
@secref["config-file" #:doc raco-doc]).
|
||||
directory. An installation can be configured to include the directory
|
||||
in its search path for installed packages (see @secref["config-file"
|
||||
#:doc raco-doc]). When a directory path is used as a @tech{package
|
||||
scope}, operations such as dependency checking will use all paths in
|
||||
the configured search path starting with the one that is designed as a
|
||||
@tech{package scope}; if the designated path is not in the configured
|
||||
search path, then the dierctory by itself is used as the search path.
|
||||
|
||||
Conflict checking disallows installation of the same or conflicting
|
||||
package in different scopes, but if such a configuration is forced,
|
||||
|
|
|
@ -78,10 +78,22 @@ directory}:
|
|||
"pkg/scribblings/pkg.scrbl")]{package scope}. It defaults to
|
||||
@filepath{pkgs} in the main shared-file directory.}
|
||||
|
||||
@item{@indexed-racket['pkgs-search-dirs] --- like
|
||||
@racket['lib-search-dirs], but for packages in @exec{installation}
|
||||
@tech[#:doc '(lib "pkg/scribblings/pkg.scrbl")]{package
|
||||
scope}.}
|
||||
@item{@indexed-racket['pkgs-search-dirs] --- similar to
|
||||
@racket['lib-search-dirs], but for packages in roughly
|
||||
@exec{installation} @tech[#:doc '(lib
|
||||
"pkg/scribblings/pkg.scrbl")]{package scope}. More precisely, a
|
||||
@racket[#f] value in the list is replaced with the directory
|
||||
specified by @racket['pkgs-dir], and that point in the search
|
||||
list corresponds to @exec{installation} scope. Paths before or
|
||||
after a @racket[#f] value in the list can be selected as a
|
||||
scopes to start searches at that path's point in the list.
|
||||
Directories listed in @racket['pkgs-search-dirs] typically oblige
|
||||
a corresponding entry in @racket['links-search-files], where
|
||||
the corresponding entry is @filepath{links.rktd} within the
|
||||
directory.
|
||||
|
||||
@history[#:changed "7.0.0.19" @elem{Adapt the package-search path in
|
||||
a general way for a directory scope.}]}
|
||||
|
||||
@item{@indexed-racket['bin-dir] --- a path, string, or byte string for the
|
||||
installation's directory containing executables. It defaults to a
|
||||
|
|
27
pkgs/racket-test/tests/pkg/test-scope-add.rkt
Normal file
27
pkgs/racket-test/tests/pkg/test-scope-add.rkt
Normal file
|
@ -0,0 +1,27 @@
|
|||
#lang racket/base
|
||||
(require racket/cmdline
|
||||
setup/dirs)
|
||||
|
||||
;; This module is meant to be run via "tests-scope.rkt". It adds the
|
||||
;; given paths to the package-search list, and it adds "links.rktd" in
|
||||
;; those paths to the links-search list.
|
||||
|
||||
(command-line
|
||||
#:args
|
||||
path
|
||||
(unless (null? path)
|
||||
(let ([paths path]
|
||||
[file (build-path (find-config-dir) "config.rktd")])
|
||||
(define ht (call-with-input-file* file read))
|
||||
(define new-ht
|
||||
(hash-set (hash-set ht
|
||||
'pkgs-search-dirs
|
||||
(append paths (hash-ref ht 'pkgs-search-dirs '(#f))))
|
||||
'links-search-files
|
||||
(append (for/list ([path (in-list paths)])
|
||||
(path->string (build-path path "links.rktd")))
|
||||
(hash-ref ht 'links-search-files '(#f)))))
|
||||
(call-with-output-file*
|
||||
file
|
||||
#:exists 'truncate/replace
|
||||
(lambda (o) (write new-ht o))))))
|
|
@ -3,7 +3,8 @@
|
|||
"util.rkt"
|
||||
pkg/lib
|
||||
setup/dirs
|
||||
racket/format)
|
||||
racket/format
|
||||
racket/file)
|
||||
|
||||
(this-test-is-run-by-the-main-test)
|
||||
|
||||
|
@ -78,4 +79,22 @@
|
|||
$ "racket -l racket/base -l pkg-test1/number -e '(number)'" =stdout> "2\n"
|
||||
$ "raco pkg remove pkg-test1" =stdout> #rx"Inferred package scope: installation")
|
||||
|
||||
(initialize-catalogs)
|
||||
(define alone-dir (make-temporary-file "alone~a" 'directory))
|
||||
(define in-search-dir (make-temporary-file "in-search~a" 'directory))
|
||||
(shelly-case
|
||||
"directory as a package scope"
|
||||
$ "raco pkg config -i --set catalogs http://localhost:9990 http://localhost:9991"
|
||||
$ "raco pkg install -i pkg-test1"
|
||||
$ "racket -l pkg-test1" =stdout> #rx"main loaded"
|
||||
;; won't find "base" on catalog:
|
||||
$ (~a "raco pkg install --scope-dir "alone-dir" --auto pkg-test2") =exit> 1 =stderr> #rx"cannot find package.*base"
|
||||
$ "racket -l pkg-test2" =exit> 1 =stderr> #rx"collection not found"
|
||||
$ (~a "racket -l tests/pkg/test-scope-add "in-search-dir)
|
||||
;; will install "pkg-test2" without an extra "pkg-test1" or "base":
|
||||
$ (~a "raco pkg install --scope-dir "in-search-dir" --auto pkg-test2")
|
||||
$ "racket -l pkg-test2" =stdout> #rx"pkg-test2/main loaded")
|
||||
(delete-directory/files alone-dir)
|
||||
(delete-directory/files in-search-dir)
|
||||
|
||||
)))
|
||||
|
|
|
@ -37,20 +37,10 @@
|
|||
|
||||
;; read all packages in this scope or wider
|
||||
(define (merge-pkg-dbs [scope (current-pkg-scope)])
|
||||
(define (merge-next-pkg-dbs scope)
|
||||
(parameterize ([current-pkg-scope scope])
|
||||
(merge-pkg-dbs scope)))
|
||||
(if (path? scope)
|
||||
(read-pkg-db)
|
||||
(case scope
|
||||
[(installation)
|
||||
(for*/hash ([dir (in-list (get-pkgs-search-dirs))]
|
||||
[(k v) (read-pkgs-db dir)])
|
||||
(values k v))]
|
||||
[(user)
|
||||
(define db (read-pkgs-db 'user (current-pkg-scope-version)))
|
||||
(for/fold ([ht (merge-next-pkg-dbs 'installation)]) ([(k v) (in-hash db)])
|
||||
(hash-set ht k v))])))
|
||||
(for/fold ([ht #hash()]) ([m-scope (in-list (reverse (get-scope-list scope)))])
|
||||
(define db (read-pkgs-db m-scope (current-pkg-scope-version)))
|
||||
(for/fold ([ht ht]) ([(k v) (in-hash db)])
|
||||
(hash-set ht k v))))
|
||||
|
||||
;; Finds the scope, in which `pkg-name' is installed; returns 'dir,
|
||||
;; 'installation, a path, or #f (where #f means "not installed"). If
|
||||
|
@ -149,19 +139,22 @@
|
|||
(and (path? scope)
|
||||
(build-path scope "links.rktd")))
|
||||
|
||||
(define (get-scope-list)
|
||||
(define (get-scope-list [current-scope (current-pkg-scope)])
|
||||
;; Get a list of scopes suitable for searches with respect to
|
||||
;; the current scope
|
||||
(define current-scope (current-pkg-scope))
|
||||
(if (path? current-scope)
|
||||
(list current-scope)
|
||||
(or
|
||||
;; Exploit the fact that `member` returns a list starting
|
||||
;; with the found element:
|
||||
(member current-scope
|
||||
(append '(user)
|
||||
(let ([main (find-pkgs-dir)])
|
||||
(for/list ([d (get-pkgs-search-dirs)])
|
||||
(if (equal? d main)
|
||||
'installation
|
||||
d)))))))
|
||||
d)))))
|
||||
;; In case the specified scope wasn't in the list,
|
||||
;; then make a search path that has just that scope:
|
||||
(list current-scope)))
|
||||
|
||||
(define (pkg-directory pkg-name #:cache [cache #f])
|
||||
;; Warning: takes locks individually.
|
||||
|
|
Loading…
Reference in New Issue
Block a user