Commit 5e972da1 authored by Eric Timmons's avatar Eric Timmons
Browse files

Add version constraints to manual

parent 3667461e
Pipeline #2997 passed with stages
in 32 minutes and 48 seconds
......@@ -1229,6 +1229,7 @@ slightly convoluted example:
(defsystem "foo"
:version (:read-file-form "variables" :at (3 2))
:compatible-versions (:>= "1")
((:file "package")
(:file "variables" :depends-on ("package"))
......@@ -1407,6 +1408,13 @@ We recommend you either prefix use of UIOP functions with the package prefix @co
or make sure your system @code{:depends-on ((:version "asdf" "3.1.2"))}
or has a @code{#-asdf3.1 (error "MY-SYSTEM requires ASDF 3.1.2")}.
Starting with ASDF 3.4, you can specify how backwards compatible you
expect your system to be using the @code{:compatible-versions}
argument. In this example, this version of @code{foo} should satisfy any
system that expects @code{foo} to be between versions 1 and the current
Finally, we elided most metadata, but showed how you can have ASDF automatically extract
the system's version from a source file. In this case, the 3rd subform of the 4th form
......@@ -1477,6 +1485,8 @@ Presumably, the 4th form looks like @code{(defparameter *foo-version* "5.6.7")}.
| :source-control @refrule{source-control}
| :version @refrule{version-specifier}
| :entry-point @var{object} # @pxref{Entry point}
# This is only available since ASDF 3.4
| :compatible-versions @refrule{version-constraint}
@defrule{source-control} ( @var{keyword} @var{string} )
......@@ -1513,7 +1523,7 @@ Presumably, the 4th form looks like @code{(defparameter *foo-version* "5.6.7")}.
# in :in-order-to
@defrule{dependency-def} @refrule{simple-component-name}
| ( :feature @refrule{feature-expression} @refrule{dependency-def} ) # @pxref{Feature dependencies}
| ( :version @refrule{simple-component-name} @refrule{version-specifier} )
| ( :version @refrule{simple-component-name} @refrule{version-constraint} )
| ( :require @var{module-name} )
# "dependency" is used in :in-order-to, as opposed to "dependency-def"
......@@ -1532,6 +1542,16 @@ Presumably, the 4th form looks like @code{(defparameter *foo-version* "5.6.7")}.
@defrule{line-specifier} :at @var{integer} # base zero
@defrule{form-specifier} :at [ @var{integer} | ( @var{integer}+ ) ]
@defrule{version-constraint} @refrule{compound-version-constraint}
| @refrule{compatibility-version-constraint}
| @refrule{simple-version-constraint}
@defrule{compound-version-constraint} ( :and @refrule{version-constraint} )
| ( :or @refrule{version-constraint} )
@defrule{compatibility-version-constraint} ( :compatible @var{string} ) | @var{string}
@defrule{simple-version-constraint} ( :> @var{string} ) | ( :>= @var{string} )
| ( :< @var{string} ) | ( :<= @var{string} )
| ( := @var{string} ) | ( :/= @var{string} )
@defrule{method-form} ( @refrule{operation-name} @refrule{qual} @var{lambda-list} @Arest{} @var{body} )
@defrule{qual} @refrule{method-qualifier}?
@defrule{method-qualifier} :before | :after | :around
......@@ -1805,6 +1825,67 @@ where significant API incompatibilities are signaled by an increased major numbe
@xref{Common attributes of components}.
@subsection Version constraints
@cindex version constraints
@cindex :compatible-versions
@anchor{Version constraints}
ASDF allows systems to specify constraints on the allowed version of
their dependencies. Additionally, systems can specify which of their own
versions they are API compatible with. Both of these are specified using
version constraints. Be aware that ASDF simply evaluates these
constraints and signals an error if they are not met. It is up to you or
your package management system to ensure that compatible versions of
systems are installed and discoverable by ASDF.
To specify a constraint on the version of dependency @code{foo}, simply
add something like the following to your @code{:depends-on} list:
@code{(:version "foo" (:and "1.2" (:/= "1.4.0")))}. This constraint says
that any version of @code{foo} is allowed, so long as it is
``compatible'' with version 1.2 (discussed more below) and is not equal
to 1.4.0.
By default a compatibility constraint is equivalent to specifying the
minimum version of a system. However, a system can provide its own
defintion of what compatibility means to it via the
@code{:compatible-versions} argument to @code{defsystem}. Version
@var{x} of a system is considered compatible with version @var{y} of
itself if both @var{x} is greater than or equal to @var{y} and @var{y}
satisfies version @var{x}'s @code{:compatible-versions} constraint, if
Consider the three following examples of system @code{foo}. The first
two satisfy the previous dependency constraint, but the third does not.
(defsystem "foo"
:version "1.3.0"
(defsystem "foo"
:version "2.0.0"
(defsystem "foo"
:version "3.0.0"
:compatible-versions (:>= "3")
@end lisp
Common Lisp allows for a great deal of introspection at run and compile
time. As such, it is very possible that your system can handle any
version of @code{foo}, even if @code{foo}'s author believes them to be
incompatible under normal circumstances. If that is the case, simply use
the @code{:or} operator. All three definitions of @code{foo} satisfy
this constraint: @code{(:version "foo" (:and (:or "1.2" "3.0") (:/= "1.4.0")))}.
While the version constraint language allows you to disallow versions of
a dependency that are yet unrelasesed, it is extremely bad form to do
so. When specifying a constraint on a dependency, you should avoid the
@code{:<} and @code{:<=} operators. Instead you should use @code{:/=} to
knock out known bad versions and otherwise leave it up to the author of
your dependency to declare known incompatibilities.
@subsection Require
@cindex :require dependencies
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment