Skip to content

Commit

Permalink
Add check_linked_version() (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
lionel- authored Feb 26, 2020
1 parent 08c777e commit fff1388
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
64 changes: 64 additions & 0 deletions R/compat-linked-version.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# nocov start --- compat-linked-version --- 2020-02-24 Mon 12:55 CET


check_linked_version <- local({

howto_reinstall_msg <- function(pkg) {
os <- tolower(Sys.info()[["sysname"]])

if (os == "windows") {
url <- "https://github.com/jennybc/what-they-forgot/issues/62"
c(
i = sprintf("Please update %s to the latest version.", pkg),
i = sprintf("Updating packages on Windows requires precautions:\n <%s>", url)
)
} else {
c(
i = sprintf("Please update %s with `install.packages(\"%s\")` and restart R.", pkg, pkg)
)
}
}

function(pkg, with_rlang = requireNamespace("rlang")) {
ver <- utils::packageVersion(pkg)

ns <- asNamespace(pkg)
linked_ver_ptr <- ns[[paste0(pkg, "_linked_version")]]
if (is.null(linked_ver_ptr)) {
linked_ver <- ""
} else {
linked_ver <- .Call(linked_ver_ptr)
}

if (nzchar(linked_ver) && ver == linked_ver) {
return(invisible(NULL))
}

header <- sprintf("The %s package is not properly installed.", pkg)

if (nzchar(linked_ver)) {
msg <- c(x = sprintf(
"The DLL version (%s) does not correspond to the package version (%s).",
linked_ver,
ver
))
} else {
# Package does not have a version pointer. This happens when DLL
# updating fails for the first version that includes the pointer.
msg <- c(x = "The DLL version does not correspond to the package version.")
}

msg <- c(msg, howto_reinstall_msg(pkg))

if (with_rlang) {
msg <- paste(header, rlang::format_error_bullets(msg), sep = "\n")
rlang::abort(msg)
} else {
msg <- paste(c(header, msg), collapse = "\n")
stop(msg, call. = FALSE)
}
}
})


# nocov end
1 change: 1 addition & 0 deletions R/rlang.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ base_pkg_env <- NULL
is_same_body <<- is_reference
}

check_linked_version(pkg, with_rlang = FALSE)
on_package_load("glue", .Call(rlang_glue_is_there))

.Call(r_init_library)
Expand Down
2 changes: 2 additions & 0 deletions src/export/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ extern sexp* rlang_is_weakref(sexp*);
extern sexp* rlang_find_var(sexp*, sexp*);
extern sexp* rlang_env_bind_list(sexp*, sexp*, sexp*);
extern sexp* rlang_glue_is_there();
extern sexp* rlang_linked_version();

// Library initialisation defined below
sexp* rlang_library_load(sexp*);
Expand Down Expand Up @@ -287,6 +288,7 @@ static const r_callable r_callables[] = {
{"rlang_find_var", (r_fn_ptr) &rlang_find_var, 2},
{"rlang_env_bind_list", (r_fn_ptr) &rlang_env_bind_list, 3},
{"rlang_glue_is_there", (r_fn_ptr) &rlang_glue_is_there, 0},
{"rlang_linked_version", (r_fn_ptr) &rlang_linked_version, 0},
{NULL, NULL, 0}
};

Expand Down
27 changes: 27 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#define R_NO_REMAP
#include <Rinternals.h>

const char* rlang_version = "0.4.4.9000";

/**
* This file records the expected package version in the shared
* library (or DLL) of the package. This is useful to check that users
* have properly installed your package. Installation issues where the
* package is updated but the DLL isn't are common on Windows in
* particular. To automatically check that the native library of the
* package was properly installed:
*
* - Register the function below as a C callable under the name
* "rlang_linked_version".
*
* - Call `rlang::check_linked_version(pkg_name)` from your
* `.onLoad()` hook. If you don't depend on rlang copy the
* compat-linked-version.R file from the rlang repository to your R
* folder. Find it at
* <https://github.com/r-lib/rlang/tree/master/R/compat-linked-version.R>
*/

// [[ register() ]]
SEXP rlang_linked_version() {
return Rf_mkString(rlang_version);
}

0 comments on commit fff1388

Please sign in to comment.