www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5de41c4bc1e9ac8029ad9db819392b2c2f1d5630
parent a80e62d9b150dbc8571310eb9786f157915de69b
Author: Matthew Flatt <mflatt@racket-lang.org>
Date:   Sun, 10 Nov 2013 12:17:01 -0700

make installers: support Mac OS X ".pkg" format

The ".pkg"-based installer doesn't provide the option of picking
an installation path, but it can add a path in "/etc/paths.d"
so that users do not have to explicitly set the `PATH` environment
variable.

original commit: 7dd10fc9bd35d8cf10d26c50e4489f9bd6922b53

Diffstat:
Mpkgs/distro-build/config.rkt | 1+
Mpkgs/distro-build/doc.txt | 5++++-
Mpkgs/distro-build/drive-clients.rkt | 2++
Apkgs/distro-build/installer-pkg.rkt | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkgs/distro-build/installer.rkt | 9++++++++-
Apkgs/distro-build/macosx-installer/pkg-bg.png | 0
Mpkgs/distro-build/readme.rkt | 24+++++++++++++++++-------
7 files changed, 166 insertions(+), 9 deletions(-)

diff --git a/pkgs/distro-build/config.rkt b/pkgs/distro-build/config.rkt @@ -145,6 +145,7 @@ [(#:source?) (boolean? val)] [(#:source-runtime?) (boolean? val)] [(#:source-pkgs?) (boolean? val)] + [(#:mac-pkg?) (boolean? val)] [(#:site-dest) (path-string? val)] [(#:pdf-doc?) (boolean? val)] [(#:max-snapshots) (real? val)] diff --git a/pkgs/distro-build/doc.txt b/pkgs/distro-build/doc.txt @@ -244,7 +244,7 @@ Site-configuration keywords (where <string*> means no spaces, etc.): makefile variable #:source? <boolean> --- determines the default value for - `#:source-runtime' and `#:source-pkgs' + `#:source-runtime?' and `#:source-pkgs' #:source-runtime? <boolean> --- if true, then create an archive that contains the run-time system in source form (possibly with built @@ -258,6 +258,9 @@ Site-configuration keywords (where <string*> means no spaces, etc.): when the `#:source-runtime?' value is also #t; the default is the value of `#:source?' + #:mac-pkg? --- if true, creates a ".pkg" for Mac OS X (in + single-file format) instead of a ".dmg"; the default is #f + #:max-snapshots <number> --- number of snapshots to keep, used by the `snapshot-site' makefile target diff --git a/pkgs/distro-build/drive-clients.rkt b/pkgs/distro-build/drive-clients.rkt @@ -277,6 +277,7 @@ (define source? (get-opt c '#:source? #f)) (define source-pkgs? (get-opt c '#:source-pkgs? source?)) (define source-runtime? (get-opt c '#:source-runtime? source?)) + (define mac-pkg? (get-opt c '#:mac-pkg? #f)) (define install-name (get-opt c '#:install-name (if release? "" snapshot-install-name))) @@ -301,6 +302,7 @@ " PKG_SOURCE_MODE=" (if source-pkgs? (q "--source --no-setup") (q "")) + " MAC_PKG_MODE=" (if mac-pkg? "--mac-pkg" (q "")) " README=" (q (file-name-from-path readme)))) (define (unix-build c platform host port user server server-port repo clean? pull? readme) diff --git a/pkgs/distro-build/installer-pkg.rkt b/pkgs/distro-build/installer-pkg.rkt @@ -0,0 +1,134 @@ +#lang at-exp racket/base +(require racket/system + racket/file + racket/format + racket/runtime-path + ds-store + ds-store/alias + xml) + +(provide installer-pkg) + +(define pkgbuild "/usr/bin/pkgbuild") +(define productbuild "/usr/bin/productbuild") + +(define-runtime-path bg-image "macosx-installer/pkg-bg.png") + +(define (system*/show . l) + (displayln (apply ~a #:separator " " l)) + (flush-output) + (unless (apply system* l) + (error "failed"))) + +(define (gen-install-script install-dest) + (~a "#!/bin/sh\n" + "echo \"" (regexp-replace* #rx"\"" + install-dest + "\"'\"'\"") + "\"/bin > /etc/paths.d/racket\n")) + +(define (make-pkg human-name src-dir pkg-name readme sign-identity) + (define install-dest (string-append "/Applications/" human-name)) + (define id (string-append "org.racket-lang." + (regexp-replace* #rx" " + human-name + "-"))) + + (define (make-rel dir-name) + (let-values ([(base name dir?) (split-path src-dir)]) + (build-path base dir-name))) + + (define work-dir (make-rel "work")) + (delete-directory/files work-dir #:must-exist? #f) + (define scripts-dir (make-rel "scripts")) + (delete-directory/files scripts-dir #:must-exist? #f) + (define resources-dir (make-rel "resources")) + (delete-directory/files resources-dir #:must-exist? #f) + + (printf "Creating ~a\n" scripts-dir) + (make-directory* scripts-dir) + (define postinstall (build-path scripts-dir "postinstall")) + (call-with-output-file* + postinstall + (lambda (o) + (write-string (gen-install-script install-dest) o))) + (file-or-directory-permissions postinstall #o770) + + (printf "Creating ~a\n" resources-dir) + (make-directory* resources-dir) + (copy-file bg-image (build-path resources-dir "background.png")) + + (printf "Copying ~a\n" src-dir) + (define dest-dir work-dir) + (copy-directory/files src-dir dest-dir + #:keep-modify-seconds? #t) + (when readme + (call-with-output-file* + (build-path dest-dir "README.txt") + #:exists 'truncate + (lambda (o) + (display readme o)))) + (copy-file (build-path dest-dir "README.txt") + (build-path resources-dir "README.txt")) + + (apply system*/show + pkgbuild + (append + (list "--root" dest-dir + "--install-location" install-dest + "--scripts" scripts-dir + "--identifier" id + "--version" (version)) + (if (string=? sign-identity "") + null + (list "--sign" sign-identity)) + (list (make-rel "racket.pkg")))) + (define pkg-xml (make-rel "racket.xml")) + (system*/show productbuild + "--synthesize" + "--package" (make-rel "racket.pkg") + pkg-xml) + (define synthesized (call-with-input-file* + pkg-xml + read-xml)) + (define updated + (struct-copy document synthesized + [element (let ([e (document-element synthesized)]) + (struct-copy element e + [content + (list* + (element #f #f + 'title + null + (list (pcdata #f #f human-name))) + (element #f #f + 'readme + (list (attribute #f #f 'file "README.txt")) + null) + (element #f #f + 'background + (list (attribute #f #f 'file "background.png") + (attribute #f #f 'alignment "topleft") + (attribute #f #f 'scaling "none")) + null) + (element-content e))]))])) + (call-with-output-file* + pkg-xml + #:exists 'truncate + (lambda (o) + (write-xml updated o))) + (system*/show productbuild + "--distribution" pkg-xml + "--package-path" (make-rel 'same) + "--resources" resources-dir + "--identifier" id + "--version" (version) + pkg-name)) + +(define (installer-pkg human-name base-name dist-suffix readme sign-identity) + (define pkg-name (format "bundle/~a-~a~a.pkg" + base-name + (system-library-subpath #f) + dist-suffix)) + (make-pkg human-name "bundle/racket" pkg-name readme sign-identity) + pkg-name) diff --git a/pkgs/distro-build/installer.rkt b/pkgs/distro-build/installer.rkt @@ -2,6 +2,7 @@ (require racket/cmdline "installer-sh.rkt" "installer-dmg.rkt" + "installer-pkg.rkt" "installer-exe.rkt" "installer-tgz.rkt" net/url @@ -12,6 +13,7 @@ (define release? #f) (define source? #f) +(define mac-pkg? #f) (define upload-to #f) (define upload-desc "") (define download-readme #f) @@ -23,6 +25,8 @@ (set! release? #t)] [("--source") "Create a source installer" (set! source? #t)] + [("--mac-pkg") "Create a \".pkg\" installer on Mac OS X" + (set! mac-pkg? #t)] [("--upload") url "Upload installer" (set! upload-to url)] [("--desc") desc "Description to accompany upload" @@ -58,7 +62,10 @@ (installer-tgz base-name dir-name dist-suffix readme) (case (system-type) [(unix) (installer-sh human-name base-name dir-name release? dist-suffix readme)] - [(macosx) (installer-dmg human-name base-name dist-suffix readme sign-identity)] + [(macosx) (if mac-pkg? + (installer-pkg (if release? short-human-name human-name) + base-name dist-suffix readme sign-identity) + (installer-dmg human-name base-name dist-suffix readme sign-identity))] [(windows) (installer-exe short-human-name base-name release? dist-suffix readme)]))) (call-with-output-file* diff --git a/pkgs/distro-build/macosx-installer/pkg-bg.png b/pkgs/distro-build/macosx-installer/pkg-bg.png Binary files differ. diff --git a/pkgs/distro-build/readme.rkt b/pkgs/distro-build/readme.rkt @@ -105,10 +105,20 @@ @~a{The distribution includes any pre-installed packages in source form.}])) (define (make-macosx-notes config) - @~a{Install by dragging the enclosing - @|(hash-ref config '#:dist-name "Racket")| v@(version) - folder to your Applications folder --- or wherever you like. You can - move the folder at any time, but do not move applications or other - files within the folder. If you want to use the Racket command-line - programs, then (optionally) add the path of the "bin" subdirectory to - your PATH environment variable.}) + (if (hash-ref config '#:mac-pkg? #f) + @~a{The installation directory is + /Applications/@(string-append + (hash-ref config '#:dist-name "Racket") + (if (hash-ref config '#:release? #f) + "" + (string-append " v" (version)))) + The installer also adjusts "/etc/paths.d/racket" to point to that + directory's "bin" directory, which adjusts the default PATH + environment variable for all users.} + @~a{Install by dragging the enclosing + @|(hash-ref config '#:dist-name "Racket")| v@(version) + folder to your Applications folder --- or wherever you like. You can + move the folder at any time, but do not move applications or other + files within the folder. If you want to use the Racket command-line + programs, then (optionally) add the path of the "bin" subdirectory to + your PATH environment variable.}))