pkg/lib: add pkg-index-update-local' and pkg-index-suggestions-for-module'

Assembles other functions to create and consult a local database of
packages and the modules that the packages implement.
This commit is contained in:
Matthew Flatt 2013-04-22 10:16:24 -06:00
parent ef0491be07
commit 27b7e7dc7e
3 changed files with 103 additions and 1 deletions

View File

@ -1729,6 +1729,68 @@
(when clean?
(delete-directory/files dir))))
(define (pkg-index-update-local #:index-file [index-file (db:current-pkg-index-file)]
#:quiet? [quiet? #f])
(parameterize ([db:current-pkg-index-file index-file])
(define indexes (pkg-config-indexes))
(db:set-indexes! indexes)
(for ([index (in-list indexes)])
(parameterize ([current-pkg-indexes (list (string->url index))])
(define details (get-all-pkg-details-from-indexes))
(db:set-pkgs! index (for/list ([(name ht) (in-hash details)])
(db:pkg name
index
(hash-ref ht 'author "")
(hash-ref ht 'source "")
(hash-ref ht 'checksum "")
(hash-ref ht 'description ""))))
(define need-modules (db:get-pkgs-without-modules #:index index))
(for ([(pkg) (in-list need-modules)])
(define name (db:pkg-name pkg))
(define ht (hash-ref details name))
(define source (hash-ref ht 'source))
(unless quiet?
(printf "Downloading ~s\n" source))
(define-values (checksum modules deps)
(get-pkg-content (pkg-desc source
#f
(hash-ref ht 'checksum #f)
#f)))
(db:set-pkg-modules! name index checksum modules))))))
(define (choose-index-file)
(define default (db:current-pkg-index-file))
(if (file-exists? default)
default
(let ([installation (build-path (find-lib-dir) "pkgs" (file-name-from-path default))])
(if (file-exists? installation)
installation
default))))
(define (pkg-index-suggestions-for-module module-path
#:index-file [index-file (choose-index-file)])
(if (file-exists? index-file)
(parameterize ([db:current-pkg-index-file index-file])
(let* ([mod (collapse-module-path
module-path
(lambda () (build-path (current-directory) "dummy.rkt")))]
[pkgs (db:get-module-pkgs mod)]
[more-pkgs (let ([rx:reader #rx"/lang/reader[.]rkt$"])
(if (and (pair? mod)
(eq? (car mod) 'lib)
(regexp-match rx:reader (cadr mod)))
(db:get-module-pkgs `(lib ,(regexp-replace rx:reader (cadr mod) "/main.rkt")))
null))])
(sort (set->list
(list->set
(map db:pkg-name (append pkgs more-pkgs))))
string<?)))
null))
(define dep-behavior/c
(or/c #f 'fail 'force 'search-ask 'search-auto))
@ -1820,6 +1882,15 @@
boolean?))]
[pkg-config-indexes
(-> (listof string?))]
[pkg-index-update-local
(->* ()
(#:index-file path-string?
#:quiet? boolean?)
void?)]
[pkg-index-suggestions-for-module
(->* (module-path?)
(#:index-file path-string?)
(listof string?))]
[get-all-pkg-names-from-indexes
(-> (listof string?))]
[get-all-pkg-details-from-indexes

View File

@ -2,6 +2,8 @@
(require racket/contract/base
racket/format
racket/set
racket/path
racket/file
db)
(provide
@ -85,13 +87,18 @@
(make-parameter (build-path
(find-system-path 'addon-dir)
(version)
"pkgs"
"pnr.sqlite")))
(define (call-with-pnr-db proc)
(define db #f)
(dynamic-wind
(lambda ()
(set! db (sqlite3-connect #:database (current-pkg-index-file)
(define file (current-pkg-index-file))
(define dir (path-only file))
(unless (directory-exists? dir)
(make-directory* dir))
(set! db (sqlite3-connect #:database file
#:mode 'create
#:busy-retry-limit +inf.0)))
(lambda () (proc db))

View File

@ -4,6 +4,7 @@
racket/contract/base
pkg
pkg/lib
(only-in pkg/pnr-db current-pkg-index-file)
net/url
syntax/modcollapse
setup/getinfo))
@ -239,6 +240,29 @@ then @racket[names] should be empty.}
Implements the @racket[index-copy] command.}
@defproc[(pkg-index-update-local [#:index-file index-file path-string? (current-pkg-index-file)]
[#:quiet? quiet? boolean? #f])
void?]{
Consults the user's configured @tech{package name resolvers} (like
@racket[pkg-index-copy]) and package servers to populate the database
@racket[index-file] with information about available packages and the
modules that they implement.}
@defproc[(pkg-index-suggestions-for-module
[module-path module-path?]
[#:index-file index-file path-string? ....])
(listof string?)]{
Consults @racket[index-file] and returns a list of available packages
that provide the module specified by @racket[module-path].
The default @racket[index-file] is @racket[(current-pkg-index-file)]
if that file exists, otherwise a file in the racket installation is
tried.}
@defproc[(get-all-pkg-names-from-indexes) (listof string?)]{
Consults @tech{package name resolvers} to obtain a list of available