ropensci-review-tools / goodpractice

Advice on R Package Building
https://docs.ropensci.org/goodpractice/
Other
465 stars 36 forks source link

Platform non-agnostic / dangerous functions #63

Open njtierney opened 7 years ago

njtierney commented 7 years ago

There are some functions, or options within functions, or patterns that can not be run on all operating systems.

After some discussion around the checkers pkg, at the rOpenSci unconf17, we thought it might be useful to create a list of these functions, options, or patterns.

This list may eventually turn into something that goodpractice or lintr uses.

Tagging a few folks in here who might be interested in contributing to this: @jennybc @jeroen @richierocks @stephlock @daattali @gaborcsardi

Please feel free to add others!

gaborcsardi commented 7 years ago
daattali commented 7 years ago

Don't know if it counys, but many popular parallel processing packages don't work on windows

gmbecker commented 7 years ago

A list of functions with windows implementations (defined in /R/windows/*.R) not present in my OS X version of R (NB, the versions are different, but that probably matters in ~0 of them)

## wd is the src/library directory of a checkout of the R source code
pkgdirs = list.dirs(".", recursive=FALSE, full.names=TRUE)
pkgdirs = pkgdirs[-grep("Recommended", pkgdirs)]
windirs = file.path(pkgdirs,"R","windows")

winrfils = list.files(windirs, pattern = ".R", full.names=TRUE)

library(CodeDepends)

winfuns = unlist(lapply(winrfils,
                        function(f) {
    scr = readScript(f)
    info = getInputs(scr)
    unlist(lapply(info, function(y) y@outputs))
}))

winfuns[!sapply(winfuns, exists)]
 [1] "Sys.junction"             "shell"                   
 [3] "shell.exec"               "check_gs_type"           
 [5] ".geometry"                ".WindowsEnv"             
 [7] ".Windows.Options"         ".Windows.Options.default"
 [9] "aa.win"                   "aa.cairo"                
[11] "windows.options"          "windows"                 
[13] "win.graph"                "win.print"               
[15] "win.metafile"             "bringToTop"              
[17] "msgWindow"                "print.SavedPlots"        
[19] "[.SavedPlots"             ".Windows.Fonts"          
[21] "checkWindowsFont"         "setWindowsFonts"         
[23] "printFont"                "printFonts"              
[25] "windowsFonts"             "windowsFont"             
[27] "makeForkCluster"          "mclapply"                
[29] "pvec"                     "mcmapply"                
[31] "mcMap"                    ".TkUp"                   
[33] ".onLoad"                  ".onUnload"               
[35] "loadRconsole"             "Filters"                 
[37] "choose.files"             "choose.dir"              
[39] "unpackPkgZip"             ".install.winbinary"      
[41] "menuInstallPkgs"          "menuInstallLocal"        
[43] "zip.unpack"               "DLL.version"             
[45] "getClipboardFormats"      "readClipboard"           
[47] "writeClipboard"           "getIdentification"       
[49] "setWindowTitle"           "getWindowTitle"          
[51] "setStatusBar"             "getWindowsHandle"        
[53] "getWindowsHandles"        "arrangeWindows"          
[55] "menuShowCRAN"             "shortPathName"           
[57] "readRegistry"             "setInternet2"            
[59] "win.version"              "winDialog"               
[61] "winDialogString"          "winMenuDel"              
[63] "winMenuDelItem"           "winMenuAdd"              
[65] "winMenuAddItem"           "winMenuNames"            
[67] "winMenuItems"             "winProgressBar"          
[69] "close.winProgressBar"     "setWinProgressBar"       
[71] "getWinProgressBar"        "askYesNoWinDialog"       
gmbecker commented 7 years ago

I did the above quickly, so obviously there are some false positives (the .onLoad jumps out) but most of them pass the eyeball test.

Double edit: I'll do a better version of this later today. at the very least these are functions that have windows-specific implementations.

gmbecker commented 7 years ago

Ok, this time with proper checking for the functions in the Mac versions I have installed, and some comments (and code highlighting...)

pkgdirs = list.dirs(".", recursive=FALSE, full.names=TRUE)
pkgdirs = pkgdirs[-grep("Recommended", pkgdirs)]
windirs = file.path(pkgdirs,"R","windows")

winrfils = list.files(windirs, pattern = ".R", full.names=TRUE)

library(CodeDepends)
basepkgs = installed.packages(priority="base")[,"Package"]

## attach all the base packages, probably overkill give new way of checking
## for existence later on...
lapply(basepkgs, function(x) library(x, character.only=TRUE))

## returns a list of vectors of functions defined in /R/windows/*.R files
## named by the file.
winfuns = sapply(winrfils,
                        function(f) {
    scr = readScript(f)
    info = getInputs(scr)
    ## the outputs here are functions defined in the .R file
    unlist(lapply(info, function(y) y@outputs))
})

## names of packages 
pkgs = gsub(".*/([^/]*)/R/windows/.*", "\\1", names(winfuns))
## vector of functions defined in /windows/*.R files in base pkgs
## will be parallel to pkgs
winfunsvec = unlist(winfuns)

## logical indicated whether each function exists in the namespace
## of the corresponding package on my mac
foundonmac = mapply(function(f, pkg) {
    ff = try(get(f, envir = asNamespace(pkg), inherits = FALSE),
             silent = TRUE)
    !is(ff, "try-error")
}, f = winfunsvec, pkg = rep(pkgs, times = lengths(winfuns)))

## functions implemented for windows versions of base packages but not
## for mac versions I have installed.
winonly = winfunsvec[!foundonmac]
names(winonly) = pkgsvec[!foundonmac]
winonly

Gives us

                     base                       base 
            "Sys.junction"                    "shell" 
                      base                  grDevices 
              "shell.exec"              ".WindowsEnv" 
                 grDevices                  grDevices 
        ".Windows.Options" ".Windows.Options.default" 
                 grDevices                  grDevices 
                  "aa.win"          "windows.options" 
                 grDevices                  grDevices 
                 "windows"                "win.graph" 
                 grDevices                  grDevices 
               "win.print"             "win.metafile" 
                 grDevices                  grDevices 
              "bringToTop"                "msgWindow" 
                 grDevices                  grDevices 
        "print.SavedPlots"             "[.SavedPlots" 
                 grDevices                  grDevices 
          ".Windows.Fonts"         "checkWindowsFont" 
                 grDevices                  grDevices 
         "setWindowsFonts"             "windowsFonts" 
                 grDevices                      tcltk 
             "windowsFont"                ".onUnload" 
                     utils                      utils 
            "loadRconsole"                  "Filters" 
                     utils                      utils 
            "choose.files"               "choose.dir" 
                     utils                      utils 
            "unpackPkgZip"       ".install.winbinary" 
                     utils                      utils 
         "menuInstallPkgs"         "menuInstallLocal" 
                     utils                      utils 
              "zip.unpack"              "DLL.version" 
                     utils                      utils 
     "getClipboardFormats"            "readClipboard" 
                     utils                      utils 
          "writeClipboard"        "getIdentification" 
                     utils                      utils 
          "setWindowTitle"           "getWindowTitle" 
                     utils                      utils 
            "setStatusBar"         "getWindowsHandle" 
                     utils                      utils 
       "getWindowsHandles"           "arrangeWindows" 
                     utils                      utils 
            "menuShowCRAN"            "shortPathName" 
                     utils                      utils 
            "readRegistry"             "setInternet2" 
                     utils                      utils 
             "win.version"                "winDialog" 
                     utils                      utils 
         "winDialogString"               "winMenuDel" 
                     utils                      utils 
          "winMenuDelItem"               "winMenuAdd" 
                     utils                      utils 
          "winMenuAddItem"             "winMenuNames" 
                     utils                      utils 
            "winMenuItems"           "winProgressBar" 
                     utils                      utils 
    "close.winProgressBar"        "setWinProgressBar" 
                     utils                      utils 
       "getWinProgressBar"        "askYesNoWinDialog" 
njtierney commented 7 years ago

Thanks @gmbecker ! This is great :)