raco pkg update: recognize a directory that coresponds to a clone link

For example,

 raco pkg update --clone my/clone/test-pkg
 raco pkg update my/clone/test-pkg

will check for updates in the second case, not change the installation
to a directory link.
This commit is contained in:
Matthew Flatt 2014-12-07 09:05:12 -07:00
parent 9c75238cf2
commit 39a9526f35
7 changed files with 98 additions and 19 deletions

View File

@ -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}.

View File

@ -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}.}

View File

@ -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)))

View File

@ -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?)))))]

View File

@ -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

View File

@ -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)

View File

@ -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)