Skip to content

Commit a3d140b

Browse files
committed
[GR-12858] Override installation of special packages like rJava and data.table.
PullRequest: fastr/1902
2 parents 7958498 + fa6a996 commit a3d140b

File tree

5 files changed

+95
-33
lines changed

5 files changed

+95
-33
lines changed

com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/R/utils.R

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ eval(expression({
2525

2626
fastrRepoPath <- NULL
2727

28-
install.fastr.packages <- function(pkgs) {
28+
install.fastr.packages <- function(pkgs, lib, INSTALL_opts=character(0)) {
2929
if (is.null(fastrRepoPath) || !file.exists(fastrRepoPath)) {
3030
workDir <- tempdir()
3131
download.file('https://api.github.com/repos/oracle/fastr/tarball/master', file.path(workDir, 'fastr-repo.tar.gz'))
@@ -37,7 +37,11 @@ eval(expression({
3737
for (pkg in pkgs) {
3838
pkgPath <- file.path(fastrRepoPath, 'com.oracle.truffle.r.pkgs', pkg)
3939
if (file.exists(pkgPath)) {
40-
install.packages(pkgPath, repos=NULL)
40+
if (missing(lib)) {
41+
install.packages(pkgPath, repos=NULL, INSTALL_opts=INSTALL_opts)
42+
} else {
43+
install.packages(pkgPath, lib=lib, repos=NULL, INSTALL_opts=INSTALL_opts)
44+
}
4145
} else {
4246
stop(paste0("FastR doesn't provide patched version of package ", pkg, ". Use install.packages to install it."));
4347
}
@@ -92,4 +96,4 @@ eval(expression({
9296

9397
# export new public functions
9498
exports <- asNamespace("utils")[[".__NAMESPACE__."]][['exports']]
95-
assign('install.fastr.packages', 'install.fastr.packages', envir = exports)
99+
assign('install.fastr.packages', 'install.fastr.packages', envir = exports)

com.oracle.truffle.r.test.packages/initial.package.blacklist

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,6 @@ Reason: Bioconductor
295295
Package: lumi
296296
Reason: Bioconductor
297297

298-
Package: rJava
299-
Reason: java
300-
301298
Package: mzR
302299
Reason: Bioconductor
303300

com.oracle.truffle.r.test.packages/pkgtest/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,17 @@ def _installpkgs_script():
9595
return join(packages_test, 'r', 'install.packages.R')
9696

9797

98+
def commit_fastr_builtins():
99+
'''
100+
There are some FastR builtins which we also want to use in GnuR (i.e. 'install.fastr.packages').
101+
This function deparses these functions and writes them into a file which is then loaded by GnuR.
102+
'''
103+
dest_file = join(_packages_test_project_dir(), 'r', 'fastr.functions.rdx')
104+
cmd_line = [get_fastr_rscript(), "--silent", "-e", '{ fastrRepoPath <- NULL; save(fastrRepoPath, install.fastr.packages, file="%s") }' % dest_file]
105+
logging.debug("Generating fastr.functions.R: " + str(cmd_line))
106+
return pkgtest_run(cmd_line)
107+
108+
98109
def _installpkgs(args, **kwargs):
99110
'''
100111
Runs the R script that does package/installation and testing.
@@ -164,6 +175,9 @@ def pkgtest(args):
164175
env['FASTR_OPTION_PrintErrorStacktracesToFile'] = 'false'
165176
env['FASTR_OPTION_PrintErrorStacktraces'] = 'true'
166177

178+
# transfer required FastR functions to GnuR
179+
commit_fastr_builtins()
180+
167181
# If '--cache-pkgs' is set, then also set the native API version value
168182
_set_pkg_cache_api_version(install_args, get_fastr_include_path())
169183

com.oracle.truffle.r.test.packages/r/install.cache.R

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -710,45 +710,69 @@ transitive.dependencies <- function(pkg, lib, pl = as.data.frame(available.packa
710710
unique(deps)
711711
}
712712

713+
pkg.cache.in.overrides <- function(pkgname) pkgname %in% (if(is.fastr()) overrides$fastr else overrides$gnur)
714+
715+
pkg.cache.full.install <- function(install.candidate.names, contriburl, lib.install) {
716+
# separate uncached packages that are listed in 'overrides'
717+
pkgs.in.overrides <- as.character(install.candidate.names[pkg.cache.in.overrides(install.candidate.names)])
718+
pkgs.not.in.overrides <- as.character(install.candidate.names[!pkg.cache.in.overrides(install.candidate.names)])
719+
720+
# override packages need to be installed differently
721+
if (length(pkgs.in.overrides) > 0) {
722+
install.fastr.packages(as.character(pkgs.in.overrides), lib=lib.install, INSTALL_opts="--install-tests")
723+
}
724+
725+
if (length(pkgs.not.in.overrides) > 0) {
726+
install.packages(as.character(pkgs.not.in.overrides), contriburl=contriburl, type="source", lib=lib.install, INSTALL_opts="--install-tests")
727+
}
728+
}
729+
713730
# Fetches the package from the cache or installs it. This is also done for all transitive dependencies.
714731
pkg.cache.internal.install <- function(pkg.cache.env, pkgname, contriburl, lib.install) {
715732
tryCatch({
716-
if (pkg.cache.is.enabled(pkg.cache.env)) {
717-
# determine available packages
718-
pkg.list <- as.data.frame(available.packages(contriburl=contriburl), stringAsFactors=FALSE)
733+
# determine available packages
734+
pkg.list <- as.data.frame(available.packages(contriburl=contriburl, filters=list(add=TRUE, function(x) x), stringAsFactors=FALSE))
719735

720-
# query version of the package
721-
pkg <- pkg.list[pkgname, c("Package", "Version")]
736+
# query version of the package
737+
pkg <- pkg.list[pkgname, c("Package", "Version")]
722738

723-
# compute transitive dependencies of the package to install
724-
log.message("Computing transitive package dependencies for ", paste0(pkgname, "_", as.character(pkg$Version)), level=1)
725-
transitive.pkg.list <- rbind(transitive.dependencies(pkgname, lib=lib.install, pl=pkg.list), pkg)
726-
log.message("transitive deps: ", as.character(transitive.pkg.list$Package), level=1)
739+
# compute transitive dependencies of the package to install
740+
log.message("Computing transitive package dependencies for ", paste0(pkgname, "_", as.character(pkg$Version)), level=1)
741+
transitive.pkg.list <- rbind(transitive.dependencies(pkgname, lib=lib.install, pl=pkg.list), pkg)
742+
log.message("transitive deps: ", as.character(transitive.pkg.list$Package), level=1)
727743

744+
if (pkg.cache.is.enabled(pkg.cache.env)) {
728745
# apply pkg cache to fetch cached packages first
729746
cached.pkgs <- apply(transitive.pkg.list, 1, function(pkg) pkg.cache.get(pkg.cache.env, pkg, lib.install))
730747
log.message("Number of uncached packages:", nrow(transitive.pkg.list[!cached.pkgs, ]), level=1)
731748

732749
# if there was at least one non-cached package
733750
if (any(!cached.pkgs) || length(cached.pkgs) == 0L) {
734751
# install the package (and the transitive dependencies implicitly)
735-
install.packages(as.character(transitive.pkg.list[!cached.pkgs, "Package"]), contriburl=contriburl, type="source", lib=lib.install, INSTALL_opts="--install-tests")
752+
uncached.pkg.names <- transitive.pkg.list[!cached.pkgs, "Package"]
753+
754+
# install uncached packages
755+
pkg.cache.full.install(uncached.pkg.names, contriburl, lib.install)
736756

737757
# cache packages that were not in the cache before
738758
log.message("Caching uncached dependencies:", as.character(transitive.pkg.list[!cached.pkgs, "Package"]), level=1)
739759
apply(transitive.pkg.list[!cached.pkgs, ], 1, function(pkg) pkg.cache.insert(pkg.cache.env, pkg, lib.install))
740760
}
741761
} else {
742-
install.packages(pkgname, contriburl=contriburl, type="source", lib=lib.install, INSTALL_opts="--install-tests")
762+
# Even if we do not use the package cache, we need to compute the dependencies transitively
763+
# because the deps may contain overridden packages.
764+
pkg.cache.full.install(transitive.pkg.list[, "Package"], contriburl, lib.install)
743765
}
744766

745767
# if we reach here, installation was a success
746768
0L
747769
}, error = function(e) {
748770
log.message(e$message)
771+
log.message(traceback())
749772
return (1L)
750773
}, warning = function(e) {
751774
log.message(e$message)
752775
return (1L)
753776
})
754777
}
778+

com.oracle.truffle.r.test.packages/r/install.packages.R

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,13 @@ ignore.suggests <- list(
162162
mboost = ignore.all.but('TH.data', 'survival', 'RColorBrewer'), # this pkg has only vignettes and grepping then gave these libs
163163
quantmod = '*', # probably not necessary, the tests output does not contain any 'library', 'require' or 'load' calls
164164
forcats = ignore.all.but('testthat'), # other suggested: ggplot2 and covcor not used in tests
165-
sqldf = 'tcltk|RPostgreSQL|RJDBC|rJava|RH2' # tcltk not on CRAN, RPostgreSQL can't be installed, RH2 and RJDBC depend on rJava which can't be installed
165+
sqldf = 'tcltk|RPostgreSQL|RJDBC|RH2' # tcltk not on CRAN, RPostgreSQL can't be installed, RH2 and RJDBC depend on rJava which can't be installed
166+
)
167+
168+
# manually maintained list of packages that need to be install with 'install.fastr.packages'
169+
overrides <- list(
170+
fastr = c("rJava", "data.table"),
171+
gnur = c("data.table")
166172
)
167173

168174
choice.depends <- function(pkg, choice=c("direct","suggests")) {
@@ -464,7 +470,7 @@ get.pkgs <- function() {
464470
quit(save="no", status=100)
465471
}
466472
tryCatch({
467-
avail.pkgs <<- available.packages(type="source")
473+
avail.pkgs <<- available.packages(type="source", filters = list(add=TRUE, function(x) x))
468474
}, warning=my.warning)
469475

470476
# Owing to a FastR bug, we may not invoke the handler above, but
@@ -493,6 +499,8 @@ get.pkgs <- function() {
493499

494500
in.installed <- function(x) x["Package"] %in% installed.pkgs
495501

502+
in.overrides <- function(x) FALSE
503+
496504
basic.exclude <- function(x, exclude.installed = T) {
497505
in.blacklist(x) || ifelse(exclude.installed, in.installed(x), F)
498506
}
@@ -502,15 +510,15 @@ get.pkgs <- function() {
502510
# if inverting, alter sense of the basic match but still exclude blacklist/installed
503511
if (!is.na(pkg.filelistfile)) {
504512
if (invert.pkgset) {
505-
match.fun <- function(x) !in.filelist(x) && !basic.exclude(x, exclude.installed)
513+
match.fun <- function(x) !in.filelist(x) && (in.overrides(x) || !basic.exclude(x, exclude.installed))
506514
} else {
507-
match.fun <- function(x) in.filelist(x) && !basic.exclude(x, exclude.installed)
515+
match.fun <- function(x) in.filelist(x) && (in.overrides(x) || !basic.exclude(x, exclude.installed))
508516
}
509517
} else {
510518
if (invert.pkgset) {
511-
match.fun <- function(x) !in.pattern(x) && !basic.exclude(x, exclude.installed)
519+
match.fun <- function(x) !in.pattern(x) && (in.overrides(x) || !basic.exclude(x, exclude.installed))
512520
} else {
513-
match.fun <- function(x) in.pattern(x) && !basic.exclude(x, exclude.installed)
521+
match.fun <- function(x) in.pattern(x) && (in.overrides(x) || !basic.exclude(x, exclude.installed))
514522
}
515523
}
516524
}
@@ -523,7 +531,6 @@ get.pkgs <- function() {
523531
if (length(toinstall.pkgs) == 0 && !use.installed.pkgs) {
524532
print("Fatal error: requested package(s) found in repo(s)")
525533
quit(save="no", status=100)
526-
527534
}
528535

529536
if (!is.na(random.count)) {
@@ -970,7 +977,11 @@ parse.args <- function() {
970977
svalue <- strsplit(get.argvalue(), ",")[[1]]
971978
for (s in svalue) {
972979
arg <- strsplit(s, "=", fixed=T)[[1]]
973-
assign(arg[[1]], arg[[2]], envir=pkg.cache)
980+
if (arg[[1]] == "dir") {
981+
assign(arg[[1]], normalizePath(arg[[2]]), envir=pkg.cache)
982+
} else {
983+
assign(arg[[1]], arg[[2]], envir=pkg.cache)
984+
}
974985
}
975986
} else if (a == "--random") {
976987
random.count <<- as.integer(get.argvalue())
@@ -1230,20 +1241,32 @@ getCurrentScriptDir <- function() {
12301241
}
12311242

12321243
run <- function() {
1233-
parse.args()
1234-
if (!is.na(find.top.pkgs)) {
1235-
set.repos()
1236-
do.find.top.pkgs(find.top.pkgs)
1237-
} else {
1238-
run.setup()
1239-
do.it()
1240-
}
1244+
tryCatch({
1245+
parse.args()
1246+
if (!is.na(find.top.pkgs)) {
1247+
set.repos()
1248+
do.find.top.pkgs(find.top.pkgs)
1249+
} else {
1250+
run.setup()
1251+
do.it()
1252+
}
1253+
}, errors = function(e) traceback()
1254+
)
12411255
}
12421256

12431257
# load package cache code
12441258
curScriptDir <- getCurrentScriptDir()
12451259
if (!is.null(curScriptDir)) {
12461260
source(file.path(curScriptDir, "install.cache.R"))
1261+
if (!is.fastr()) {
1262+
fastr.functions.path <- file.path(curScriptDir, "fastr.functions.rdx")
1263+
if (file.exists(fastr.functions.path)) {
1264+
loaded.names <- load(fastr.functions.path)
1265+
log.message("Loaded names: ", loaded.names)
1266+
} else {
1267+
log.message("Warning: Running with GnuR but could not find file '", fastr.functions.path, "'")
1268+
}
1269+
}
12471270
} else {
12481271
log.message("Cannot use package cache since script directory cannot be determined")
12491272

0 commit comments

Comments
 (0)