Racketize the `version' collection.

Also some other style things, and get rid of the redundant "doc.txt".
This commit is contained in:
Eli Barzilay 2012-06-20 12:46:02 -04:00
parent 303aaec2b4
commit 2c058f5f03
6 changed files with 225 additions and 293 deletions

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(define version-url "http://download.racket-lang.org/version.txt") (define version-url "http://download.racket-lang.org/version.txt")
(define timeout 30) (define timeout 30)
@ -13,9 +13,9 @@
(require scheme/tcp) (require scheme/tcp)
(define (url->port url) (define (url->port url)
(define-values (host path) (define-values [host path]
(apply values (cdr (regexp-match #rx"^http://([^/:@]+)(/.*)$" url)))) (apply values (cdr (regexp-match #rx"^http://([^/:@]+)(/.*)$" url))))
(define-values (i o) (tcp-connect host 80)) (define-values [i o] (tcp-connect host 80))
(fprintf o "GET ~a HTTP/1.0\r\nHost: ~a\r\n\r\n" path host) (fprintf o "GET ~a HTTP/1.0\r\nHost: ~a\r\n\r\n" path host)
(flush-output o) (flush-output o)
(close-output-port o) (close-output-port o)
@ -27,29 +27,26 @@
(case-lambda (case-lambda
[(what) `(error ,what)] [(what) `(error ,what)]
[(what more) [(what more)
`(error ,what `(error ,what ,(cond [(list? more) (format "~a" more)]
,(cond [(list? more) (format "~a" more)] [(exn? more) (format "(~a)" (exn-message more))]
[(exn? more) (format "(~a)" (exn-message more))] [else (format "(~a)" more)]))]))
[else (format "(~a)" more)]))]))
(define (with-timeout timeout thunk) (define (with-timeout timeout thunk)
(define result #f) (define result #f)
(let ([r (sync/timeout timeout (define r (sync/timeout timeout
(thread (lambda () (thread (λ ()
(set! result (set! result
(with-handlers (with-handlers
([void (lambda (e) ([void (λ (e)
(error-value "internal error" e))]) (error-value "internal error" e))])
(thunk))))))]) (thunk)))))))
(if r result (error-value "timeout")))) (if r result (error-value "timeout")))
(define (check-version-raw) (define (check-version-raw)
(let/ec escape (let/ec escape
(define (err . args) (escape (apply error-value args))) (define (err . args) (escape (apply error-value args)))
(define-syntax try (define-syntax-rule (try expr error-message)
(syntax-rules () (with-handlers ([void (λ (e) (err error-message e))]) expr))
[(_ expr error-message)
(with-handlers ([void (lambda (e) (err error-message e))]) expr)]))
;; Get server information, carefully ;; Get server information, carefully
(define version-info (define version-info
(parameterize ([current-input-port (parameterize ([current-input-port
@ -60,38 +57,35 @@
(cond [(assq key version-info) => cadr] (cond [(assq key version-info) => cadr]
[else (err (format "no `~s' in response" key) version-info)])) [else (err (format "no `~s' in response" key) version-info)]))
(define (getver key) (define (getver key)
(let ([ver (get key)]) (define ver (get key))
(if (valid-version? ver) (if (valid-version? ver) ver (err "bad version string from server" key)))
ver
(err "bad version string from server" key))))
(unless (and (list? version-info) (unless (and (list? version-info)
(andmap (lambda (x) (andmap (λ (x) (and (list? x)
(and (list? x) (= 2 (length x))
(= 2 (length x)) (symbol? (car x))
(symbol? (car x)) (string? (cadr x))))
(string? (cadr x))))
version-info)) version-info))
(err "bad response from server" version-info)) (err "bad response from server" version-info))
;; Make a decision ;; Make a decision
(let ([current (version)] (define current (version))
[stable (getver 'stable)] (define stable (getver 'stable))
[recent (getver 'recent)]) (define recent (getver 'recent))
(cond (cond
;; we have the newest version (can be > if we have a build from git) ;; we have the newest version (can be > if we have a build from git)
[(version<=? recent current) 'ok] [(version<=? recent current) 'ok]
;; we're stable, but there's a newer version ;; we're stable, but there's a newer version
[(version<=? stable current) `(ok-but ,recent)] [(version<=? stable current) `(ok-but ,recent)]
;; new version out -- no alphas or we have an alpha => show recent ;; new version out -- no alphas or we have an alpha => show recent
[(or (equal? recent stable) [(or (equal? recent stable)
(and (alpha-version? current) (and (alpha-version? current)
;; but if we have an alpha that is older then the current ;; but if we have an alpha that is older then the current
;; stable then go to the next case ;; stable then go to the next case
(version<=? stable current))) (version<=? stable current)))
`(newer ,recent)] `(newer ,recent)]
;; new version out, we have an outdated stable, there is also an alpha ;; new version out, we have an outdated stable, there is also an alpha
;; (alternatively, we have an alpha that is older than the current ;; (alternatively, we have an alpha that is older than the current
;; stable) ;; stable)
[else `(newer ,stable ,recent)])))) [else `(newer ,stable ,recent)])))
;; Check the version on the server and compare to our version. Possible return ;; Check the version on the server and compare to our version. Possible return
;; values (message is always a string): ;; values (message is always a string):

View File

@ -1,47 +0,0 @@
_version_: Racket version checking
==================================
The version collection contains several version-related pieces that
are used by Racket. First, the "check.ss" module provides a single
function:
> (check-version)
This procedure checks the currently available version on the Racket
website (doanload.racket-lang.org), and returns a value that indicates
your current state -- one of these:
* `ok
You're fine.
* `(ok-but ,version)
You have a fine stable version, but note that there is a newer
alpha version available
* `(newer ,version)
You have an old version, please upgrade to `version'
* `(newer ,version ,alpha)
You have an old-but-stable version, please upgrade to `version';
you may consider also the newer alpha version
* `(error ,message [,additional-info])
An error occurred, the message is a string that indicates the
error.
The third (optional) value is a string that can be shown as the
system error that happened. This string will always be
parenthesized, so `message' is a short error and
`(string-append message " " additional-info)' is a verbose one.
The second functionality that is provided by this collection is in the
_patchlevel_ module. This module provides a single value:
> patchlevel
which is an integer that indicates the current patch level. This is
normally zero, but may be updated by patches to DrRacket.
Finally, the "tool.rkt" makes DrRacket use both features:
* the patchlevel appears as a version `pN' suffix in DrRacket (but the
binary version as reported by `(version)' is not changed);
* it is possible to periodically check whether a new Racket
distribution is available for download.

View File

@ -1,5 +1,5 @@
;; This file contains the current patch level of Racket. ;; This file contains the current patch level of Racket.
;; It is usually `0' in the repository, changes only when a patch is made. ;; It is usually `0' in the repository, changes only when a patch is made.
#lang scheme/base #lang racket/base
(define patchlevel 0) (define patchlevel 0)
(provide patchlevel) (provide patchlevel)

View File

@ -1,6 +1,6 @@
#lang scheme/gui #lang racket/gui
(require scheme/unit scheme/class framework drscheme/tool (require racket/unit racket/class framework drracket/tool
browser/external string-constants browser/external string-constants
"patchlevel.rkt" "patchlevel.rkt"
"check.rkt") "check.rkt")
@ -29,10 +29,10 @@
(define top (and (pair? top?) (car top?))) (define top (and (pair? top?) (car top?)))
;; wait until the definitions are instantiated, return top-level window ;; wait until the definitions are instantiated, return top-level window
(define (wait-for-definitions) (define (wait-for-definitions)
(let ([ws (get-top-level-windows)]) (define ws (get-top-level-windows))
(if (null? ws) (if (null? ws)
(begin (sleep 1) (wait-for-definitions)) (begin (sleep 1) (wait-for-definitions))
(car ws)))) (car ws)))
#| ;; Cute code, but may resize the window if too much space, and people #| ;; Cute code, but may resize the window if too much space, and people
;; didn't like this way of asking if you want update checks. ;; didn't like this way of asking if you want update checks.
;; show a message and a disable button ;; show a message and a disable button
@ -40,112 +40,108 @@
(define (show-message first-time?) (define (show-message first-time?)
;; No info display if we got some non-drscheme window by accident ;; No info display if we got some non-drscheme window by accident
(cond (cond
[(with-handlers ([void (lambda _ #f)]) (send top get-info-panel)) => [(with-handlers ([void (λ _ #f)]) (send top get-info-panel)) =>
(lambda (info) (λ (info)
(sleep 3) ; wait to make this appearance visible (sleep 3) ; wait to make this appearance visible
(let* ([-check "Checking for updates..."] (define -check "Checking for updates...")
[-about "About to auto-check for updates, you can"] (define -about "About to auto-check for updates, you can")
[p (make-object horizontal-panel% info)] (define p (make-object horizontal-panel% info))
[m (make-object message% (if first-time? -about -check) p)] (define m (make-object message% (if first-time? -about -check) p))
[b (make-object button% "Disable" p disable)]) (define b (make-object button% "Disable" p disable))
(send info change-children (lambda (l) (cons p (remq p l)))) (send info change-children (λ (l) (cons p (remq p l))))
(when first-time? (when first-time?
(let ([m1 (make-object message% "these checks" p)]) (define m1 (make-object message% "these checks" p))
(sleep 20) (sleep 20)
(send p change-children (lambda (l) (remq m1 l)))) (send p change-children (λ (l) (remq m1 l)))
(send m set-label -check)) (send m set-label -check))
(sleep 2) ; wait before and after check to make it visible (sleep 2) ; wait before and after check to make it visible
(set! hide-message (set! hide-message
(lambda now? (λ ([now? #f])
(unless (and (pair? now?) (car now?)) (sleep 1)) (unless now? (sleep 1))
(send info change-children (lambda (l) (remq p l))) (send info change-children (λ (l) (remq p l)))
(set! hide-message void)))) (set! hide-message void)))
#t)] ; return #t so that the check starts #t)] ; return #t so that the check starts
[else #f])) ; no standard window -- return #f to skip the whole thing [else #f])) ; no standard window -- return #f to skip the whole thing
|# |#
;; show results in a dialog in a non-modal dialog (if it was not an ;; show results in a dialog in a non-modal dialog (if it was not an
;; explicit call) , so the window can be left around as a reminder. ;; explicit call) , so the window can be left around as a reminder.
(define (message style fmt . args) (define (message style fmt . args)
(define (run) (define (run)
(let-values ([(result new-enabled?) (define-values [result new-enabled?]
(message+check-box/custom (message+check-box/custom
(string-constant version:results-title) (string-constant version:results-title)
(apply format fmt args) (apply format fmt args)
(string-constant version:do-periodic-checks) (string-constant version:do-periodic-checks)
(string-constant ok) (string-constant ok)
(and (eq? 'newer style) (and (eq? 'newer style) (string-constant version:take-me-there))
(string-constant version:take-me-there)) #f
#f (and explicit? top)
(and explicit? top) `(,@(case style
`(,@(case style [(#f) '()] [(newer) '(stop)] [else (list style)])
[(#f) '()] [(newer) '(stop)] [else (list style)]) ,@(if enabled? '(checked) '())
,@(if enabled? '(checked) '()) default=1)))
default=1))]) (unless (eq? enabled? new-enabled?)
(unless (eq? enabled? new-enabled?) (preferences:set 'updates:enabled? (if new-enabled? 'yes 'no))
(preferences:set 'updates:enabled? (if new-enabled? 'yes 'no)) (set! enabled? new-enabled?))
(set! enabled? new-enabled?)) result)
result))
(if explicit? (if explicit?
(run) (run)
;; non-modal ;; non-modal
(parameterize ([current-eventspace (make-eventspace)]) (run)))) (parameterize ([current-eventspace (make-eventspace)]) (run))))
;; main checker ;; main checker
(define (check) (define (check)
(let ([result #f]) (define result #f)
;; run the check in a thread, with a chance to abort it ;; run the check in a thread, with a chance to abort it
(let* ([d #f] (let ([d #f])
[t (thread (lambda () (define t (thread (λ () (set! result (check-version))
(set! result (check-version)) (when d (send d show #f)))))
(when d (send d show #f))))]) (unless (sync/timeout .4 t) ; still checking, pop message
(unless (sync/timeout .4 t) ; still checking, pop message (when explicit? ; unless it's an automatic check
(when explicit? ; unless it's an automatic check (queue-callback
(queue-callback (λ ()
(lambda () (set! d (new (class dialog%
(set! d (new (class dialog% (super-new
(super-new [label (string-constant version:update-check)]
[label (string-constant version:update-check)] [parent #f])
[parent #f]) (make-object message%
(make-object message% (string-constant version:connecting-server)
(string-constant version:connecting-server) this)
this) (make-object button%
(make-object button% (string-constant abort) this
(string-constant abort) this (λ (b e) (kill-thread t) (send this show #f))
(lambda (b e) '(border))
(kill-thread t) (send this center))))
(send this show #f)) (send d show #t)))
'(border)) (sleep/yield .5))
(send this center)))) (thread-wait t)))
(send d show #t))) (cond
(sleep/yield .5)) [(and (pair? result) (eq? 'newer (car result)))
(thread-wait t))) (when (equal? 2 (message 'newer "Racket v~a ~a ~a"
(cond (cadr result)
[(and (pair? result) (eq? 'newer (car result))) (string-constant version:now-available-at)
(when (equal? 2 (message 'newer "Racket v~a ~a ~a" download-url))
(cadr result) ;; 2 = go there
(string-constant version:now-available-at) (send-url download-url)
download-url)) ;; (sleep 1) ((application-quit-handler))
;; 2 = go there )]
(send-url download-url) ;; implicit auto-check => show a message only if there is a newer
;; (sleep 1) ((application-quit-handler)) ;; version => the rest are only for explicit calls
)] [(not explicit?) (void)]
;; implicit auto-check => show a message only if there is a newer [(eq? result 'ok)
;; version => the rest are only for explicit calls (message #f (string-constant version:plt-up-to-date))]
[(not explicit?) (void)] [(not (pair? result)) (void)] ; either #f (canceled) or ok
[(eq? result 'ok) [else (case (car result)
(message #f (string-constant version:plt-up-to-date))] [(error)
[(not (pair? result)) (void)] ; either #f (canceled) or ok (message 'stop "~a: ~a~a"
[else (case (car result) (string-constant error) (cadr result)
[(error) (if (pair? (cddr result))
(message 'stop "~a: ~a~a" (string-append "\n" (caddr result)) ""))]
(string-constant error) (cadr result) [(ok-but)
(if (pair? (cddr result)) (message 'caution "~a,\n~a (v~a)"
(string-append "\n" (caddr result)) ""))] (string-constant version:plt-up-to-date)
[(ok-but) (string-constant version:but-newer-alpha)
(message 'caution "~a,\n~a (v~a)" (cadr result))]
(string-constant version:plt-up-to-date) [else (error 'check-for-updates "internal error")])]))
(string-constant version:but-newer-alpha)
(cadr result))]
[else (error 'check-for-updates "internal error")])])))
;; start the check if enabled and enough time passed ;; start the check if enabled and enough time passed
(when (or explicit? enabled?) (when (or explicit? enabled?)
(unless top (set! top (wait-for-definitions))) (unless top (set! top (wait-for-definitions)))
@ -163,25 +159,25 @@
(define (phase1) (void)) (define (phase1) (void))
(define (phase2) (define (phase2)
(preferences:add-to-warnings-checkbox-panel (preferences:add-to-warnings-checkbox-panel
(lambda (panel) (λ (panel)
(let ([b (make-object check-box% (define b
(string-constant version:do-periodic-checks) (make-object check-box%
panel (string-constant version:do-periodic-checks)
(lambda (b e) panel
(preferences:set 'updates:enabled? (λ (b e) (preferences:set 'updates:enabled?
(if (send b get-value) 'yes 'no))))]) (if (send b get-value) 'yes 'no)))))
(preferences:add-callback (preferences:add-callback
'updates:enabled? 'updates:enabled?
(lambda (p v) (send b set-value (is-enabled? v)))) (λ (p v) (send b set-value (is-enabled? v))))
(send b set-value (send b set-value
(is-enabled? (preferences:get 'updates:enabled?)))))) (is-enabled? (preferences:get 'updates:enabled?)))))
(drscheme:get/extend:extend-unit-frame (drscheme:get/extend:extend-unit-frame
(lambda (f%) (λ (f%)
(class f% (class f%
(define/override (help-menu:after-about m) (define/override (help-menu:after-about m)
(make-object menu-item% (make-object menu-item%
(string-constant version:update-menu-item) m (string-constant version:update-menu-item) m
(lambda (b e) (check-for-updates this))) (λ (b e) (check-for-updates this)))
(super help-menu:after-about m)) (super help-menu:after-about m))
(super-new)))) (super-new))))
(thread check-for-updates)) (thread check-for-updates))

View File

@ -1,4 +1,4 @@
#lang scheme/base #lang racket/base
(provide valid-version? version->list version<? version<=? alpha-version? (provide valid-version? version->list version<? version<=? alpha-version?
version->integer) version->integer)
@ -17,16 +17,15 @@
;; returns a list of 4 integers (see src/mzscheme/src/schvers.h) ;; returns a list of 4 integers (see src/mzscheme/src/schvers.h)
(define (version->list str) (define (version->list str)
(let ([ver (map string->number (regexp-split #rx"[.]" str))]) (define ver (map string->number (regexp-split #rx"[.]" str)))
(case (length ver) (case (length ver)
[(2) (append ver '(0 0))] [(2) (append ver '(0 0))]
[(3) (append ver '(0))] [(3) (append ver '(0))]
[(4) ver] [(4) ver]
[else (error 'version->list "bad version: ~e" str)]))) [else (error 'version->list "bad version: ~e" str)]))
(define (version<? a b) (define (version<? a b)
(let loop ([a (version->list a)] (let loop ([a (version->list a)] [b (version->list b)])
[b (version->list b)])
(cond [(null? a) #f] (cond [(null? a) #f]
[(< (car a) (car b)) #t] [(< (car a) (car b)) #t]
[(> (car a) (car b)) #f] [(> (car a) (car b)) #f]
@ -36,10 +35,10 @@
(or (equal? a b) (version<? a b))) (or (equal? a b) (version<? a b)))
(define (alpha-version? v) (define (alpha-version? v)
(let ([l (version->list v)]) (define l (version->list v))
(or ((list-ref l 1) . >= . 90) (or ((list-ref l 1) . >= . 90)
((list-ref l 2) . >= . 900) ((list-ref l 2) . >= . 900)
((list-ref l 3) . >= . 900)))) ((list-ref l 3) . >= . 900)))
;; returns an integer representing the version (XXYYZZZWWW) or #f if invalid ;; returns an integer representing the version (XXYYZZZWWW) or #f if invalid
;; works for pre v4 versions too ;; works for pre v4 versions too
@ -54,20 +53,19 @@
[(< n 49) ver] [(< n 49) ver]
;; old versions (earliest useful is 49, changed at 3.99) ;; old versions (earliest useful is 49, changed at 3.99)
[(<= 49 n 379) [(<= 49 n 379)
(let*-values (define-values [q r] (quotient/remainder n 100))
([(q r) (quotient/remainder n 100)] (define sfx (let ([sfx (substring ver (cdar m))])
[(sfx) (substring ver (cdar m))] (cond [(equal? sfx "") ""]
[(sfx) (cond [(equal? sfx "") ""] ;; NNNpN -> N.NN.N
;; NNNpN -> N.NN.N [(regexp-match? #rx"^p[0-9]" sfx)
[(regexp-match? #rx"^p[0-9]" sfx) (string-append "." (substring sfx 1))]
(string-append "." (substring sfx 1))] ;; NNN.N -> N.NN.0.N (not a release version)
;; NNN.N -> N.NN.0.N (not a release version) [(regexp-match? #rx"^[.]" sfx)
[(regexp-match? #rx"^[.]" sfx) (string-append ".0" sfx)]
(string-append ".0" sfx)] [else #f])))
[else #f])]) (and sfx (format "~a.~a~a" q r sfx))]
(and sfx (format "~a.~a~a" q r sfx)))]
;; bad strings ;; bad strings
[else #f])) [else #f]))
(and v (valid-version? v) (and v (valid-version? v)
(foldl (lambda (ver mul acc) (+ ver (* mul acc))) 0 (foldl (λ (ver mul acc) (+ ver (* mul acc))) 0
(version->list v) '(0 100 1000 1000)))) (version->list v) '(0 100 1000 1000))))

View File

@ -12,8 +12,8 @@
@title{Version: Racket Version Checking} @title{Version: Racket Version Checking}
The version collection contains several version-related pieces that The @racketmodname[version] collection contains several version-related
are used by Racket. See also @racket[version] from pieces that are used by Racket. See also @racket[version] from
@racketmodname[racket/base]. @racketmodname[racket/base].
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -39,36 +39,34 @@ Checks the currently available version on the PLT website
(@selflink["http://download.racket-lang.org"]) and returns a value that (@selflink["http://download.racket-lang.org"]) and returns a value that
indicates the current state of the curent installation: indicates the current state of the curent installation:
@itemize[ @itemize[
@item{@racket[`ok] --- You're fine.} @item{@racket[`ok] --- You're fine.}
@item{@racket[`(ok-but ,_version)] --- You have a fine stable @item{@racket[`(ok-but ,_version)] --- You have a fine stable
version, but note that there is a newer alpha version available version, but note that there is a newer alpha version available
numbered @racket[_version].} numbered @racket[_version].}
@item{@racket[`(newer ,_version)] --- You have an old @item{@racket[`(newer ,_version)] --- You have an old
version. Please upgrade to @racket[_version].} version. Please upgrade to @racket[_version].}
@item{@racket[`(newer ,_version ,_alpha)] --- You have an @item{@racket[`(newer ,_version ,_alpha)] --- You have an
old-but-stable version, please upgrade to @racket[_version]; you old-but-stable version, please upgrade to @racket[_version]; you
may consider also the newer alpha version numbered may consider also the newer alpha version numbered
@racket[_alpha].} @racket[_alpha].}
@item{@racket[`(error ,_message)] --- An error occurred, and @item{@racket[`(error ,_message)] --- An error occurred, and
@racket[_message] is a string that indicates the error.} @racket[_message] is a string that indicates the error.}
@item{@racket[`(error ,_message ,_additional-info)] --- An error @item{@racket[`(error ,_message ,_additional-info)] --- An error
occurred; @racket[_message] is a string that indicates the occurred; @racket[_message] is a string that indicates the
error, and @racket[_additional-info] is a string containing a error, and @racket[_additional-info] is a string containing a
system error. The @racket[_additional-info] content is always system error. The @racket[_additional-info] content is always
parenthesizes, so @racket[message] is a short error and parenthesizes, so @racket[message] is a short error and
@racket[(string-append message " " additional-info)] is a @racket[(string-append message " " additional-info)] is a
verbose one.} verbose one.}
] ]}
}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -80,11 +78,11 @@ The @racket[version/tool] library implements a DrRacket tool that
@itemize[ @itemize[
@item{makes the patchlevel display as a version @tt{p}@nonterm{N} @item{makes the patchlevel display as a version @tt{p}@nonterm{N}
suffix in DrRacket (though the base verion reported by suffix in DrRacket (though the base verion reported by
@racket[(version)] is not changed);} @racket[(version)] is not changed);}
@item{if enabled by the user, periodically checks whether a @item{if enabled by the user, periodically checks whether a
new Racket distribution is available for download.} new Racket distribution is available for download.}
] ]
@ -94,48 +92,41 @@ The @racket[version/tool] library implements a DrRacket tool that
@section{Version Utilities} @section{Version Utilities}
@defmodule[version/utils]{ @defmodule[version/utils]{
The @racketmodname[version/utils] library provides a few of convenient
The @racketmodname[version/utils] library provides a few of convenient utilities for dealing with version strings. Unless explicitly noted,
utilities for dealing with version strings. Unless explicitly noted, these functions do not handle legacy versions of Racket.}
these functions do not handle legacy versions of Racket.}
@defproc[(valid-version? [str string?]) boolean?]{ @defproc[(valid-version? [str string?]) boolean?]{
Returns @racket[#t] if @racket[str] is a valid Racket version
Returns @racket[#t] if @racket[str] is a valid Racket version string, @racket[#f] otherwise.}
string, @racket[#f] otherwise.}
@defproc[(version->list [str valid-version?]) @defproc[(version->list [str valid-version?])
(list integer? integer? integer? integer?)]{ (list integer? integer? integer? integer?)]{
Returns a list of four numbers that the given version string
Returns a list of four numbers that the given version string represent. @racket[str] is assumed to be a valid version.}
represent. @racket[str] is assumed to be a valid version.}
@defproc[(version<? [str1 valid-version?] [str2 valid-version?]) boolean?]{ @defproc[(version<? [str1 valid-version?] [str2 valid-version?]) boolean?]{
Returns @racket[#t] if @racket[str1] represents a version that is
Returns @racket[#t] if @racket[str1] represents a version that is strictly smaller than @racket[str2], @racket[#f] otherwise.
strictly smaller than @racket[str2], @racket[#f] otherwise. @racket[str1] and @racket[str2] are assumed to be valid versions.}
@racket[str1] and @racket[str2] are assumed to be valid versions.}
@defproc[(version<=? [str1 valid-version?] [str2 valid-version?]) boolean?]{ @defproc[(version<=? [str1 valid-version?] [str2 valid-version?]) boolean?]{
Returns @racket[#t] if @racket[str1] represents a version that is
Returns @racket[#t] if @racket[str1] represents a version that is smaller than or equal to @racket[str2], @racket[#f] otherwise.
smaller than or equal to @racket[str2], @racket[#f] otherwise. @racket[str1] and @racket[str2] are assumed to be valid versions.}
@racket[str1] and @racket[str2] are assumed to be valid versions.}
@defproc[(alpha-version? [str valid-version?]) boolean?]{ @defproc[(alpha-version? [str valid-version?]) boolean?]{
Returns @racket[#t] if the version that @racket[str] represents is an
Returns @racket[#t] if the version that @racket[str] represents is an alpha version. @racket[str] is assumed to be a valid version.}
alpha version. @racket[str] is assumed to be a valid version.}
@defproc[(version->integer [str string?]) (or/c integer? false/c)]{ @defproc[(version->integer [str string?]) (or/c integer? false/c)]{
Converts the version string into an integer. For version
@racket["X.YY.ZZZ.WWW"], the result will be @racketvalfont{XYYZZZWWW}.
This function works also for legacy Racket versions, by
translating @racket["XYY.ZZZ"] to @racketvalfont{XYYZZZ000}. The
resulting integer can thefore be used to conveniently compare any two
(valid) version strings. If the version string is invalid the
resulting value is @racket[#f].
Converts the version string into an integer. For version Note that this is the only function that deals with legacy version
@racket["X.YY.ZZZ.WWW"], the result will be @racketvalfont{XYYZZZWWW}. strings.}
This function works also for legacy Racket versions, by
translating @racket["XYY.ZZZ"] to @racketvalfont{XYYZZZ000}. The
resulting integer can thefore be used to conveniently compare any two
(valid) version strings. If the version string is invalid the
resulting value is @racket[#f].
Note that this is the only function that deals with legacy version
strings.}