planet2: versions for dependencies
This commit is contained in:
parent
bfe9548aa6
commit
0e140a8173
|
@ -23,6 +23,7 @@
|
|||
setup/getinfo
|
||||
setup/dirs
|
||||
racket/format
|
||||
version/utils
|
||||
"name.rkt"
|
||||
"util.rkt")
|
||||
|
||||
|
@ -153,12 +154,35 @@
|
|||
(define (check-dependencies deps)
|
||||
(unless (and (list? deps)
|
||||
(for/and ([dep (in-list deps)])
|
||||
(and (string? dep)
|
||||
(package-source->name dep))))
|
||||
(define (package-source? dep)
|
||||
(and (string? dep)
|
||||
(package-source->name dep)))
|
||||
(define (version? s)
|
||||
(and (string? s)
|
||||
(valid-version? s)))
|
||||
(or (package-source? dep)
|
||||
(and (list? dep)
|
||||
(= 2 (length dep))
|
||||
(package-source? (car dep))
|
||||
(version? (cadr dep))))))
|
||||
(pkg-error (~a "invalid `deps' specification\n"
|
||||
" specification: ~e")
|
||||
deps)))
|
||||
|
||||
(define (dependency->name dep)
|
||||
(package-source->name
|
||||
(dependency->source dep)))
|
||||
|
||||
(define (dependency->source dep)
|
||||
(if (string? dep)
|
||||
dep
|
||||
(car dep)))
|
||||
|
||||
(define (dependency->version dep)
|
||||
(if (string? dep)
|
||||
#f
|
||||
(cadr dep)))
|
||||
|
||||
(define (with-package-lock* t)
|
||||
(make-directory* (pkg-dir))
|
||||
(call-with-file-lock/timeout
|
||||
|
@ -187,10 +211,11 @@
|
|||
(define (package-index-lookup pkg)
|
||||
(or
|
||||
(for/or ([i (in-list (read-pkg-cfg/def "indexes"))])
|
||||
(define addr (combine-url/relative (string->url i)
|
||||
(format "pkg/~a" pkg)))
|
||||
(log-planet2-debug "resolving via ~a" (url->string addr))
|
||||
(call/input-url+200
|
||||
(combine-url/relative
|
||||
(string->url i)
|
||||
(format "/pkg/~a" pkg))
|
||||
addr
|
||||
read))
|
||||
(pkg-error (~a "cannot find package on indexes\n"
|
||||
" package: ~a")
|
||||
|
@ -631,7 +656,8 @@
|
|||
(when clean?
|
||||
(delete-directory/files pkg-dir)))
|
||||
(define simultaneous-installs
|
||||
(list->set (map install-info-name infos)))
|
||||
(for/hash ([i (in-list infos)])
|
||||
(values (install-info-name i) (install-info-directory i))))
|
||||
(cond
|
||||
[(and (not updating?) (package-info pkg-name #f))
|
||||
(clean!)
|
||||
|
@ -683,32 +709,38 @@
|
|||
'deps (lambda () empty)
|
||||
#:checker check-dependencies))
|
||||
(define unsatisfied-deps
|
||||
(filter-not (λ (dep)
|
||||
(or (set-member? simultaneous-installs
|
||||
(package-source->name dep))
|
||||
(hash-has-key? db dep)))
|
||||
deps))
|
||||
(map dependency->source
|
||||
(filter-not (λ (dep)
|
||||
(define name (dependency->name dep))
|
||||
(or (equal? name "racket")
|
||||
(hash-ref simultaneous-installs name #f)
|
||||
(hash-has-key? db name)))
|
||||
deps)))
|
||||
(and (not (empty? unsatisfied-deps))
|
||||
unsatisfied-deps)))
|
||||
=>
|
||||
(λ (unsatisfied-deps)
|
||||
(match
|
||||
(match
|
||||
(or dep-behavior
|
||||
(if name?
|
||||
'search-ask
|
||||
'fail))
|
||||
['fail
|
||||
(clean!)
|
||||
(pkg-error "missing dependencies\n missing packages:~a" (format-list unsatisfied-deps))]
|
||||
(pkg-error (~a "missing dependencies\n"
|
||||
" for package: ~a\n"
|
||||
" missing packages:~a")
|
||||
pkg
|
||||
(format-list unsatisfied-deps))]
|
||||
['search-auto
|
||||
(printf (string-append
|
||||
"The following packages are listed as dependencies, but are not currently installed,\n"
|
||||
"so we will automatically install them:\n"))
|
||||
"so they will be automatically installed:\n"))
|
||||
(printf "\t")
|
||||
(for ([p (in-list unsatisfied-deps)])
|
||||
(printf "~a " p))
|
||||
(printf "\n")
|
||||
(raise (vector infos unsatisfied-deps))]
|
||||
(raise (vector updating? infos unsatisfied-deps void))]
|
||||
['search-ask
|
||||
(printf "The following packages are listed as dependencies, but are not currently installed:\n")
|
||||
(printf "\t")
|
||||
|
@ -720,13 +752,110 @@
|
|||
(flush-output)
|
||||
(match (read-line)
|
||||
[(or "y" "Y" "")
|
||||
(raise (vector infos unsatisfied-deps))]
|
||||
(raise (vector updating? infos unsatisfied-deps void))]
|
||||
[(or "n" "N")
|
||||
(clean!)
|
||||
(pkg-error "missing dependencies\n missing packages:~a" (format-list unsatisfied-deps))]
|
||||
[x
|
||||
(eprintf "Invalid input: ~e\n" x)
|
||||
(loop)]))]))]
|
||||
[(and
|
||||
(not (eq? dep-behavior 'force))
|
||||
(let ()
|
||||
(define deps (get-metadata metadata-ns pkg-dir
|
||||
'deps (lambda () empty)
|
||||
#:checker check-dependencies))
|
||||
(define update-deps
|
||||
(filter-map (λ (dep)
|
||||
(define name (dependency->name dep))
|
||||
(define req-vers (dependency->version dep))
|
||||
(define-values (inst-vers* can-try-update?)
|
||||
(cond
|
||||
[(not req-vers)
|
||||
(values #f #f)]
|
||||
[(equal? name "racket")
|
||||
(values (version) #f)]
|
||||
[(hash-ref simultaneous-installs name #f)
|
||||
=> (lambda (dir)
|
||||
(values
|
||||
(get-metadata metadata-ns dir
|
||||
'version (lambda () "0.0"))
|
||||
#f))]
|
||||
[else
|
||||
(values (get-metadata metadata-ns (package-directory name)
|
||||
'version (lambda () "0.0"))
|
||||
#t)]))
|
||||
(define inst-vers (if (and req-vers
|
||||
(not (and (string? inst-vers*)
|
||||
(valid-version? inst-vers*))))
|
||||
(begin
|
||||
(log-planet2-error
|
||||
"bad verson specification for ~a: ~e"
|
||||
name
|
||||
inst-vers*)
|
||||
"0.0")
|
||||
inst-vers*))
|
||||
(and req-vers
|
||||
((version->integer req-vers)
|
||||
. > .
|
||||
(version->integer inst-vers))
|
||||
(list name can-try-update? inst-vers req-vers)))
|
||||
deps))
|
||||
(and (not (empty? update-deps))
|
||||
update-deps)))
|
||||
=> (lambda (update-deps)
|
||||
(define (report-mismatch update-deps)
|
||||
(define multi? (1 . < . (length update-deps)))
|
||||
(pkg-error (~a "version mismatch for dependenc~a\n"
|
||||
" for package: ~a\n"
|
||||
" mismatch packages:~a")
|
||||
(if multi? "ies" "y")
|
||||
pkg
|
||||
(format-deps update-deps)))
|
||||
(define (format-deps update-deps)
|
||||
(format-list (for/list ([ud (in-list update-deps)])
|
||||
(format "~a (have ~a, need ~a)"
|
||||
(car ud)
|
||||
(caddr ud)
|
||||
(cadddr ud)))))
|
||||
;; If there's a mismatch that we can't attempt to update, complain.
|
||||
(unless (andmap cadr update-deps)
|
||||
(report-mismatch (filter (compose not cadr) update-deps)))
|
||||
;; Try updates:
|
||||
(define update-pkgs (map car update-deps))
|
||||
(define (make-pre-succeed)
|
||||
(let ([to-update (filter-map update-package update-pkgs)])
|
||||
(log-error "to update ~s" to-update)
|
||||
(λ () (for-each (compose remove-package pkg-desc-name) to-update))))
|
||||
(match (or dep-behavior
|
||||
(if name?
|
||||
'search-ask
|
||||
'fail))
|
||||
['fail
|
||||
(clean!)
|
||||
(report-mismatch update-deps)]
|
||||
['search-auto
|
||||
(printf (string-append
|
||||
"The following packages are listed as dependencies, but are not at the required\n"
|
||||
"version, so they will be automatically updated:~a\n")
|
||||
(format-deps update-deps))
|
||||
(raise (vector #t infos update-pkgs (make-pre-succeed)))]
|
||||
['search-ask
|
||||
(printf (~a "The following packages are listed as dependencies, but are not at the required\n"
|
||||
"versions:~a\n")
|
||||
(format-deps update-deps))
|
||||
(let loop ()
|
||||
(printf "Would you like to update them via your package indices? [Yn] ")
|
||||
(flush-output)
|
||||
(match (read-line)
|
||||
[(or "y" "Y" "")
|
||||
(raise (vector #t infos update-pkgs (make-pre-succeed)))]
|
||||
[(or "n" "N")
|
||||
(clean!)
|
||||
(report-mismatch update-deps)]
|
||||
[x
|
||||
(eprintf "Invalid input: ~e\n" x)
|
||||
(loop)]))]))]
|
||||
[else
|
||||
(λ ()
|
||||
(define final-pkg-dir
|
||||
|
@ -788,14 +917,14 @@
|
|||
#:updating? [updating? #f])
|
||||
(with-handlers* ([vector?
|
||||
(match-lambda
|
||||
[(vector new-infos deps)
|
||||
[(vector updating? new-infos deps more-pre-succeed)
|
||||
(install-cmd
|
||||
#:old-infos new-infos
|
||||
#:old-auto+pkgs (append old-descs descs)
|
||||
#:force? force
|
||||
#:ignore-checksums? ignore-checksums
|
||||
#:dep-behavior dep-behavior
|
||||
#:pre-succeed pre-succeed
|
||||
#:pre-succeed (lambda () (pre-succeed) (more-pre-succeed))
|
||||
#:updating? updating?
|
||||
(for/list ([dep (in-list deps)])
|
||||
(pkg-desc dep #f #f #t)))])])
|
||||
|
@ -841,7 +970,7 @@
|
|||
(and new-checksum
|
||||
(not (equal? checksum new-checksum))
|
||||
;; FIXME: the type shouldn't be #f here; it should be
|
||||
;; preseved form instal time:
|
||||
;; preseved from install time:
|
||||
(pkg-desc orig-pkg-source #f pkg-name auto?))]))
|
||||
|
||||
(define ((package-dependencies metadata-ns) pkg-name)
|
||||
|
|
|
@ -39,26 +39,38 @@ metadata}.
|
|||
|
||||
@deftech{Package metadata} is:
|
||||
@itemlist[
|
||||
@item{a @deftech{package name} -- a string made of the characters @|package-name-chars|.}
|
||||
@item{a list of dependencies -- a list of strings that name other packages that must be installed simultaneously.}
|
||||
@item{a checksum -- a string that identifies different releases of a package.}
|
||||
@item{a @deftech{package name} --- a string made of the characters @|package-name-chars|.}
|
||||
@item{a @deftech{version} --- a string of the form @nonterm{maj}@litchar{.}@nonterm{min},
|
||||
@nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub}, or
|
||||
@nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub}@litchar{.}@nonterm{rel},
|
||||
where @nonterm{maj}, @nonterm{min}, @nonterm{sub}, and @nonterm{rel} are
|
||||
all canonical decimal representations of natural numbers, @nonterm{min} has no more
|
||||
than two digits, and @nonterm{sub} and @nonterm{rel} has no more than
|
||||
three digits. A version is intended to reflect available features of
|
||||
a package, and should not be confused with different releases of
|
||||
a package as indicated by the @tech{checksum}.}
|
||||
@item{a list of dependencies --- a list of packages to be installed simultaneously, optionally
|
||||
with a lower bound on each package's version.}
|
||||
@item{a @deftech{checksum} --- a string that identifies different releases of a package. A
|
||||
package can be updated when its @tech{checksum} changes
|
||||
whether or not its @tech{version} changes.}
|
||||
]
|
||||
|
||||
A @tech{package} is typically represented by a directory with the same
|
||||
name as the package. The checksum is typically left implicit.
|
||||
If the package depends on other packages, the directory can
|
||||
contain a file named @filepath{info.rkt} (see @secref["metadata"]).
|
||||
name as the package. The @tech{checksum} is typically left implicit.
|
||||
The package directory can contain a file named @filepath{info.rkt}
|
||||
to declare other metadata (see @secref["metadata"]).
|
||||
|
||||
A @deftech{package source} identifies a @tech{package}
|
||||
representation. Each package source type has a different way of
|
||||
storing the checksum. The valid package source types are:
|
||||
storing the @tech{checksum}. The valid package source types are:
|
||||
|
||||
@itemlist[
|
||||
|
||||
@item{a local file path naming an archive -- The name of the package
|
||||
is the basename of the archive file. The checksum for archive
|
||||
is the basename of the archive file. The @tech{checksum} for archive
|
||||
@filepath{f.@nonterm{ext}} is given by the file @filepath{f.@nonterm{ext}.CHECKSUM}. For
|
||||
example, @filepath{~/tic-tac-toe.zip}'s checksum would be inside
|
||||
example, @filepath{~/tic-tac-toe.zip}'s @tech{checksum} would be inside
|
||||
@filepath{~/tic-tac-toe.zip.CHECKSUM}. The valid archive formats
|
||||
are (currently) @filepath{.zip}, @filepath{.tar}, @filepath{.tgz},
|
||||
@filepath{.tar.gz}, and
|
||||
|
@ -71,7 +83,7 @@ with alphabetic characters followed by @litchar{://}. The inferred
|
|||
package name is the filename without its suffix.}
|
||||
|
||||
@item{a local directory -- The name of the package is the name of the
|
||||
directory. The checksum is not present. For example,
|
||||
directory. The @tech{checksum} is not present. For example,
|
||||
@filepath{~/tic-tac-toe/} is directory package source.
|
||||
|
||||
A package source is inferred to refer
|
||||
|
@ -81,10 +93,10 @@ with alphabetic characters followed by @litchar{://}. The inferred
|
|||
package name is the directory name.}
|
||||
|
||||
@item{a remote URL naming an archive -- This type follows the same
|
||||
rules as a local file path, but the archive and checksum files are
|
||||
rules as a local file path, but the archive and @tech{checksum} files are
|
||||
accessed via HTTP(S). For example,
|
||||
@filepath{http://game.com/tic-tac-toe.zip} is a remote URL package
|
||||
source whose checksum is found at
|
||||
source whose @tech{checksum} is found at
|
||||
@filepath{http://game.com/tic-tac-toe.zip.CHECKSUM}.
|
||||
|
||||
A package source is inferred to be a URL only when it
|
||||
|
@ -99,9 +111,9 @@ contain a file named @filepath{MANIFEST} that lists all the contingent
|
|||
files. These are downloaded into a local directory and then the rules
|
||||
for local directory paths are followed. However, if the remote
|
||||
directory contains a file named @filepath{.CHECKSUM}, then it is used
|
||||
to determine the checksum. For example,
|
||||
to determine the @tech{checksum}. For example,
|
||||
@filepath{http://game.com/tic-tac-toe/} is a directory URL package
|
||||
source whose checksum is found at
|
||||
source whose @tech{checksum} is found at
|
||||
@filepath{http://game.com/tic-tac-toe/.CHECKSUM}.
|
||||
|
||||
A package source is inferred to be a URL the same for a directory or
|
||||
|
@ -120,7 +132,7 @@ is a GitHub package source.
|
|||
|
||||
The @exec{zip}-formatted archive for the repository (generated by GitHub for
|
||||
every branch) is used as a remote URL archive path, except the
|
||||
checksum is the hash identifying the branch.
|
||||
@tech{checksum} is the hash identifying the branch.
|
||||
|
||||
A package source is inferred to be a GitHub reference when it
|
||||
starts with @litchar{github://}; a package source that is otherwise
|
||||
|
@ -130,7 +142,7 @@ is the last element of @nonterm{optional-subpath} if it is
|
|||
non-empty, otherwise the inferred name is @nonterm{repository}.}
|
||||
|
||||
@item{a @tech{package name} -- A @tech{package name resolver} is
|
||||
consulted to determine the source and checksum for the package. For
|
||||
consulted to determine the source and @tech{checksum} for the package. For
|
||||
example, @exec{tic-tac-toe} is a package name that can be used as a
|
||||
package source.
|
||||
|
||||
|
@ -143,10 +155,10 @@ means that it has only the characters @|package-name-chars|.}
|
|||
A @deftech{package name resolver} (@deftech{PNR}) is a server that
|
||||
converts package names to other package sources. A PNR is identified
|
||||
by a string representing a URL, such that appending
|
||||
@exec{/pkg/}@nonterm{package} forms a URL that refers to a
|
||||
@racket[read]-able hash table with the keys: @racket['source] bound to
|
||||
the source and @racket['checksum] bound to the checksum. Typically,
|
||||
the source will be a remote URL string.
|
||||
@exec{pkg/}@nonterm{package} forms a URL that refers to a
|
||||
@racket[read]-able hash table with the keys: @racket['source] mapped to
|
||||
the @tech{package source} string and @racket['checksum] mapped to the
|
||||
@tech{checksum} value. Typically, the source will be a remote URL.
|
||||
|
||||
PLT supports two @tech{package name resolvers} that are enabled by
|
||||
default: @url{https://plt-etc.byu.edu:9004} for new
|
||||
|
@ -175,8 +187,11 @@ the purposes of conflicts, a module is a file that ends in
|
|||
@filepath{.rkt} or @filepath{.ss}.
|
||||
|
||||
Package A is a @deftech{package update} of Package B if (1) B is
|
||||
installed, (2) A and B have the same name, and (3) A's checksum is
|
||||
different than B's.
|
||||
installed, (2) A and B have the same name, and (3) A's @tech{checksum} is
|
||||
different than B's. Note that a package @tech{version} is not taken
|
||||
into account when determining a @tech{package update}, although a change
|
||||
in a package's @tech{version} (in either direction) should normally
|
||||
imply a change in the @tech{checksum}.
|
||||
|
||||
@; ----------------------------------------
|
||||
|
||||
|
@ -212,20 +227,20 @@ sub-sub-commands:
|
|||
environment variable @envvar{PLT_PLANET2_NOSETUP} is set to any non-empty value.}
|
||||
|
||||
@item{@DFlag{installation} or @Flag{i} --- Install system-wide, rather than user-local.}
|
||||
@item{@DFlag{shared} or @Flag{s} --- Install for all versions, rather than user-local and version-specific.}
|
||||
@item{@DFlag{shared} or @Flag{s} --- Install for all Racket versions, rather than user-local and version-specific.}
|
||||
|
||||
@item{@DFlag{deps} @nonterm{behavior} --- Selects the behavior for dependencies, where @nonterm{behavior} is one of
|
||||
@itemlist[
|
||||
@item{@exec{fail} --- Cancels the installation if dependencies are unmet (default for most packages)}
|
||||
@item{@exec{force} --- Installs the package(s) despite missing dependencies (unsafe)}
|
||||
@item{@exec{search-ask} --- Looks for the dependencies via the configured @tech{package name resolvers}
|
||||
(default if the dependency is an indexed name) but asks if you would like it installed.}
|
||||
@item{@exec{search-auto} --- Like @exec{search-ask}, but does not ask for permission to install.}
|
||||
@item{@exec{fail} --- Cancels the installation if dependencies are version requirements are unmet (default for most packages)}
|
||||
@item{@exec{force} --- Installs the package(s) despite missing dependencies or version requirements (unsafe)}
|
||||
@item{@exec{search-ask} --- Looks for the dependencies or updates via the configured @tech{package name resolvers}
|
||||
(default if the dependency is an indexed name) but asks if you would like it installed or updated.}
|
||||
@item{@exec{search-auto} --- Like @exec{search-ask}, but does not ask for permission to install or update.}
|
||||
]}
|
||||
|
||||
@item{@DFlag{force} --- Ignores conflicts (unsafe)}
|
||||
|
||||
@item{@DFlag{ignore-checksums} --- Ignores errors verifying package checksums (unsafe.)}
|
||||
@item{@DFlag{ignore-checksums} --- Ignores errors verifying package @tech{checksums} (unsafe).}
|
||||
|
||||
@item{@DFlag{link} --- Implies @exec{--type dir} (and overrides any specified type),
|
||||
and links the existing directory as an installed package.}
|
||||
|
@ -259,13 +274,14 @@ listed, this command fails atomically. It accepts the following @nonterm{option}
|
|||
@item{@DFlag{installation} or @Flag{i} --- Same as for @exec{install}.}
|
||||
@item{@DFlag{shared} or @Flag{s} --- Same as for @exec{install}.}
|
||||
@item{@DFlag{force} --- Ignore dependencies when removing packages.}
|
||||
@item{@DFlag{auto} --- Remove packages that were installed by the @exec{search-auto} and @exec{search-ask} dependency behavior that are no longer required.}
|
||||
@item{@DFlag{auto} --- Remove packages that were installed by the @exec{search-auto} or @exec{search-ask}
|
||||
dependency behavior and are no longer required.}
|
||||
]
|
||||
}
|
||||
|
||||
@item{@exec{show} @nonterm{option} ... --- Print information about currently installed packages.
|
||||
By default, packages are shown for all installation modes (installation-wide,
|
||||
user- and version-specific, and user-specific all-version).
|
||||
user- and Racket-version-specific, and user-specific all-version).
|
||||
The command accepts the following @nonterm{option}s:
|
||||
|
||||
@itemlist[
|
||||
|
@ -398,7 +414,7 @@ first:
|
|||
|
||||
@commandline{raco pkg create @nonterm{package}}
|
||||
|
||||
And then upload the archive and its checksum to your site:
|
||||
And then upload the archive and its @tech{checksum} to your site:
|
||||
|
||||
@commandline{scp @nonterm{package}.zip @nonterm{package}.zip.CHECKSUM your-host:public_html/}
|
||||
|
||||
|
@ -406,8 +422,8 @@ Now, publish your package source as:
|
|||
|
||||
@inset{@exec{http://your-host/~@nonterm{user}/@nonterm{package}.zip}}
|
||||
|
||||
Whenever you want to release a new version, recreate and reupload the
|
||||
package archive (and checksum). Your changes will automatically be
|
||||
Whenever you want to provide a new release of a package, recreate and reupload the
|
||||
package archive (and @tech{checksum}). Your changes will automatically be
|
||||
discovered by those who used your package source when they use
|
||||
@exec{raco pkg update}.
|
||||
|
||||
|
@ -459,6 +475,16 @@ when backwards incompatible changes are necessary. For example,
|
|||
present interfaces to external, versioned things, such as
|
||||
@pkgname{sqlite3} or @pkgname{libgtk2}.}
|
||||
|
||||
@item{A @tech{version} declaration for a package is used only by other
|
||||
package implementors to effectively declare dependencies on provided
|
||||
features. Such declarations allow @exec{raco pkg install} and
|
||||
@exec{raco pkg update} to help check dependencies. Declaring and
|
||||
changing a version is optional, and @tech{package name resolvers}
|
||||
ignore version declarations; in particular, a package is a candidate
|
||||
for updating when its @tech{checksum} changes, independent of whether
|
||||
the package's version changes or in which direction the version
|
||||
changes.}
|
||||
|
||||
@item{Packages should not include large sets of utilities libraries
|
||||
that are likely to cause conflicts. For example, packages should not
|
||||
contain many extensions to the @filepath{racket} collection, like
|
||||
|
@ -491,11 +517,26 @@ The following fields are used by the package manager:
|
|||
|
||||
@itemlist[
|
||||
|
||||
@item{@racketidfont{deps} --- a list of @tech{package source} strings.
|
||||
Each string determines a dependency on the @tech{package} whose name
|
||||
is inferred from the @tech{package source} (i.e., dependencies are
|
||||
on package names, not package sources), while the @tech{package source} indicates
|
||||
where to get the package if needed to satisfy the dependency.}
|
||||
@item{@racketidfont{version} --- a @tech{version} string. The default
|
||||
@tech{version} of a package is @racket["0.0"].}
|
||||
|
||||
@item{@racketidfont{deps} --- a list of dependencies, where each
|
||||
dependency is either a @tech{package source} strings or a list
|
||||
containing a @tech{package source} string and a
|
||||
@tech{version} string.
|
||||
|
||||
Each elements of the @racketidfont{deps} list determines a
|
||||
dependency on the @tech{package} whose name is inferred from
|
||||
the @tech{package source} (i.e., dependencies are on package
|
||||
names, not package sources), while the @tech{package source}
|
||||
indicates where to get the package if needed to satisfy the
|
||||
dependency.
|
||||
|
||||
When provided, a @tech{version} string specifies a lower bound
|
||||
on an acceptable @tech{version} of the package.
|
||||
|
||||
Use the package name @racket["racket"] to specify a dependency
|
||||
on the version of the Racket installation.}
|
||||
|
||||
@item{@racketidfont{setup-collects} --- a list of path strings and/or
|
||||
lists of path strings, which are used as collection names to
|
||||
|
@ -511,6 +552,7 @@ For example, a basic @filepath{info.rkt} file might be
|
|||
|
||||
@codeblock{
|
||||
#lang setup/infotab
|
||||
(define version "1.0")
|
||||
(define deps (list _package-source-string ...))
|
||||
}
|
||||
|
||||
|
@ -578,7 +620,7 @@ requires reinstallation of all packages every version change.)
|
|||
|
||||
@subsection{Where and how are packages installed?}
|
||||
|
||||
User-local and version-specific packages are in @racket[(build-path
|
||||
User-local and Racket-version-specific packages are in @racket[(build-path
|
||||
(find-system-path 'addon-dir) (version) "pkgs")], user-local and
|
||||
all-version packages are in @racket[(build-path (find-system-path
|
||||
'addon-dir) "pkgs")], and installation-wide packages are in
|
||||
|
@ -597,18 +639,20 @@ conflict checks for user-specific packages. Similarly, new
|
|||
user-specific but all-version packages can invalidate previous
|
||||
user-specific conflict checks for a different Racket version.
|
||||
|
||||
@subsection{If packages have no version numbers, how can I update
|
||||
packages with error fixes, etc?}
|
||||
@subsection{Do I need to change a package's version when I update a package with error fixes, @|etc|?}
|
||||
|
||||
If you have a new version of the code for a package, then it will have
|
||||
a new checksum. When package updates are searched for, the checksum of
|
||||
the installed package is compared with the checksum of the source, if
|
||||
they are different, then the source is re-installed. This allows code
|
||||
changes to be distributed.
|
||||
If you have new code for a package, then it should have a new
|
||||
@tech{checksum}. When package updates are searched for, the checksum
|
||||
of the installed package is compared with the checksum of the source,
|
||||
if they are different, then the source is re-installed. This allows
|
||||
code changes to be distributed. You do not need to declare an update a
|
||||
version number, except to allow other package implementors to indicate
|
||||
a dependency on particular features (where a bug fix might be
|
||||
considered a feature, but it is not usually necessary to consider it
|
||||
that way).
|
||||
|
||||
@subsection{If packages have no version numbers, how can I specify
|
||||
which version of a package I depend on if its interface has changed
|
||||
and I need an old version?}
|
||||
@subsection{How can I specify which version of a package I depend on
|
||||
if its interface has changed and I need an @emph{old} version?}
|
||||
|
||||
In such a situation, the author of the package has released a
|
||||
backwards incompatible edition of a package. The package manager provides
|
||||
|
@ -646,9 +690,7 @@ flexible---so that code can migrate in and out of the core, packages
|
|||
can easily be split up, combined, or taken over by other authors, etc.
|
||||
|
||||
This change is bad because it makes the meaning of your program
|
||||
dependent on the state of the system. (This is already true of Racket
|
||||
code in general, because there's no way to make the required core
|
||||
version explicit, but the problem will be exacerbated by the package manager.)
|
||||
dependent on the state of the system.
|
||||
|
||||
The second major difference is that @|Planet1| is committed to
|
||||
guaranteeing that packages that never conflict with one another, so
|
||||
|
|
3
collects/tests/planet2/test-pkgs/pkg-v-one/info.rkt
Normal file
3
collects/tests/planet2/test-pkgs/pkg-v-one/info.rkt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#lang setup/infotab
|
||||
|
||||
(define version "1.0")
|
3
collects/tests/planet2/test-pkgs/pkg-v-two/info.rkt
Normal file
3
collects/tests/planet2/test-pkgs/pkg-v-two/info.rkt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#lang setup/infotab
|
||||
|
||||
(define version "2.1")
|
4
collects/tests/planet2/test-pkgs/pkg-w-one/info.rkt
Normal file
4
collects/tests/planet2/test-pkgs/pkg-w-one/info.rkt
Normal file
|
@ -0,0 +1,4 @@
|
|||
#lang setup/infotab
|
||||
|
||||
(define deps '(("pkg-v" "2.0")
|
||||
("racket" "5.3.1.10")))
|
|
@ -39,5 +39,6 @@
|
|||
"planet"
|
||||
"update-deps"
|
||||
"update-auto"
|
||||
"versions"
|
||||
"raco"
|
||||
"main-server")
|
||||
|
|
65
collects/tests/planet2/tests-versions.rkt
Normal file
65
collects/tests/planet2/tests-versions.rkt
Normal file
|
@ -0,0 +1,65 @@
|
|||
#lang racket/base
|
||||
(require rackunit
|
||||
racket/system
|
||||
unstable/debug
|
||||
racket/match
|
||||
(for-syntax racket/base
|
||||
syntax/parse)
|
||||
racket/file
|
||||
racket/runtime-path
|
||||
racket/path
|
||||
racket/list
|
||||
planet2/util
|
||||
"shelly.rkt"
|
||||
"util.rkt")
|
||||
|
||||
(pkg-tests
|
||||
(shelly-begin
|
||||
(initialize-indexes)
|
||||
|
||||
(shelly-case
|
||||
"create packages"
|
||||
$ "raco pkg create --format zip test-pkgs/pkg-v-one"
|
||||
$ "raco pkg create --format zip test-pkgs/pkg-v-two"
|
||||
$ "raco pkg create --format zip test-pkgs/pkg-w-one")
|
||||
|
||||
(hash-set! *index-ht-1* "pkg-v"
|
||||
(hasheq 'checksum
|
||||
(file->string "test-pkgs/pkg-v-one.zip.CHECKSUM")
|
||||
'source
|
||||
"http://localhost:9999/pkg-v-one.zip"))
|
||||
|
||||
(hash-set! *index-ht-1* "pkg-w"
|
||||
(hasheq 'checksum
|
||||
(file->string "test-pkgs/pkg-w-one.zip.CHECKSUM")
|
||||
'source
|
||||
"http://localhost:9999/pkg-w-one.zip"))
|
||||
|
||||
$ "raco pkg config --set indexes http://localhost:9990"
|
||||
|
||||
(shelly-case
|
||||
"update"
|
||||
(shelly-begin "install pkg-v version 1.0"
|
||||
$ "raco pkg install pkg-v")
|
||||
(shelly-begin "fail on install pkg-w, bad version for pkg-v"
|
||||
$ "raco pkg install --deps fail pkg-w"
|
||||
=exit> 1
|
||||
=stderr> #rx".*version mismatch for dependency.*for package: pkg-w.*pkg-v [(]have 1[.]0, need 2[.]0[)]")
|
||||
(shelly-begin "auto-update still fails"
|
||||
$ "raco pkg install --deps search-auto pkg-w"
|
||||
=exit> 1
|
||||
=stderr> #rx".*version mismatch for dependency.*for package: pkg-w.*pkg-v [(]have 1[.]0, need 2[.]0[)]"))
|
||||
|
||||
(hash-set! *index-ht-1* "pkg-v"
|
||||
(hasheq 'checksum
|
||||
(file->string "test-pkgs/pkg-v-two.zip.CHECKSUM")
|
||||
'source
|
||||
"http://localhost:9999/pkg-v-two.zip"))
|
||||
|
||||
(shelly-case
|
||||
"update"
|
||||
(shelly-begin "auto-update now succeeds (installs and version matches)"
|
||||
$ "raco pkg install --deps search-auto pkg-w"))
|
||||
|
||||
(initialize-indexes)))
|
||||
|
Loading…
Reference in New Issue
Block a user