add PLTUSERHOME

The new `PLTUSERHOME` environment variable redirects all of the
user-specific paths reported by `find-system-path`.

Also, improve the tests for `raco exe` (particularly the bug
fixed in 6cb6f3fbf1) using `PLTUSERHOME`.
This commit is contained in:
Matthew Flatt 2014-02-25 14:54:40 -07:00
parent 6cb6f3fbf1
commit e4ce0d0331
3 changed files with 97 additions and 68 deletions

View File

@ -53,28 +53,30 @@
(let ([plthome (getenv "PLTHOME")] (let ([plthome (getenv "PLTHOME")]
[collects (getenv "PLTCOLLECTS")] [collects (getenv "PLTCOLLECTS")]
[out (open-output-string)]) [out (open-output-string)])
(define temp-home-dir (make-temporary-file "racket-tmp-home~a" 'directory))
;; Try to hide usual collections: ;; Try to hide usual collections:
(when plthome (parameterize ([current-environment-variables
(putenv "PLTHOME" (path->string (build-path (find-system-path 'temp-dir) "NOPE")))) (environment-variables-copy
(when collects (current-environment-variables))])
(putenv "PLTCOLLECTS" (path->string (build-path (find-system-path 'temp-dir) "NOPE")))) (putenv "PLTUSERHOME" (path->string temp-home-dir))
;; Execute: (when plthome
(parameterize ([current-directory (find-system-path 'temp-dir)]) (putenv "PLTHOME" (path->string (build-path (find-system-path 'temp-dir) "NOPE"))))
(when (file-exists? "stdout") (when collects
(delete-file "stdout")) (putenv "PLTCOLLECTS" (path->string (build-path (find-system-path 'temp-dir) "NOPE"))))
(let ([path (if (and mred? (eq? 'macosx (system-type))) ;; Execute:
(let-values ([(base name dir?) (split-path exe)]) (parameterize ([current-directory (find-system-path 'temp-dir)])
(build-path exe "Contents" "MacOS" (when (file-exists? "stdout")
(path-replace-suffix name #""))) (delete-file "stdout"))
exe)]) (let ([path (if (and mred? (eq? 'macosx (system-type)))
(test #t (let-values ([(base name dir?) (split-path exe)])
path (build-path exe "Contents" "MacOS"
(parameterize ([current-output-port out]) (path-replace-suffix name #"")))
(system* path))))) exe)])
(when plthome (test #t
(putenv "PLTHOME" plthome)) path
(when collects (parameterize ([current-output-port out])
(putenv "PLTCOLLECTS" collects)) (system* path))))))
(delete-directory/files temp-home-dir)
(let ([stdout-file (build-path (find-system-path 'temp-dir) "stdout")]) (let ([stdout-file (build-path (find-system-path 'temp-dir) "stdout")])
(if (file-exists? stdout-file) (if (file-exists? stdout-file)
(test expect with-input-from-file stdout-file (test expect with-input-from-file stdout-file

View File

@ -21,17 +21,23 @@ by @racket[kind], which must be one of the following:
@itemize[ @itemize[
@item{@indexed-racket['home-dir] --- the current user's home @item{@indexed-racket['home-dir] --- the current @deftech{user's home
directory. directory}.
On Unix and Mac OS X, this directory is determined by expanding On all platforms, if the @indexed-envvar{PLTUSERHOME} environment
the path @filepath{~}, which is expanded by first checking for a variable is defined as a @tech{complete} path, then the path is used
@indexed-envvar{HOME} environment variable. If none is defined, the as the user's home directory.
@indexed-envvar{USER} and @indexed-envvar{LOGNAME} environment
On Unix and Mac OS X, when @envvar{PLTUSERHOME} does not apply,
the user's home directory is determined by
expanding the path @filepath{~}, which is expanded by first checking
for a @indexed-envvar{HOME} environment variable. If none is defined,
the @indexed-envvar{USER} and @indexed-envvar{LOGNAME} environment
variables are consulted (in that order) to find a user name, and then variables are consulted (in that order) to find a user name, and then
system files are consulted to locate the user's home directory. system files are consulted to locate the user's home directory.
On Windows, the user's home directory is the user-specific profile On Windows, when @envvar{PLTUSERHOME} does not apply,
the user's home directory is the user-specific profile
directory as determined by the Windows registry. If the registry directory as determined by the Windows registry. If the registry
cannot provide a directory for some reason, the value of the cannot provide a directory for some reason, the value of the
@indexed-envvar{USERPROFILE} environment variable is used instead, as @indexed-envvar{USERPROFILE} environment variable is used instead, as
@ -44,12 +50,14 @@ by @racket[kind], which must be one of the following:
@item{@indexed-racket['pref-dir] --- the standard directory for @item{@indexed-racket['pref-dir] --- the standard directory for
storing the current user's preferences. On Unix, the directory is storing the current user's preferences. On Unix, the directory is
@filepath{.racket} in the user's home directory. On Windows, it @filepath{.racket} in the @tech{user's home directory}. On Windows,
is @filepath{Racket} in the user's application-data folder as it is @filepath{Racket} in the @tech{user's home directory} if
specified by the Windows registry; the application-data folder is determined by @envvar{PLTUSERHOME}, otherwise in the user's
usually @filepath{Application Data} in the user's profile application-data folder as specified by the Windows registry; the
directory. On Mac OS X, it is @filepath{Library/Preferences} in the application-data folder is usually @filepath{Application Data} in the
user's home directory. This directory might not exist.} user's profile directory. On Mac OS X, the preferences directory
is @filepath{Library/Preferences} in the
@tech{user's home directory}. The preferences directory might not exist.}
@item{@indexed-racket['pref-file] --- a file that contains a @item{@indexed-racket['pref-file] --- a file that contains a
symbol-keyed association list of preference values. The file's symbol-keyed association list of preference values. The file's
@ -70,7 +78,7 @@ by @racket[kind], which must be one of the following:
@item{@indexed-racket['init-dir] --- the directory containing the @item{@indexed-racket['init-dir] --- the directory containing the
initialization file used by the Racket executable. initialization file used by the Racket executable.
It is the same as the current user's home directory.} It is the same as the @tech{user's home directory}.}
@item{@indexed-racket['init-file] --- the file loaded at start-up by @item{@indexed-racket['init-file] --- the file loaded at start-up by
the Racket executable. The directory part of the the Racket executable. The directory part of the
@ -103,24 +111,26 @@ by @racket[kind], which must be one of the following:
overridden by the @DFlag{addon} or @Flag{A} command-line flag. If no overridden by the @DFlag{addon} or @Flag{A} command-line flag. If no
environment variable or flag is specified, or if the value is not a environment variable or flag is specified, or if the value is not a
legal path name, then this directory defaults to legal path name, then this directory defaults to
@filepath{Library/Racket} in the user's home directory on Mac @filepath{Library/Racket} in the @tech{user's home directory} on Mac
OS X and @racket['pref-dir] otherwise. The directory might not OS X and @racket['pref-dir] otherwise. The directory might not
exist.} exist.}
@item{@indexed-racket['doc-dir] --- the standard directory for @item{@indexed-racket['doc-dir] --- the standard directory for
storing the current user's documents. On Unix, it's the same as storing the current user's documents. On Unix, it's
@racket['home-dir]. On Mac OS X, it's the the @tech{user's home directory}. On Windows, it is the @tech{user's
@filepath{Documents} directory in the user's home directory. On home directory} if determined by @envvar{PLTUSERHOME}, otherwise it
Windows, it is the user's documents folder as specified by the is the user's documents folder as specified by the Windows registry;
Windows registry; the documents folder is usually @filepath{My Documents} the documents folder is usually @filepath{My Documents} in the user's
in the user's home directory.} home directory. On Mac OS X, it's the @filepath{Documents} directory
in the @tech{user's home directory}.}
@item{@indexed-racket['desk-dir] --- the directory for the current user's @item{@indexed-racket['desk-dir] --- the directory for the current user's
desktop. On Unix, it's the same as @racket['home-dir]. On desktop. On Unix, it's the @tech{user's home directory}. On
Windows, it is the user's desktop folder as specified by the Windows Windows, it is the @tech{user's home directory} if determined by
registry; the documents folder is usually @filepath{Desktop} in the @envvar{PLTUSERHOME}, otherwise it is the user's desktop folder as
user's home directory. On Mac OS X, it is the desktop directory, specified by the Windows registry; the desktop folder is usually
which is specifically @filepath{~/Desktop} on Mac OS X.} @filepath{Desktop} in the user's home directory. On Mac OS X, it is
@filepath{Desktop} in the @tech{user's home directory}}
@item{@indexed-racket['sys-dir] --- the directory containing the @item{@indexed-racket['sys-dir] --- the directory containing the
operating system for Windows. On @|AllUnix|, the operating system for Windows. On @|AllUnix|, the
@ -157,7 +167,9 @@ by @racket[kind], which must be one of the following:
from @racket[(find-system-path 'exec-file)] or from @racket[(find-system-path 'exec-file)] or
@racket[(find-system-path 'run-file)] to a complete path.} @racket[(find-system-path 'run-file)] to a complete path.}
]} ]
@history[#:changed "6.0.0.3" @elem{Added @envvar{PLTUSERHOME}.}]}
@defproc[(path-list-string->path-list [str (or/c string? bytes?)] @defproc[(path-list-string->path-list [str (or/c string? bytes?)]
[default-path-list (listof path?)]) [default-path-list (listof path?)])

View File

@ -6272,9 +6272,12 @@ find_system_path(int argc, Scheme_Object **argv)
{ {
/* Everything else is in ~: */ /* Everything else is in ~: */
Scheme_Object *home; Scheme_Object *home;
char *home_str, *ex_home; char *home_str, *ex_home, *alt_home;
int ends_in_slash; int ends_in_slash;
/* cast here avoids a clang warning: */
# define mz_STR_OFFSET(s, d) ((const char *)s XFORM_OK_PLUS d)
if ((which == id_pref_dir) if ((which == id_pref_dir)
|| (which == id_pref_file) || (which == id_pref_file)
|| (which == id_addon_dir)) { || (which == id_addon_dir)) {
@ -6297,18 +6300,29 @@ find_system_path(int argc, Scheme_Object **argv)
home_str = "~/"; home_str = "~/";
} }
ex_home = do_expand_filename(NULL, home_str, strlen(home_str), NULL, alt_home = getenv("PLTUSERHOME");
NULL, if (alt_home && scheme_is_complete_path(alt_home, strlen(alt_home), SCHEME_PLATFORM_PATH_KIND)) {
0, 1, home = scheme_make_path(alt_home);
0, SCHEME_UNIX_PATH_KIND, if (home_str[2]) {
1); Scheme_Object *a[2];
a[0] = home;
if (!ex_home) { a[1] = scheme_make_path(mz_STR_OFFSET(home_str, 2));
/* Something went wrong with the user lookup. Just drop "~'. */ home = scheme_build_path(2, a);
home = scheme_make_sized_offset_path(home_str, 1, -1, 1); } else
} else home = scheme_path_to_directory_path(home);
home = scheme_make_path(ex_home); } else {
ex_home = do_expand_filename(NULL, home_str, strlen(home_str), NULL,
NULL,
0, 1,
0, SCHEME_UNIX_PATH_KIND,
1);
if (!ex_home) {
/* Something went wrong with the user lookup. Just drop "~'. */
home = scheme_make_sized_offset_path(home_str, 1, -1, 1);
} else
home = scheme_make_path(ex_home);
}
if ((which == id_pref_dir) || (which == id_init_dir) if ((which == id_pref_dir) || (which == id_init_dir)
|| (which == id_home_dir) || (which == id_addon_dir) || (which == id_home_dir) || (which == id_addon_dir)
@ -6317,9 +6331,6 @@ find_system_path(int argc, Scheme_Object **argv)
ends_in_slash = (SCHEME_PATH_VAL(home))[SCHEME_PATH_LEN(home) - 1] == '/'; ends_in_slash = (SCHEME_PATH_VAL(home))[SCHEME_PATH_LEN(home) - 1] == '/';
/* cast here avoids a clang warning: */
# define mz_STR_OFFSET(s, d) ((const char *)s + d)
if (which == id_init_file) if (which == id_init_file)
return append_path(home, scheme_make_path(mz_STR_OFFSET("/.racketrc", ends_in_slash))); return append_path(home, scheme_make_path(mz_STR_OFFSET("/.racketrc", ends_in_slash)));
if (which == id_pref_file) { if (which == id_pref_file) {
@ -6359,7 +6370,11 @@ find_system_path(int argc, Scheme_Object **argv)
home = NULL; home = NULL;
{ p = getenv("PLTUSERHOME");
if (p && scheme_is_complete_path(p, strlen(p), SCHEME_PLATFORM_PATH_KIND))
home = scheme_path_to_directory_path(scheme_make_path(p));
if (!home) {
/* Try to get Application Data directory: */ /* Try to get Application Data directory: */
LPITEMIDLIST items; LPITEMIDLIST items;
int which_folder; int which_folder;