Skip to content

Commit 6cca7d6

Browse files
proper caching for installed packages
1 parent 5be132a commit 6cca7d6

File tree

5 files changed

+116
-15
lines changed

5 files changed

+116
-15
lines changed

R/prepare.R

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,14 @@ ref_install <- function(ref = "master",
2424
fs::dir_create(libpath_touchstone(ref)),
2525
.libPaths()
2626
)
27-
last_change <- last_source_change()
2827
withr::local_libpaths(libpath)
2928
remotes::install_local(path_pkg,
3029
upgrade = "never", quiet = TRUE,
3130
dependencies = install_dependencies,
32-
force = last_change != getOption("touchstone.timestamp_source_package")
31+
force = !cache_up_to_date(ref, path_pkg)
3332
)
34-
options("touchstone.timestamp_source_package" = last_change)
33+
cache_update(ref, path_pkg)
3534
usethis::ui_done("Installed branch {ref} into {libpath[1]}.")
36-
37-
libpath
3835
}
3936
}
4037

@@ -80,10 +77,44 @@ libpath_touchstone <- function(ref) {
8077
#' When did the package sources change last?
8178
#'
8279
#' @keywords internal
83-
last_source_change <- function() {
84-
max(vctrs::vec_rbind(
85-
fs::dir_info("R"),
86-
fs::file_info("DESCRIPTION"),
87-
if (fs::dir_exists("scr")) fs::dir_info("scr"),
88-
)$modification_time)
80+
hash_pkg <- function() {
81+
list(
82+
tools::md5sum(c(
83+
fs::dir_ls("R"),
84+
"DESCRIPTION",
85+
if (fs::dir_exists("scr")) fs::dir_info("scr")
86+
))
87+
)
88+
}
89+
90+
#' Cache package sources within a session
91+
#'
92+
#' This is required to make sure [remotes::install_local()] installs again
93+
#' when source code changed.
94+
#' @inheritParams ref_install
95+
#' @keywords internal
96+
cache_up_to_date <- function(ref, path_pkg) {
97+
md5_hashes <- hash_pkg()
98+
cache <- cache_get()
99+
identical(md5_hashes, cache$md5_hashes[cache$ref == ref & cache$path_pkg == path_pkg])
100+
}
101+
102+
#' @rdname cache_up_to_date
103+
#' @keywords internal
104+
cache_update <- function(ref, path_pkg) {
105+
md5_hashes <- hash_pkg()
106+
cache <- cache_get()
107+
stopifnot(sum(cache$ref[cache$path_pkg == path_pkg] == ref) <= 1)
108+
cache <- cache[(!(cache$ref == ref) & (cache$path_pkg == path_pkg)), ]
109+
cache <- vctrs::vec_rbind(
110+
cache, tibble::tibble(ref, md5_hashes, path_pkg)
111+
)
112+
options("touchstone.hash_source_package" = cache)
113+
}
114+
115+
116+
#' @rdname cache_up_to_date
117+
#' @keywords internal
118+
cache_get <- function() {
119+
getOption("touchstone.hash_source_package")
89120
}

R/zzz.R

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
.onLoad <- function(libname, pkgname) {
22
op <- options()
3+
cache <- tibble::tibble(
4+
ref = character(), md5_hashes = list(), path_pkg = character()
5+
)
36
op.touchstone <- list(
47
"touchstone.skip_install" = FALSE,
58
"touchstone.dir" = "touchstone",
69
# how many times should inner loop be ran in benchmark_run_iteration
710
"touchstone.n_iterations" = 1,
8-
"touchstone.timestamp_source_package" = Sys.time()
11+
"touchstone.hash_source_package" = cache
912
)
1013
toset <- !(names(op.touchstone) %in% names(op))
1114
if (any(toset)) options(op.touchstone[toset])

man/cache_up_to_date.Rd

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/last_source_change.Rd renamed to man/hash_pkg.Rd

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-prepare.R

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,45 @@ test_that("can install in isolated repos", {
1818
withr::with_libpaths(lib_path2, bli44:::x), 55
1919
)
2020
})
21+
22+
test_that("cache works", {
23+
ref <- "devel"
24+
withr::local_options(list(
25+
"touchstone.hash_source_package" = tibble::tibble(
26+
ref = character(), md5_hashes = list(), path_pkg = character()
27+
)
28+
))
29+
name_tmp_pkg <- "bli44"
30+
path_pkg <- local_package(name_tmp_pkg, r_sample = "x <- 55")
31+
32+
expect_equal(nrow(cache_get()), 0)
33+
expect_false(cache_up_to_date(ref, path_pkg))
34+
cache_update(ref, path_pkg)
35+
expect_equal(nrow(cache_get()), 1)
36+
print(getwd())
37+
writeLines(c("x <- 55"), "R/sample.R")
38+
expect_true(cache_up_to_date(ref, path_pkg))
39+
writeLines(c("22"), "R/sample.R")
40+
expect_false(cache_up_to_date(ref, path_pkg))
41+
expect_false(cache_up_to_date(ref, path_pkg))
42+
cache_update(ref, path_pkg)
43+
expect_true(cache_up_to_date(ref, path_pkg))
44+
45+
# new ref
46+
ref <- "m2"
47+
expect_equal(nrow(cache_get()), 1)
48+
# prepare for case that remotes would ever have global cache across libraries
49+
# (currently not the case) and could think "version has not changed, just copying"
50+
expect_false(cache_up_to_date(ref, path_pkg))
51+
cache_update(ref, path_pkg)
52+
expect_equal(nrow(cache_get()), 2)
53+
cache_update(ref, path_pkg)
54+
expect_true(cache_up_to_date(ref, path_pkg))
55+
56+
# new root
57+
path_pkg <- local_package(name_tmp_pkg, r_sample = "c")
58+
expect_equal(nrow(cache_get()), 2)
59+
expect_false(cache_up_to_date(ref, path_pkg))
60+
cache_update(ref, path_pkg)
61+
expect_true(cache_up_to_date(ref, path_pkg))
62+
})

0 commit comments

Comments
 (0)