1#lang scribble/manual
2@(require scribble/bnf
3          (for-label version/patchlevel
4                     version/check
5                     version/utils
6                     racket/base
7                     racket/contract))
8
9@(define (selflink s) (link s (tt s)))
10
11@title{Version: Racket Version Checking}
12
13The @filepath{version} collection contains several version-related
14pieces that are used by Racket.  See also @racket[version] from
15@racketmodname[racket/base].
16
17@; ----------------------------------------------------------------------
18
19@section{Installed Patch Level}
20
21@defmodule[version/patchlevel]
22
23@defthing[patchlevel exact-nonnegative-integer?]{
24
25Indicates the current installed patch level, which is normally zero,
26but may be updated by patches to DrRacket.}
27
28@; ----------------------------------------
29
30@section{Checking Available Versions}
31
32@defmodule[version/check]
33
34@defproc[(check-version) (or/c symbol? list?)]{
35
36Checks the currently available version on the Racket website
37(@selflink["https://download.racket-lang.org"]) and returns a value that
38indicates the state of the current installation:
39
40@itemize[
41
42@item{@racket[`ok] --- You're fine.}
43
44@item{@racket[`(ok-but ,_version)] --- You have a fine stable
45  version, but note that there is a newer alpha version available
46  numbered @racket[_version].}
47
48@item{@racket[`(newer ,_version)] --- You have an old
49  version.  Please upgrade to @racket[_version].}
50
51@item{@racket[`(newer ,_version ,_alpha)] --- You have an
52  old-but-stable version, please upgrade to @racket[_version]; you
53  may consider also the newer alpha version numbered
54  @racket[_alpha].}
55
56@item{@racket[`(error ,_message)] --- An error occurred, and
57  @racket[_message] is a string that indicates the error.}
58
59@item{@racket[`(error ,_message ,_additional-info)] --- An error
60   occurred; @racket[_message] is a string that indicates the
61   error, and @racket[_additional-info] is a string containing a
62   system error.  The @racket[_additional-info] content is always
63   parenthesizes, so @racket[message] is a short error and
64   @racket[(string-append message " " additional-info)] is a
65   verbose one.}
66
67]
68 Note that, depending on network conditions, @racket[check-version]
69 may keep trying for a long time (currently 30 seconds)
70 before returning @racket['(error "timeout")].
71 For testing purposes, when the environment variable
72 @indexed-envvar{PLT_CHECK_VERSION_SIMULATE_TIMEOUT}
73 is set, @racket[check-version] will simulate such network conditions,
74 @seclink["logging" #:doc '(lib "scribblings/reference/reference.scrbl")]{logging}
75 a @racket['warning]-level message with the topic @racket['version/check]
76 and then sleeping until the timeout.
77}
78
79@; ----------------------------------------------------------------------
80
81@section{Version Utilities}
82
83@defmodule[version/utils]{
84  The @racketmodname[version/utils] library provides a few of convenient
85  utilities for dealing with version strings.}
86
87@defproc[(valid-version? [v any/c]) boolean?]{
88  Returns @racket[#t] if @racket[v] is a valid Racket version
89  string, @racket[#f] otherwise.
90
91  A valid version has one of the following forms:
92
93  @itemlist[
94    @item{@nonterm{maj}@litchar{.}@nonterm{min}}
95    @item{@nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub}}
96    @item{@nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub}@litchar{.}@nonterm{rel}}
97  ]
98
99  subject to the following constraints:
100
101  @itemlist[
102
103     @item{@nonterm{maj}, @nonterm{min}, @nonterm{sub}, and
104           @nonterm{rel} are all canonical decimal representations of
105           natural numbers (i.e., decimal digits with no leading
106           @litchar{0} unless the number is exactly @litchar{0})}
107
108    @item{@nonterm{rel} is not @litchar{0}}
109
110    @item{@nonterm{sub} is not @litchar{0} unless @nonterm{rel} is included}
111
112    @item{@nonterm{min} has no more than two digits}
113
114    @item{@nonterm{sub} and @nonterm{rel} have no more than three digits}
115
116  ]
117
118  The constraints force version numbers to be in a canonical form. For
119  example, a would-be version string @racket["4.3.0"] must be written
120  instead as @racket["4.3"], @racket["4.3.1.0"] must be written
121  instead as @racket["4.3.1"], and @racket["4"] must be written as
122  @racket["4.0"].}
123
124@defproc[(version->list [str valid-version?])
125         (list/c integer? integer? integer? integer?)]{
126  Returns a list of four numbers that the given version string
127  represent.}
128
129@defproc[(version<? [str1 valid-version?] [str2 valid-version?]) boolean?]{
130  Returns @racket[#t] if @racket[str1] represents a version that is
131  strictly smaller than @racket[str2], @racket[#f] otherwise.}
132
133@defproc[(version<=? [str1 valid-version?] [str2 valid-version?]) boolean?]{
134  Returns @racket[#t] if @racket[str1] represents a version that is
135  smaller than or equal to @racket[str2], @racket[#f] otherwise.}
136
137@defproc[(alpha-version? [str valid-version?]) boolean?]{
138  Returns @racket[#t] if the version that @racket[str] represents is an
139  alpha version.
140
141  A version number of the form @nonterm{maj}@litchar{.}@nonterm{min},
142  @nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub},
143  or @nonterm{maj}@litchar{.}@nonterm{min}@litchar{.}@nonterm{sub}@litchar{.}@nonterm{rel}
144  is an alpha version if @nonterm{min} is @litchar{90} or more,
145  @nonterm{sub} is @litchar{900} or more, or @nonterm{rel} is
146  @litchar{900} or more.}
147
148@defproc[(version->integer [str string?]) (or/c integer? #f)]{
149  Converts the version string into an integer.  For version
150  @racket["X.YY.ZZZ.WWW"], the result will be @racketvalfont{XYYZZZWWW}.
151  This function works also for legacy Racket versions by
152  translating @racket["XYY.ZZZ"] to @racketvalfont{XYYZZZ000}.  The
153  resulting integer can thefore be used to conveniently compare any two
154  (valid) version strings. If the version string is invalid as either a
155  regular version string or a legacy version string, the resulting
156  value is @racket[#f].
157
158  Note that this is the only function that deals with legacy version
159  strings.}
160