diff --git a/Makefile b/Makefile index e3e9d035a5..a22aa48355 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,10 @@ DIST_DESC = # installers, where "" is replaced by the default configuration: DIST_CATALOGS_q = "" +# An identifier for this build; if not specified, a build identifier +# is inferred from the date and git repository +BUILD_STAMP = + # "Name" of the installation used for `user' package scope by default # in an installation from an installer, where an empty value leaves # the default as the version number: @@ -226,6 +230,10 @@ build/site.rkt: echo "(machine)" >> build/site.rkt stamp: + if [ "$(BUILD_STAMP)" = '' ] ; then $(MAKE) stamp-as-inferred ; else $(MAKE) stamp-as-given ; fi +stamp-as-given: + echo "$(BUILD_STAMP)" > build/stamp.txt +stamp-as-inferred: if [ -d ".git" ] ; then $(MAKE) stamp-from-git ; else $(MAKE) stamp-from-date ; fi stamp-from-git: echo `date +"%Y%m%d"`-`git log -1 --pretty=format:%h` > build/stamp.txt @@ -276,7 +284,7 @@ fresh-user: rm -rf build/user set-config: - $(RACKET) -l distro-build/set-config racket/etc/config.rktd $(CONFIG_MODE_q) "$(DOC_SEARCH)" "" "" + $(RACKET) -l distro-build/set-config racket/etc/config.rktd $(CONFIG_MODE_q) "$(DOC_SEARCH)" "" "" "" # Install packages from the source copies in this directory. The # packages are installed in user scope, but we set the add-on @@ -344,7 +352,7 @@ client: $(MAKE) bundle-config $(MAKE) installer-from-bundle -COPY_ARGS = SERVER=$(SERVER) PKGS="$(PKGS)" \ +COPY_ARGS = SERVER=$(SERVER) PKGS="$(PKGS)" BUILD_STAMP="$(BUILD_STAMP)" \ RELEASE_MODE=$(RELEASE_MODE) SOURCE_MODE=$(SOURCE_MODE) \ PKG_SOURCE_MODE=$(PKG_SOURCE_MODE) INSTALL_NAME="$(INSTALL_NAME)"\ DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \ @@ -352,7 +360,7 @@ COPY_ARGS = SERVER=$(SERVER) PKGS="$(PKGS)" \ DIST_DESC="$(DIST_DESC)" README="$(README)" \ JOB_OPTIONS="$(JOB_OPTIONS)" -SET_BUNDLE_CONFIG_q = $(BUNDLE_CONFIG) "" "" "$(INSTALL_NAME)" "$(DOC_SEARCH)" $(DIST_CATALOGS_q) +SET_BUNDLE_CONFIG_q = $(BUNDLE_CONFIG) "" "" "$(INSTALL_NAME)" "$(BUILD_STAMP)" "$(DOC_SEARCH)" $(DIST_CATALOGS_q) win32-client: IF EXIST build\user cmd /c rmdir /S /Q build\user diff --git a/pkgs/distro-build/config.rkt b/pkgs/distro-build/config.rkt index 9bd9a96472..09e7973968 100644 --- a/pkgs/distro-build/config.rkt +++ b/pkgs/distro-build/config.rkt @@ -121,6 +121,7 @@ [(#:dist-catalogs) (and (list? val) (andmap string? val))] [(#:dist-base-url) (string? val)] [(#:install-name) (string? val)] + [(#:build-stamp) (string? val)] [(#:max-vm) (real? val)] [(#:server) (simple-string? val)] [(#:host) (simple-string? val)] diff --git a/pkgs/distro-build/doc.txt b/pkgs/distro-build/doc.txt index 9f9360d208..1daefe6897 100644 --- a/pkgs/distro-build/doc.txt +++ b/pkgs/distro-build/doc.txt @@ -146,6 +146,11 @@ Site-configuration keywords (where means no spaces, etc.): where "" keeps the name as the Racket version; the default is "snapshot" if the value of `#:release?' is false, "" otherwise. + #:build-stamp --- a string representing a build stamp, + recorded in installes; the default is from the `BUILD_STAMP' + makefile variable or generated if the value of `#:release?' is + false, "" otherwise. + #:dist-name --- the distribution name; defaults to the `DIST_NAME' makefile variable diff --git a/pkgs/distro-build/drive-clients.rkt b/pkgs/distro-build/drive-clients.rkt index 7db5bb0572..c0ed0a744c 100644 --- a/pkgs/distro-build/drive-clients.rkt +++ b/pkgs/distro-build/drive-clients.rkt @@ -9,7 +9,8 @@ (only-in "config.rkt" current-mode site-config? - site-config-tag site-config-options site-config-content) + site-config-tag site-config-options site-config-content + current-stamp) "url-options.rkt" "display-time.rkt" "readme.rkt") @@ -257,6 +258,9 @@ (define install-name (get-opt c '#:install-name (if release? "" snapshot-install-name))) + (define build-stamp (get-opt c '#:build-stamp (if release? + "" + (current-stamp)))) (~a " SERVER=" server " PKGS=" (q pkgs) " DOC_SEARCH=" (q doc-search) @@ -267,6 +271,7 @@ " DIST_SUFFIX=" (q dist-suffix) " DIST_CATALOGS_q=" (qq dist-catalogs kind) " INSTALL_NAME=" (q install-name) + " BUILD_STAMP=" (q build-stamp) " RELEASE_MODE=" (if release? "--release" (q "")) " SOURCE_MODE=" (if source-runtime? "--source" (q "")) " PKG_SOURCE_MODE=" (if source-pkgs? @@ -343,7 +348,10 @@ '#:pkgs (string-split default-pkgs) '#:install-name (if (get-opt c '#:release? default-release?) "" - snapshot-install-name)))))) + snapshot-install-name) + '#:build-stamp (if (get-opt c '#:release? default-release?) + "" + (current-stamp))))))) (make-directory* (build-path "build" "readmes")) (define readme (make-temporary-file "README-~a" diff --git a/pkgs/distro-build/set-config.rkt b/pkgs/distro-build/set-config.rkt index eea6620100..d98d65b99b 100644 --- a/pkgs/distro-build/set-config.rkt +++ b/pkgs/distro-build/set-config.rkt @@ -6,13 +6,15 @@ "url-options.rkt") (define-values (dest-config-file config-file config-mode - install-name + install-name build-stamp default-doc-search default-catalogs) (command-line #:args - (dest-config-file config-file config-mode install-name doc-search . catalog) + (dest-config-file config-file config-mode + install-name build-stamp + doc-search . catalog) (values dest-config-file config-file config-mode - install-name + install-name build-stamp doc-search catalog))) (define config (if (equal? config-file "") @@ -42,7 +44,10 @@ c))))] [table (if (equal? install-name "") table - (hash-set table 'installation-name install-name))]) + (hash-set table 'installation-name install-name))] + [table (if (equal? build-stamp "") + table + (hash-set table 'build-stamp build-stamp))]) (unless (equal? table orig) (make-directory* (path-only dest-config-file)) (call-with-output-file dest-config-file diff --git a/pkgs/drracket-pkgs/drracket/repo-time-stamp/.gitattributes b/pkgs/drracket-pkgs/drracket/repo-time-stamp/.gitattributes deleted file mode 100644 index 9cdb23de2e..0000000000 --- a/pkgs/drracket-pkgs/drracket/repo-time-stamp/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -/stamp.rkt ident export-subst diff --git a/pkgs/drracket-pkgs/drracket/repo-time-stamp/stamp.rkt b/pkgs/drracket-pkgs/drracket/repo-time-stamp/stamp.rkt index d9df32f7a1..e8165a51d2 100644 --- a/pkgs/drracket-pkgs/drracket/repo-time-stamp/stamp.rkt +++ b/pkgs/drracket-pkgs/drracket/repo-time-stamp/stamp.rkt @@ -5,21 +5,24 @@ #| This file provides a single binding, `stamp', with a string value that - describes the Racket version. The format of this stamp is a date, a - SHA1, and a character describing how the information was retrieved: + describes the Racket version, or #f to indicate a "release" without a + stamp. + + The format of a string stamp is a date, a SHA1, and a character + describing how the information was retrieved: "YYYY-MM-DD(SHA1/H)" The description is attempted in several ways, with the `H' character indicating how it was actually obtained: - * "a" -- the date and sha1 information were in the `archive-id' string - below, which means that it had that information at the time that - `git archive' created an archive out of a git repository. This is - the expected value for nightly builds. + * "a" -- the date and sha1 information were in the installation's + configuration (as a non-empty string). This is the expected value + for a snapshot build, and if the installation's configuration has + a `build-stamp' entry, this format or #f are the only possibilities. * "g" -- `archive-id' didn't have information, but we found a git - executable and ran it. [*] + executable and ran it. [*] This strategy is currently disabled. * "d" -- an executable was not found either, but a ".git" directory was found in the usual place, with a "HEAD" file that has eventually @@ -36,19 +39,34 @@ |# -(define archive-id "$Format:%ct|%h|a$") -;; when exported through `git archive', the above becomes something like -;; "1273562690|cabd414|a" - -(require racket/system racket/runtime-path racket/string) +(require racket/system + racket/runtime-path + racket/string + racket/date + setup/dirs) (define-runtime-path this-dir ".") (define-runtime-path this-file "stamp.rkt") -(define stamp +(define (compute-stamp) (let ([rx:secs+id #rx"^([0-9]+)\\|([0-9a-f]+|-)\\|(.*?)[ \r\n]*$"]) ;; info from an archive (incl. nightly builds) - (define (from-archive-id) archive-id) + (define (from-archive-id) + (define m (regexp-match #rx"^([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])-([0-9a-f]+)$" + (or (get-build-stamp) ""))) + (define (n pos) (string->number (list-ref m pos))) + (and m + (format "~a|~a|a" + (with-handlers ([exn:fail? (lambda (exn) + ;; Last resort: + (current-seconds))]) + (with-handlers ([exn:fail? (lambda (exn) + ;; Local time failed; try UTC: + (find-seconds 0 0 12 (n 3) (n 2) (n 1) #f))]) + ;; Convert to seconds, hopfully for round-trip in seconds->date + ;; conversion below: + (find-seconds 0 0 12 (n 3) (n 2) (n 1)))) + (list-ref m 4)))) ;; adds a branch name if applicable (and if different from `master') (define (add-branch str br*) (define br @@ -76,7 +94,7 @@ ;; try to find a ".git" directory (can't run git, so conventional ;; guess) and use the sha1 from that file and its date (define (from-git-dir) - (define git-dir (build-path this-dir 'up 'up ".git")) + (define git-dir (build-path this-dir 'up 'up 'up 'up ".git")) (define branch #f) (let loop ([file (build-path git-dir "HEAD")]) (define l (and (file-exists? file) @@ -106,3 +124,11 @@ (and d (format "~a-~a-~a(~a/~a)" (date-year d) (pad02 date-month) (pad02 date-day) id how)))))) + +(define stamp + (if (equal? "" (get-build-stamp)) + ;; Release + #f + ;; Compute it: + (compute-stamp))) +stamp \ No newline at end of file diff --git a/pkgs/drracket-pkgs/drracket/repo-time-stamp/time-stamp.rkt b/pkgs/drracket-pkgs/drracket/repo-time-stamp/time-stamp.rkt index 1b87e87d4b..5161c4f74d 100644 --- a/pkgs/drracket-pkgs/drracket/repo-time-stamp/time-stamp.rkt +++ b/pkgs/drracket-pkgs/drracket/repo-time-stamp/time-stamp.rkt @@ -6,4 +6,5 @@ (unit (import drscheme:tool^) (export drscheme:tool-exports^) (define (phase1) (void)) (define (phase2) (void)) - (version:add-spec '-- stamp))) + (when stamp + (version:add-spec '-- stamp)))) diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/raco/config.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/raco/config.scrbl index b6088c1ce2..e569a3e7ae 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/raco/config.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/raco/config.scrbl @@ -18,93 +18,98 @@ other directories, but use the @racketmodname[setup/dirs] library (which combines information from the configuration files and other sources) to locate configured directories. -A @filepath{config.rktd} file in the configuration directory should +A @as-index{@filepath{config.rktd}} file in the configuration directory should contain a @racket[read]able hash table with any of the following symbolic keys, where an relative path is relative to the main collection directory: @itemlist[ - @item{@racket['doc-dir] --- a path, string, or byte string for the + @item{@indexed-racket['doc-dir] --- a path, string, or byte string for the main documentation directory. The value defaults to a @filepath{doc} sibling directory of the main collection directory.} - @item{@racket['lib-dir] --- a path, string, or byte string for the + @item{@indexed-racket['lib-dir] --- a path, string, or byte string for the main library directory; it defaults to a @filepath{lib} sibling directory of the main collection directory.} - @item{@racket['lib-search-dirs] --- a list of paths, strings, byte + @item{@indexed-racket['lib-search-dirs] --- a list of paths, strings, byte strings, or @racket[#f] representing the search path for directories containing foreign libraries; each @racket[#f] in the list, if any, is replaced with the default search path, which is the user- and version-specific @filepath{lib} directory followed by the main library directory.} - @item{@racket['dll-dir] --- a path, string, or byte string for a + @item{@indexed-racket['dll-dir] --- a path, string, or byte string for a directory containing shared libraries for the main executable; it defaults to the main library directory.} - @item{@racket['share-dir] --- a path, string, or byte string for the + @item{@indexed-racket['share-dir] --- a path, string, or byte string for the main shared-file directory, which normally includes installed packages; it defaults to a @filepath{share} sibling directory of the main collection directory.} - @item{@racket['links-file] --- a path, string, or byte string for the + @item{@indexed-racket['links-file] --- a path, string, or byte string for the @tech[#:doc reference-doc]{collection links file}; it defaults to a @filepath{links.rktd} file in the @filepath{share} sibling of the main collection directory.} - @item{@racket['links-search-files] --- like @racket['lib-search-dirs], + @item{@indexed-racket['links-search-files] --- like @racket['lib-search-dirs], but for @tech[#:doc reference-doc]{collection links file}.} - @item{@racket['pkgs-dir] --- a path, string, or byte string for + @item{@indexed-racket['pkgs-dir] --- a path, string, or byte string for packages that have installation scope; it defaults to @filepath{pkgs} in the main shared-file directory.} - @item{@racket['pkgs-search-dirs] --- like @racket['lib-search-dirs], + @item{@indexed-racket['pkgs-search-dirs] --- like @racket['lib-search-dirs], but for packages in installation scope.} - @item{@racket['bin-dir] --- a path, string, or byte string for the + @item{@indexed-racket['bin-dir] --- a path, string, or byte string for the main directory containing executables; it defaults to a @filepath{bin} sibling directory of the main collection directory.} - @item{@racket['doc-search-dirs] --- like @racket['lib-search-dirs], + @item{@indexed-racket['doc-search-dirs] --- like @racket['lib-search-dirs], but for directories containing documentation.} - @item{@racket['include-dir] --- a path, string, or byte string for + @item{@indexed-racket['include-dir] --- a path, string, or byte string for the main directory containing C header files; it defaults to an @filepath{include} sibling directory of the main collection directory.} - @item{@racket['include-search-dirs] --- like + @item{@indexed-racket['include-search-dirs] --- like @racket[doc-search-dirs], but for directories containing C header files.} - @item{@racket['doc-search-url] --- a URL string that is augmented + @item{@indexed-racket['doc-search-url] --- a URL string that is augmented with version and search-tag queries to form a remote documentation reference.} - @item{@racket['installation-name] --- a string for the installation + @item{@indexed-racket['installation-name] --- a string for the installation name, which is used for packages in @exec{user} @tech[#:doc '(lib "pkg/scribblings/pkg.scrbl")]{package scope}; the default is @racket[(version)].} - @item{@racket['catalogs] --- a list of URL strings used as the search + @item{@indexed-racket['build-stamp] --- a string that identifies a build, + which can be used to augment the Racket version number to more + specifically identify the build. An empty string is normally + appropriate for a release build.} + + @item{@indexed-racket['catalogs] --- a list of URL strings used as the search path for resolving package names; an @racket[#f] in the list is replaced with the default search path.} - @item{@racket['default-scope] --- either @racket["user"] or + @item{@indexed-racket['default-scope] --- either @racket["user"] or @racket["installation"], determining the default @tech[#:doc '(lib "pkg/scribblings/pkg.scrbl")]{package scope} for package-management operations.} - @item{@racket['absolute-installation?] --- a boolean that is + @item{@indexed-racket['absolute-installation?] --- a boolean that is @racket[#t] if the installation uses absolute path names, @racket[#f] otherwise.} - @item{@racket['cgc-suffix] --- a string used as the suffix (before + @item{@indexed-racket['cgc-suffix] --- a string used as the suffix (before the actual suffix, such as @filepath{.exe}) for a @filepath{CGC} executable. Use Windows-style casing, and the string will be downcased as appropriate (e.g., for a Unix @@ -112,7 +117,7 @@ directory: @exec{racket} binary identifies itself as CGC, then the suffix is @racket[""], otherwise it is @racket["CGC"].} - @item{@racket['3m-suffix] --- analogous to @racket['cgc-suffix], but + @item{@indexed-racket['3m-suffix] --- analogous to @racket['cgc-suffix], but for 3m. A @racket[#f] value means that if the @filepath{racket} binary identifies itself as CGC, then the suffix is @racket["3m"], otherwise it is @racket[""].} diff --git a/pkgs/racket-pkgs/racket-doc/scribblings/raco/setup.scrbl b/pkgs/racket-pkgs/racket-doc/scribblings/raco/setup.scrbl index 0beef4048e..8bd60dccef 100644 --- a/pkgs/racket-pkgs/racket-doc/scribblings/raco/setup.scrbl +++ b/pkgs/racket-pkgs/racket-doc/scribblings/raco/setup.scrbl @@ -1104,6 +1104,12 @@ v configured via @racket['installation-name] in @filepath{config.rktd} (see @secref["config-file"]).} +@defproc[(get-build-stamp) (or/c #f string?)]{ Returns a string + that identifies an installation build, which can be used to augment + the Racket version number to more specifically identify the + build. An empty string is normally produced for a release build. + The result is @racket[#f] if no build stamp is available.} + @defthing[absolute-installation? boolean?]{ A binary boolean flag that is true if this installation is using absolute path names.} diff --git a/racket/collects/setup/dirs.rkt b/racket/collects/setup/dirs.rkt index 417e47d7a7..fa8c0a4bbd 100644 --- a/racket/collects/setup/dirs.rkt +++ b/racket/collects/setup/dirs.rkt @@ -85,12 +85,14 @@ (define-config config:absolute-installation? 'absolute-installation? (lambda (x) (and x #t))) (define-config config:doc-search-url 'doc-search-url values) (define-config config:installation-name 'installation-name values) +(define-config config:build-stamp 'build-stamp values) (provide get-absolute-installation? get-cgc-suffix get-3m-suffix get-doc-search-url - get-installation-name) + get-installation-name + get-build-stamp) (define (get-absolute-installation?) (force config:absolute-installation?)) (define (get-cgc-suffix) (force config:cgc-suffix)) @@ -99,6 +101,7 @@ "http://docs.racket-lang.org")) (define (get-installation-name) (or (force config:installation-name) (version))) +(define (get-build-stamp) (force config:build-stamp)) ;; ---------------------------------------- ;; "collects"