diff --git a/pkgs/racket-pkgs/racket-doc/pkg/scribblings/lib.scrbl b/pkgs/racket-pkgs/racket-doc/pkg/scribblings/lib.scrbl index 09c2f78a50..29a05648c7 100644 --- a/pkgs/racket-pkgs/racket-doc/pkg/scribblings/lib.scrbl +++ b/pkgs/racket-pkgs/racket-doc/pkg/scribblings/lib.scrbl @@ -271,7 +271,7 @@ specific command-line flags for @command-ref{install}. The package lock must be held; see @racket[with-pkg-lock].} -@defproc[(pkg-update [names (listof (or/c string? pkg-desc?))] +@defproc[(pkg-update [sources (listof (or/c string? pkg-desc?))] [#:all? all? boolean? #f] [#:dep-behavior dep-behavior (or/c #f 'fail 'force 'search-ask 'search-auto) @@ -287,7 +287,8 @@ The package lock must be held; see @racket[with-pkg-lock].} [#:force-strip? force-string? boolean? #f] [#:lookup-for-clone? lookup-for-clone? boolean? #f] [#:multi-clone-mode multi-clone-mode (or/c 'fail 'force 'convert 'ask) 'fail] - [#:link-dirs? link-dirs? boolean? #f]) + [#:link-dirs? link-dirs? boolean? #f] + [#:infer-clone-from-dir? infer-clone-from-dir? boolean? #f]) (or/c 'skip #f (listof (or/c path-string? @@ -296,8 +297,8 @@ The package lock must be held; see @racket[with-pkg-lock].} Implements @racket[pkg-update-command]. The result is the same as for @racket[pkg-install]. -A string in @racket[names] refers to an installed package that should -be checked for updates. A @racket[pkg-desc] in @racket[names] +A string in @racket[sources] refers to an installed package that should +be checked for updates. A @racket[pkg-desc] in @racket[sources] indicates a package source that should replace the current installation; as an exception, if a @racket[package-desc] has the type @racket['clone] and a source with the syntax of a package name, it @@ -306,6 +307,14 @@ a Git repository clone---unless @racket[lookup-for-clone?] is true, in which case the package name is resolved through a catalog to locate a Git repository clone. +The @racket[link-dirs?] and @racket[infer-clone-from-dir?] arguments +affect how directory paths in @racket[sources] are treated. The +@racket[link-dirs?] argument is propagated to +@racket[package-source->name+type], while +@racket[infer-clone-from-dir?] introduces a conversion from a +directory source to a repository-clone source when the directory +corresponds to an existing repository-clone installation. + If @racket[from-command-line?] is true, error messages may suggest specific command-line flags for @command-ref{update}. diff --git a/pkgs/racket-pkgs/racket-doc/pkg/scribblings/pkg.scrbl b/pkgs/racket-pkgs/racket-doc/pkg/scribblings/pkg.scrbl index 6f25ec9d79..4212d086ab 100644 --- a/pkgs/racket-pkgs/racket-doc/pkg/scribblings/pkg.scrbl +++ b/pkgs/racket-pkgs/racket-doc/pkg/scribblings/pkg.scrbl @@ -587,16 +587,37 @@ update or replacement cannot be installed (e.g. it conflicts with another installed package), then this command fails without installing any of the @nonterm{pkg-source}s (or their dependencies). -If a @tech{package scope} is not specified, the scope is inferred from -the given @nonterm{pkg-source}s. +The treatment of a @nonterm{pkg-source} depends on the way that it parses: -If no @racket{pkg-source}, @DFlag{all} or @Flag{a} flag, or +@itemlist[ + + @item{When a @nonterm{pkg-source} parses as a @tech{package name}, + then the named package must be installed already, and it is + checked for updates. The @DFlag{lookup} and @DFlag{clone} flags + change this interpretation of @nonterm{pkg-source}.} + + @item{If @nonterm{pkg-source} parses as a directory @tech{package + source}, and if the named package is installed as a link to a + Git repository clone, then the clone is checked for + updates. The @DFlag{link}, @DFlag{static-link}, and + @DFlag{copy} flags change this interpretation of + @nonterm{pkg-source}.} + + @item{Otherwise, @nonterm{pkg-source} specifies a @tech{package + source} to replace the current installation of the named package.} + +] + +If no @nonterm{pkg-source}, @DFlag{all} or @Flag{a} flag, or @DFlag{clone} flag is specified, and if the current directory is within a package, then the enclosing package is updated. If no -@racket{pkg-source} is specified, but @DFlag{clone} is supplied, then -the clone directory's name is used as the only @racket{pkg-source} +@nonterm{pkg-source} is specified, but @DFlag{clone} is supplied, then +the clone directory's name is used as the only @nonterm{pkg-source} argument. +If a @tech{package scope} is not specified, the scope is inferred from +the given @nonterm{pkg-source}s. + The @exec{update} sub-command accepts the following @nonterm{option}s: @@ -606,7 +627,7 @@ argument. @item{@DFlag{lookup} --- Causes a @tech{package name} as a @nonterm{pkg-source} to be used as a replacement, instead of the name of a installed package that may have updates. (If the named package was installed through a package name, then there's effectively - no difference unless a different catalog is used.)} + no difference, unless a different catalog is used.)} @item{@DFlag{type} @nonterm{type} or @Flag{t} @nonterm{type} --- Same as for @command-ref{install}.} @item{@DFlag{name} @nonterm{pkg} or @Flag{n} @nonterm{pkg} --- Same as for @command-ref{install}.} @@ -616,8 +637,12 @@ argument. @item{@DFlag{update-deps} --- Same as for @command-ref{install}, but implied by @DFlag{auto} only for @command-ref{update}.} @item{@DFlag{skip-implies} --- Same as for @command-ref{install}.} - @item{@DFlag{link} --- Same as for @command-ref{install}.} + @item{@DFlag{link} --- Same as for @command-ref{install}, but a + directory package source is treated as a link by default only + when it does not correspond to a link to a Git repository + clone.} @item{@DFlag{static-link} --- Same as for @command-ref{install}.} + @item{@DFlag{copy} --- Same as for @command-ref{install}.} @item{@DFlag{clone} @nonterm{dir} --- Same as for @command-ref{install}, except that a @nonterm{pkg-source} as a @tech{package name} is treated as the name of an installed @@ -626,7 +651,6 @@ argument. catalog---and that source is used for the clone (which replaces the existing package installation).} @item{@DFlag{binary} --- Same as for @command-ref{install}.} - @item{@DFlag{copy} --- Same as for @command-ref{install}.} @item{@DFlag{source} --- Same as for @command-ref{install}.} @item{@DFlag{scope} @nonterm{scope} --- Selects a @tech{package scope}, the same as for @command-ref{install}.} @item{@Flag{i} or @DFlag{installation} --- Shorthand for @exec{--scope installation}.} diff --git a/pkgs/racket-pkgs/racket-test/tests/pkg/tests-clone.rkt b/pkgs/racket-pkgs/racket-test/tests/pkg/tests-clone.rkt index fae8ad0e99..a224dd1b32 100644 --- a/pkgs/racket-pkgs/racket-test/tests/pkg/tests-clone.rkt +++ b/pkgs/racket-pkgs/racket-test/tests/pkg/tests-clone.rkt @@ -214,6 +214,13 @@ $ "raco pkg update a" $ "racket -l a" =stdout> "3\n") + (shelly-case + "using directory name for an update should update the repo" + (set-file (build-path a-dir "main.rkt") "#lang racket/base 4") + $ (commit-changes-cmd) + $ (~a "raco pkg update " (build-path clone-dir "a")) + $ "racket -l a" =stdout> "4\n") + (delete-directory/files (build-path clone-dir "a")) (delete-directory/files a-dir))) diff --git a/racket/collects/pkg/lib.rkt b/racket/collects/pkg/lib.rkt index a235fcef3c..a6f989d9af 100644 --- a/racket/collects/pkg/lib.rkt +++ b/racket/collects/pkg/lib.rkt @@ -107,6 +107,7 @@ #:strip (or/c #f 'source 'binary 'binary-lib) #:force-strip? boolean? #:link-dirs? boolean? + #:infer-clone-from-dir? boolean? #:lookup-for-clone? boolean? #:multi-clone-behavior (or/c 'fail 'force 'convert 'ask)) (or/c #f 'skip (listof (or/c path-string? (non-empty-listof path-string?)))))] diff --git a/racket/collects/pkg/main.rkt b/racket/collects/pkg/main.rkt index 965dedc8a5..1ffb50c07b 100644 --- a/racket/collects/pkg/main.rkt +++ b/racket/collects/pkg/main.rkt @@ -341,7 +341,8 @@ (if batch 'fail 'ask)) - #:link-dirs? link-dirs?)))) + #:link-dirs? link-dirs? + #:infer-clone-from-dir? (not (or link static-link copy)))))) (setup "updated" no-setup #f setup-collects jobs))))] ;; ---------------------------------------- [remove diff --git a/racket/collects/pkg/private/clone-path.rkt b/racket/collects/pkg/private/clone-path.rkt index 8b2746fbcc..47de7e4a5e 100644 --- a/racket/collects/pkg/private/clone-path.rkt +++ b/racket/collects/pkg/private/clone-path.rkt @@ -17,6 +17,7 @@ adjust-to-normalize-repos convert-clone-name-to-clone-repo/update convert-clone-name-to-clone-repo/install + convert-directory-to-installed-clone desc->name desc->repo) @@ -306,6 +307,37 @@ new-pkg-name)] [else pkg-name])) +(define ((convert-directory-to-installed-clone db) d) + (cond + [(pkg-desc? d) + (define-values (name type) + (package-source->name+type (pkg-desc-source d) + (pkg-desc-type d) + #:must-infer-name? (not (pkg-desc-name d)))) + (case type + [(dir) + (define pkg-name (or (pkg-desc-name d) name)) + (define info (package-info pkg-name #:db db)) + (case (and info + (car (pkg-info-orig-pkg info))) + [(clone) + (cond + [(equal? (path->directory-path + (simple-form-path (pkg-desc-source d))) + (path->directory-path + (simplify-path + (path->complete-path (cadr (pkg-info-orig-pkg info)) + (pkg-installed-dir))))) + ;; Directory refers to a clone-linked package; preserve the + ;; link form: + (pkg-info->clone-desc pkg-name info + #:checksum #f + #:auto? (pkg-info-auto? info))] + [else d])] + [else d])] + [else d])] + [else d])) + ;; ---------------------------------------- (define (desc->name d) diff --git a/racket/collects/pkg/private/install.rkt b/racket/collects/pkg/private/install.rkt index c13a64f60c..e514a41bb5 100644 --- a/racket/collects/pkg/private/install.rkt +++ b/racket/collects/pkg/private/install.rkt @@ -86,7 +86,7 @@ (pkg-error (~a "cannot link a directory that overlaps with existing packages\n" " existing package: ~a\n" " overlapping path: ~a\n" - " a package: ~a") + " attempted package: ~a") found-pkg f pkg-name))) @@ -1095,6 +1095,7 @@ #:strip [strip-mode #f] #:force-strip? [force-strip? #f] #:link-dirs? [link-dirs? #f] + #:infer-clone-from-dir? [infer-clone-from-dir? #f] #:lookup-for-clone? [lookup-for-clone? #f] #:multi-clone-behavior [clone-behavior 'fail]) (define download-printf (if quiet? void printf)) @@ -1120,11 +1121,15 @@ #:use-cache? use-cache? #:from-command-line? from-command-line? #:link-dirs? link-dirs?) - (map (if lookup-for-clone? - (convert-clone-name-to-clone-repo/install catalog-lookup-cache - download-printf) - (convert-clone-name-to-clone-repo/update db - from-command-line?)) + (map (compose + (if infer-clone-from-dir? + (convert-directory-to-installed-clone db) + values) + (if lookup-for-clone? + (convert-clone-name-to-clone-repo/install catalog-lookup-cache + download-printf) + (convert-clone-name-to-clone-repo/update db + from-command-line?))) pkgs))) (cond [(empty? pkgs)