diff --git a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl index 66450cb5fd..b1bb5b0a4c 100644 --- a/pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -544,8 +544,8 @@ sub-commands. @item{@Flag{u} or @DFlag{user} --- Shorthand for @exec{--scope user}.} @item{@DFlag{scope-dir} @nonterm{dir} --- Select @nonterm{dir} as the @tech{package scope}.} - @item{@DFlag{catalog} @nonterm{catalog} --- Uses @nonterm{catalog} instead of of the currently configured - @tech{package catalogs}.} + @item{@DFlag{catalog} @nonterm{catalog} --- Uses @nonterm{catalog}s instead of of the currently configured + @tech{package catalogs}. This flag can be provided multiple times. The catalogs are tried in the order provided.} @item{@DFlag{skip-installed} --- Ignores any @nonterm{pkg-source} whose name corresponds to an already-installed package, except for promoting @seclink["concept:auto"]{auto-installed} @@ -642,7 +642,8 @@ sub-commands. #:changed "6.1.1.8" @elem{Added the @DFlag{pull} flag.} #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.} - #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.}]} + #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.} + #:changed "7.6.0.14" @elem{Allowed multiple @DFlag{catalog} flags.}]} @subcommand{@command/toc{update} @nonterm{option} ... @nonterm{pkg-source} ... @@ -774,7 +775,8 @@ the given @nonterm{pkg-source}s. #:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} #:changed "6.90.0.27" @elem{Added the @DFlag{unclone} flag.} #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.} - #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.}]} + #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.} + #:changed "7.6.0.14" @elem{Allowed multiple @DFlag{catalog} flags.}]} @subcommand{@command/toc{remove} @nonterm{option} ... @nonterm{pkg} ... --- Attempts to remove the given packages. By default, if a package is the dependency @@ -904,7 +906,8 @@ package is created. @history[#:changed "6.4.0.14" @elem{Added the @DFlag{dry-run} flag.} #:changed "7.2.0.8" @elem{Added the @DFlag{recompile-only} flag.} - #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.}]} + #:changed "7.4.0.4" @elem{Added the @DFlag{no-docs}, @Flag{D} flags.} + #:changed "7.6.0.14" @elem{Allowed multiple @DFlag{catalog} flags.}]} @subcommand{@command/toc{create} @nonterm{option} ... @nonterm{directory-or-package} --- Bundles a package into an archive. Bundling @@ -1024,12 +1027,13 @@ for @nonterm{key}. @DFlag{all}, but when a @nonterm{package-name} is provided, catalogs are consulted to ensure that he package is available.} @item{@DFlag{modules} --- Shows the modules that are implemented by a package.} - @item{@DFlag{catalog} @nonterm{catalog} --- Queries @nonterm{catalog} instead of the currently configured - @tech{package catalogs}.} + @item{@DFlag{catalog} @nonterm{catalog} --- Queries @nonterm{catalog}s instead of the currently configured + @tech{package catalogs}. This flag can be provided multiple times. The catalogs are tried in the order provided.} @item{@DFlag{version} @nonterm{version} or @Flag{v} @nonterm{version} --- Queries catalogs for a result specific to @nonterm{version}, instead of the installation's Racket version.} ] +@history[#:changed "7.6.0.14" @elem{Allowed multiple @DFlag{catalog} flags.}] } @subcommand{@command/toc{catalog-copy} @nonterm{option} ... @nonterm{src-catalog} ... @nonterm{dest-catalog} diff --git a/racket/collects/pkg/main.rkt b/racket/collects/pkg/main.rkt index f685138715..17e9086f6b 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -118,6 +118,13 @@ [(regexp-match? #rx"^[a-zA-Z]*://" s) (string->url s)] [else (path->url (path->complete-path s))])) +(define-syntax-rule (with-catalogs body ...) + (let ([catalogs (catalog-list)]) + (parameterize ([current-pkg-catalogs + (and (cons? catalogs) + (map catalog->url (reverse catalogs)))]) + body ...))) + (define (clone-to-package-name clone cmd) ;; Use directory name as sole package name, if possible (define-values (base name dir?) (split-path clone)) @@ -181,8 +188,9 @@ install-copy-flags/post-clone ... #:once-any scope-flags ... - #:once-each + #:multi catalog-flags ... + #:once-each [#:bool skip-installed () ("Skip a if already installed")] [#:bool pkgs () ("Install only the specified packages, even when none are provided")] install-force-flags ... @@ -223,8 +231,7 @@ (values pkg-source a-type))) (define setup-collects (with-pkg-lock - (parameterize ([current-pkg-catalogs (and catalog - (list (catalog->url catalog)))]) + (with-catalogs (pkg-install #:from-command-line? #t #:dep-behavior (or (and auto 'search-auto) deps @@ -279,8 +286,9 @@ install-copy-flags/post-clone ... #:once-any scope-flags ... - #:once-each + #:multi catalog-flags ... + #:once-each [#:bool skip-uninstalled () ("Skip a given if not installed")] install-force-flags ... install-clone-flags ... @@ -316,8 +324,7 @@ (define lookup? (or lookup unclone)) (define setup-collects (with-pkg-lock - (parameterize ([current-pkg-catalogs (and catalog - (list (catalog->url catalog)))]) + (with-catalogs (pkg-update (for/list ([pkg-source (in-list pkg-source)]) (cond [lookup? @@ -459,8 +466,9 @@ [#:bool binary-lib () ("Strip source elements and documentation before installing")] #:once-any scope-flags ... - #:once-each + #:multi catalog-flags ... + #:once-each install-force-flags ... dry-run-flags ... job-flags ... @@ -471,8 +479,7 @@ (lambda () (define setup-collects (with-pkg-lock - (parameterize ([current-pkg-catalogs (and catalog - (list (catalog->url catalog)))]) + (with-catalogs (pkg-migrate from-version #:from-command-line? #t #:dep-behavior deps @@ -548,25 +555,25 @@ (list "key" "val")] ;; ---------------------------------------- [catalog-show - "Show package information as reported by a catalog" + "Show package information as reported by catalogs" + #:multi + catalog-flags ... #:once-each [#:bool all () "Show all packages"] [#:bool only-names () "Show only package names"] [#:bool modules () "Show implemented modules"] - catalog-flags ... [(#:str vers #f) version ("-v") "Show result for Racket "] #:args pkg-name (when (and all (pair? pkg-name)) ((pkg-error 'catalog-show) "both `--all' and package names provided")) - (parameterize ([current-pkg-catalogs (and catalog - (list (catalog->url catalog)))] - [current-pkg-error (pkg-error 'catalog-show)] - [current-pkg-lookup-version (or version - (current-pkg-lookup-version))]) - (pkg-catalog-show pkg-name - #:all? all - #:only-names? only-names - #:modules? modules))] + (with-catalogs + (parameterize ([current-pkg-error (pkg-error 'catalog-show)] + [current-pkg-lookup-version (or version + (current-pkg-lookup-version))]) + (pkg-catalog-show pkg-name + #:all? all + #:only-names? only-names + #:modules? modules)))] ;; ---------------------------------------- [catalog-copy "Copy/merge package name catalogs" @@ -664,6 +671,7 @@ (pkg-empty-trash #:list? list #:quiet? #f)))]))])) + (define catalog-list (make-parameter null)) (make-commands #:scope-flags ([(#:sym scope [installation user] #f) scope () @@ -684,7 +692,8 @@ #:trash-flags ([#:bool no-trash () ("Delete uninstalled/updated, instead of moving to a trash folder")]) #:catalog-flags - ([(#:str catalog #f) catalog () "Use instead of configured catalogs"]) + ([(#:str catalog #f) catalog () "Use s instead of configured catalogs" + (catalog-list (cons catalog (catalog-list)))]) #:install-type-flags ([(#:sym type [file dir file-url dir-url git github name] #f) type ("-t") ("Specify type of , instead of inferred;"