@@ -59,6 +59,10 @@ install_pkg_cli_apps <- function(
5959 dir.create(destdir , recursive = TRUE ) ||
6060 stop(" Failed to create directory: " , destdir )
6161
62+ if (is_windows()) {
63+ ensure_path_windows(destdir )
64+ }
65+
6266 existing <- list_existing_rapp_launchers(destdir )
6367
6468 names(package ) <- package
@@ -120,38 +124,40 @@ list_package_apps <- function(package, lib.loc = NULL) {
120124
121125
122126rapp_install_dir <- function () {
123- env <- Sys.getenv(" RAPP_INSTALL_DIR" , NA_character_ )
124- if (! is.na(env ) && nzchar(env )) {
125- return (normalizePath(env , mustWork = FALSE ))
126- }
127-
128- switch (
129- .Platform $ OS.type ,
130- windows = {
131- base <- Sys.getenv(" LOCALAPPDATA" , " " ) # this should probably resolve to $HOME/.local/bin
132- base <- if (nzchar(base )) {
133- normalizePath(base , mustWork = FALSE )
134- } else {
135- normalizePath(file.path(" ~" , " AppData" , " Local" ), mustWork = FALSE )
127+ getenv <- function (x ) Sys.getenv(x , NA_character_ )
128+ is_set <- function (x ) ! is.na(x ) && nzchar(x )
129+
130+ path <- if (is_set(p <- getenv(" RAPP_BIN_DIR" ))) {
131+ p
132+ } else if (is_set(p <- getenv(" XDG_BIN_HOME" ))) {
133+ p
134+ } else if (is_set(p <- getenv(" XDG_DATA_HOME" ))) {
135+ file.path(dirname(p ), " bin" )
136+ } else {
137+ switch (
138+ .Platform $ OS.type ,
139+ unix = " ~/.local/bin" ,
140+ windows = {
141+ base <- if (is_set(p <- getenv(" LOCALAPPDATA" ))) {
142+ p
143+ } else if (is_set(p <- getenv(" USERPROFILE" ))) {
144+ file.path(p , " AppData" , " Local" )
145+ } else {
146+ path.expand(" ~/AppData/Local" )
147+ }
148+ file.path(base , " Programs" , " R" , " Rapp" , " bin" )
136149 }
137- normalizePath(
138- file.path(base , " Programs" , " Rapp" , " bin" ),
139- mustWork = FALSE
140- )
141- },
142- unix = {
143- xdg <- Sys.getenv(" XDG_BIN_HOME" , " ~/.local/bin" )
144- normalizePath(xdg , mustWork = FALSE )
145- }
146- )
150+ )
151+ }
152+ normalizePath(path , mustWork = FALSE )
147153}
148154
149155
150156launcher_path <- function (app_path , destdir ) {
151157 name <- sub(" \\ .[rR]$" , " " , basename(app_path ))
152158 switch (
153159 .Platform $ OS.type ,
154- windows = file.path(destdir , paste0(name , " .bat" )),
160+ windows = file.path(destdir , paste0(name , " .bat" ), fsep = " \\ " ),
155161 unix = file.path(destdir , name )
156162 )
157163}
@@ -223,7 +229,7 @@ launcher_contents <- function(app_path, package) {
223229install_rapp_launcher <- function (destdir ) {
224230 target <- switch (
225231 .Platform $ OS.type ,
226- windows = file.path(destdir , " Rapp.bat" ),
232+ windows = file.path(destdir , " Rapp.bat" , fsep = " \\ " ),
227233 unix = file.path(destdir , " Rapp" )
228234 )
229235
@@ -239,15 +245,15 @@ install_rapp_launcher <- function(destdir) {
239245 " @echo off" ,
240246 " setlocal" ,
241247 sprintf(
242- r " (" %s / Rscript.exe " --default-packages=base - e Rapp::run() %%*)" ,
248+ r " (" %s / Rscript.exe " -e Rapp::run() %%*)" ,
243249 R.home(" bin" )
244250 )
245251 ),
246252 unix = c(
247253 " #!/bin/sh" ,
248254 paste(" #" , sentinel ),
249255 sprintf(
250- r " (exec %s/Rscript --default-packages=base - e 'Rapp::run()' " $@ " )" ,
256+ r " (exec %s/Rscript -e 'Rapp::run()' " $@ " )" ,
251257 R.home(" bin" )
252258 )
253259 )
@@ -293,3 +299,47 @@ get_rapp_launcher_package <- function(path) {
293299 )
294300 if (identical(pkg , lines [2 ])) NA_character_ else pkg
295301}
302+
303+
304+ # Ensure a directory is first on the user PATH (Windows)
305+ ensure_path_windows <- function (destdir = rapp_install_dir()) {
306+ stopifnot(.Platform $ OS.type == " windows" )
307+ destdir <- normalizePath(destdir , winslash = " \\ " , mustWork = TRUE )
308+
309+ # Check if we're already on PATH. If we are, do nothing
310+ # Read current PATH from HKCU\Environment
311+ path <- get_env_win_registry(" Path" )
312+ path <- strsplit(path , " ;" , fixed = TRUE )[[1L ]]
313+ path <- path [nzchar(path )]
314+ path <- unique(path )
315+
316+ path_norm <- function (x ) tolower(normalizePath(x , mustWork = FALSE ))
317+ present <- path_norm(destdir ) %in% path_norm(path )
318+ if (present ) {
319+ return (FALSE )
320+ }
321+
322+ # We are not on the PATH yet, we have to add it
323+ # Pass the new path entry via envvar to avoid quoting and encoding shenanigans
324+ # also, propogate the new updated PATH from the registry to this R session
325+ old <- Sys.getenv(" RAPP_NEW_PATH_ENTRY" , NA_character_ )
326+ Sys.setenv(" RAPP_NEW_PATH_ENTRY" = destdir )
327+ on.exit({
328+ if (is.na(old )) {
329+ Sys.unsetenv(" RAPP_NEW_PATH_ENTRY" )
330+ } else {
331+ Sys.setenv(" RAPP_NEW_PATH_ENTRY" = old )
332+ }
333+ Sys.setenv(" PATH" = get_env_win_registry(" Path" ))
334+ })
335+
336+ script <- shQuote(utils :: shortPathName(
337+ system.file(" add-path-entry.ps1" , package = " Rapp" )
338+ ))
339+ args <- c(" -NoProfile" , " -ExecutionPolicy" , " Bypass" , " -File" , script )
340+ system2(" powershell" , args )
341+ }
342+
343+ get_env_win_registry <- function (name ) {
344+ utils :: readRegistry(" Environment" , hive = " HCU" , view = " default" )[[name ]]
345+ }
0 commit comments