pkgload/0000755000176200001440000000000014551472164011704 5ustar liggesuserspkgload/NAMESPACE0000644000176200001440000000127714502560210013114 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(print,dev_topic) export(check_dep_version) export(check_suggested) export(dev_example) export(dev_help) export(dev_meta) export(dev_topic_find) export(dev_topic_index) export(dev_topic_index_reset) export(has_tests) export(imports_env) export(inst) export(is_dev_package) export(is_loading) export(load_all) export(load_code) export(load_data) export(load_dll) export(ns_env) export(package_file) export(parse_deps) export(parse_ns_file) export(pkg_desc) export(pkg_env) export(pkg_name) export(pkg_ns) export(pkg_path) export(pkg_version) export(pkg_version_raw) export(pkgtest) export(run_example) export(unload) export(unregister) import(rlang) pkgload/README.md0000644000176200001440000000220214247353057013160 0ustar liggesusers# pkgload [![Codecov test coverage](https://codecov.io/gh/r-lib/pkgload/branch/main/graph/badge.svg)](https://app.codecov.io/gh/r-lib/pkgload?branch=main) [![R-CMD-check](https://github.com/r-lib/pkgload/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/pkgload/actions/workflows/R-CMD-check.yaml) The goal of pkgload is to simulate the process of installing and loading a package, without actually doing the complete process, and hence making package iteration much faster. This was previously part of devtools (it was in fact the original motivation) but has been moved into its own package as part of the devtools [conscious uncoupling](https://github.com/r-lib/devtools#conscious-uncoupling). ## Usage In most cases you will not use pkgload directly, and instead you'll call it via `devtools::load_all()`. ``` r devtools::load_all() ``` ## Code of Conduct Please note that the pkgload project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. pkgload/man/0000755000176200001440000000000014503041755012452 5ustar liggesuserspkgload/man/dev_help.Rd0000644000176200001440000000305414502560210014520 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dev-help.R, R/dev-topic.R \name{dev_help} \alias{dev_help} \alias{dev_topic_find} \alias{dev_topic_index} \alias{dev_topic_index_reset} \title{In-development help for package loaded with devtools} \usage{ dev_help( topic, dev_packages = NULL, stage = "render", type = getOption("help_type") ) dev_topic_find(topic, dev_packages = NULL) dev_topic_index(path = ".") dev_topic_index_reset(pkg_name) } \arguments{ \item{topic}{name of help to search for.} \item{dev_packages}{A character vector of package names to search within. If \code{NULL}, defaults to all packages loaded by devtools.} \item{stage}{at which stage ("build", "install", or "render") should \verb{\\\\Sexpr} macros be executed? This is only important if you're using \verb{\\\\Sexpr} macro's in your Rd files.} \item{type}{of html to produce: \code{"html"} or \code{"text"}. Defaults to your default documentation type.} \item{path}{Path to package.} \item{pkg_name}{Name of package.} } \description{ \code{dev_help()} searches for source documentation provided in packages loaded by devtools. To improve performance, the \code{.Rd} files are parsed to create to index once, then cached. Use \code{dev_topic_index_reset()} to clear that index. You can manually retrieve the index for a local package with \code{dev_topic_index()}. } \examples{ \dontrun{ library("ggplot2") help("ggplot") # loads installed documentation for ggplot load_all("ggplot2") dev_help("ggplot") # loads development documentation for ggplot } } pkgload/man/package_file.Rd0000644000176200001440000000115414247353057015342 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package.R \name{package_file} \alias{package_file} \title{Find file in a package.} \usage{ package_file(..., path = ".") } \arguments{ \item{...}{Components of the path.} \item{path}{Place to start search for package directory.} } \description{ It always starts by finding by walking up the path until it finds the root directory, i.e. a directory containing \code{DESCRIPTION}. If it cannot find the root directory, or it can't find the specified path, it will throw an error. } \examples{ \dontrun{ package_file("figures", "figure_1") } } pkgload/man/load_data.Rd0000644000176200001440000000052114247353057014655 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/load-data.R \name{load_data} \alias{load_data} \title{Load data.} \usage{ load_data(path = ".") } \arguments{ \item{path}{Path to a package, or within a package.} } \description{ Loads all \code{.RData} files in the data subdirectory. } \keyword{programming} pkgload/man/run_pkg_hook.Rd0000644000176200001440000000067014247353057015437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/run-loadhooks.R \name{run_pkg_hook} \alias{run_pkg_hook} \alias{run_user_hook} \title{Run user and package hooks.} \usage{ run_pkg_hook(package, hook) run_user_hook(package, hook) } \arguments{ \item{package}{package name.} \item{hook}{hook name: one of "load", "unload", "attach", or "detach"} } \description{ Run user and package hooks. } \keyword{internal} pkgload/man/load_dll.Rd0000644000176200001440000000046214247353057014523 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/load-dll.R \name{load_dll} \alias{load_dll} \title{Load a compiled DLL} \usage{ load_dll(path = ".") } \arguments{ \item{path}{Path to a package, or within a package.} } \description{ Load a compiled DLL } \keyword{programming} pkgload/man/imports_env.Rd0000644000176200001440000000131014502252337015300 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/imports-env.R \name{imports_env} \alias{imports_env} \title{Return imports environment for a package} \usage{ imports_env(package) } \arguments{ \item{package}{The package name as a string.} } \description{ Contains objects imported from other packages. Is the parent of the package namespace environment, and is a child of \verb{}, which is a child of \code{R_GlobalEnv}. } \seealso{ \code{\link[=ns_env]{ns_env()}} for the namespace environment that all the objects (exported and not exported). \code{\link[=pkg_env]{pkg_env()}} for the attached environment that contains the exported objects. } \keyword{internal} pkgload/man/load_imports.Rd0000644000176200001440000000065114247353057015445 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/imports-env.R \name{load_imports} \alias{load_imports} \title{Load all of the imports for a package} \usage{ load_imports(path = ".") } \description{ The imported objects are copied to the imports environment, and are not visible from \code{R_GlobalEnv}. This will automatically load (but not attach) the dependency packages. } \keyword{internal} pkgload/man/system.file.Rd0000644000176200001440000000347714247353057015224 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/shims.R \name{system.file} \alias{system.file} \alias{shim_system.file} \title{Replacement version of system.file} \usage{ shim_system.file(..., package = "base", lib.loc = NULL, mustWork = FALSE) } \arguments{ \item{...}{character vectors, specifying subdirectory and file(s) within some package. The default, none, returns the root of the package. Wildcards are not supported.} \item{package}{a character string with the name of a single package. An error occurs if more than one package name is given.} \item{lib.loc}{a character vector with path names of \R libraries. See \sQuote{Details} for the meaning of the default value of \code{NULL}.} \item{mustWork}{logical. If \code{TRUE}, an error is given if there are no matching files.} } \description{ This function is meant to intercept calls to \code{\link[base:system.file]{base::system.file()}}, so that it behaves well with packages loaded by devtools. It is made available when a package is loaded with \code{\link[=load_all]{load_all()}}. } \details{ When \code{system.file} is called from the R console (the global environment), this function detects if the target package was loaded with \code{\link[=load_all]{load_all()}}, and if so, it uses a customized method of searching for the file. This is necessary because the directory structure of a source package is different from the directory structure of an installed package. When a package is loaded with \code{load_all}, this function is also inserted into the package's imports environment, so that calls to \code{system.file} from within the package namespace will use this modified version. If this function were not inserted into the imports environment, then the package would end up calling \code{base::system.file} instead. } pkgload/man/pkgload-package.Rd0000644000176200001440000000172214451231442015751 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pkgload-package.R \docType{package} \name{pkgload-package} \alias{pkgload} \alias{pkgload-package} \title{pkgload: Simulate Package Installation and Attach} \description{ Simulates the process of installing a package and then attaching it. This is a key part of the 'devtools' package as it allows you to rapidly iterate while developing a package. } \seealso{ Useful links: \itemize{ \item \url{https://github.com/r-lib/pkgload} \item \url{https://pkgload.r-lib.org} \item Report bugs at \url{https://github.com/r-lib/pkgload/issues} } } \author{ \strong{Maintainer}: Lionel Henry \email{lionel@posit.co} Authors: \itemize{ \item Hadley Wickham \item Winston Chang \item Jim Hester } Other contributors: \itemize{ \item Posit Software, PBC [copyright holder, funder] \item R Core team (Some namespace and vignette code extracted from base R) [contributor] } } \keyword{internal} pkgload/man/has_tests.Rd0000644000176200001440000000040414247353057014742 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/has_tests.R \name{has_tests} \alias{has_tests} \title{Was devtools installed with tests?} \usage{ has_tests() } \description{ Was devtools installed with tests? } \keyword{internal} pkgload/man/dev_example.Rd0000644000176200001440000000274314502515617015242 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dev-example.R \name{dev_example} \alias{dev_example} \alias{run_example} \title{Run a examples for an in-development function.} \usage{ dev_example(topic, quiet = FALSE) run_example( path, run_donttest = FALSE, run_dontrun = FALSE, env = new.env(parent = globalenv()), quiet = FALSE, macros = NULL, run, test ) } \arguments{ \item{topic}{Name or topic (or name of Rd) file to run examples for} \item{quiet}{If \code{TRUE}, does not echo code to console.} \item{path}{Path to \code{.Rd} file} \item{run_donttest}{if \code{TRUE}, do run \verb{\donttest} sections in the Rd files.} \item{run_dontrun}{if \code{TRUE}, do run \verb{\dontrun} sections in the Rd files.} \item{env}{Environment in which code will be run.} \item{macros}{Custom macros to use to parse the \code{.Rd} file. See the \code{macros} argument of \code{\link[tools:parse_Rd]{tools::parse_Rd()}}. If \code{NULL}, then the \code{\link[tools:Rd2HTML]{tools::Rd2ex()}} (and \code{\link[tools:parse_Rd]{tools::parse_Rd()}}) default is used.} \item{run, test}{Deprecated, see \code{run_dontrun} and \code{run_donttest} above.} } \description{ \code{dev_example} is a replacement for \code{example}. \code{run_example} is a low-level function that takes a path to an Rd file. } \examples{ \dontrun{ # Runs installed example: library("ggplot2") example("ggplot") # Runs development example: dev_example("ggplot") } } \concept{example functions} pkgload/man/check_suggested.Rd0000644000176200001440000000111414247353057016073 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils.R \name{check_suggested} \alias{check_suggested} \title{Check that the version of an suggested package satisfies the requirements} \usage{ check_suggested(package, version = NULL, compare = NA, path = inst("pkgload")) } \arguments{ \item{package}{The name of the suggested package} \item{version}{The version of the package} \item{compare}{The comparison operator used to check the version} } \description{ Check that the version of an suggested package satisfies the requirements } \keyword{internal} pkgload/man/inst.Rd0000644000176200001440000000106214247353057013723 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/inst.R \name{inst} \alias{inst} \title{Get the installation path of a package} \usage{ inst(name) } \arguments{ \item{name}{the name of a package.} } \description{ Given the name of a package, this returns a path to the installed copy of the package, which can be passed to other devtools functions. } \details{ It searches for the package in \code{\link[=.libPaths]{.libPaths()}}. If multiple dirs are found, it will return the first one. } \examples{ inst("pkgload") inst("grid") } pkgload/man/is_dev_package.Rd0000644000176200001440000000057714247353057015704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package.R \name{is_dev_package} \alias{is_dev_package} \title{Is the package currently under development?} \usage{ is_dev_package(name) } \arguments{ \item{name}{the name of a package.} } \description{ Returns \code{TRUE} or \code{FALSE} depending on if the package has been loaded by \strong{pkgload}. } pkgload/man/unload.Rd0000644000176200001440000000274314247353057014237 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/unload.R \name{unload} \alias{unload} \alias{unregister} \title{Unload a package} \usage{ unload(package = pkg_name(), quiet = FALSE) unregister(package = pkg_name()) } \arguments{ \item{package}{package name.} \item{quiet}{if \code{TRUE} suppresses output from this function.} } \description{ \code{unload()} attempts to cleanly unload a package, including unloading its namespace, deleting S4 class definitions and unloading any loaded DLLs. Unfortunately S4 classes are not really designed to be cleanly unloaded, and so we have to manually modify the class dependency graph in order for it to work - this works on the cases for which we have tested but there may be others. Similarly, automated DLL unloading is best tested for simple scenarios (particularly with \code{useDynLib(pkgname)} and may fail in other cases. If you do encounter a failure, please file a bug report at \url{https://github.com/r-lib/pkgload/issues}. \code{unregister()} is a gentler version of \code{unload()} which removes the package from the search path, unregisters methods, and unregisters the namespace. It doesn't unload the namespace or its DLL to keep it in working order in case of dangling references. } \examples{ \dontrun{ # Unload package that is in current directory unload() # Unload package that is in ./ggplot2/ unload(pkg_name("ggplot2/")) library(ggplot2) # unload the ggplot2 package directly by name unload("ggplot2") } } pkgload/man/load_code.Rd0000644000176200001440000000073314326232547014661 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/load-code.R \name{load_code} \alias{load_code} \title{Load R code.} \usage{ load_code(path = ".", quiet = NULL) } \arguments{ \item{path}{Path to a package, or within a package.} \item{quiet}{if \code{TRUE} suppresses output from this function.} } \description{ Sources all \code{.R}/\code{.r} files in the \verb{R/} directory, storing results into the package namespace. } \keyword{programming} pkgload/man/packages.Rd0000644000176200001440000000210214451231442014506 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package.R \name{packages} \alias{packages} \alias{pkg_path} \alias{pkg_name} \alias{pkg_desc} \alias{pkg_version} \alias{pkg_version_raw} \alias{pkg_ns} \title{Helper functions for working with development packages.} \usage{ pkg_path(path = ".") pkg_name(path = ".") pkg_desc(path = ".") pkg_version(path = ".") pkg_version_raw(path = ".") pkg_ns(path = ".") } \arguments{ \item{path}{Path to a package, or within a package.} } \description{ All functions search recursively up the directory tree from the input path until they find a DESCRIPTION file. } \section{Functions}{ \itemize{ \item \code{pkg_path()}: Return the normalized package path. \item \code{pkg_name()}: Return the package name. \item \code{pkg_desc()}: Return the package DESCRIPTION as a \code{\link[desc:desc]{desc::desc()}} object. \item \code{pkg_version()}: Return the parsed package version. \item \code{pkg_version_raw()}: Return the raw package version (as a string). \item \code{pkg_ns()}: Return the package namespace. }} pkgload/man/load_all.Rd0000644000176200001440000001430114503041755014507 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/load.R \name{load_all} \alias{load_all} \alias{is_loading} \title{Load complete package} \usage{ load_all( path = ".", reset = TRUE, compile = NA, attach = TRUE, export_all = TRUE, export_imports = export_all, helpers = export_all, attach_testthat = uses_testthat(path), quiet = NULL, recompile = FALSE, warn_conflicts = TRUE ) is_loading(pkg = NULL) } \arguments{ \item{path}{Path to a package, or within a package.} \item{reset}{clear package environment and reset file cache before loading any pieces of the package. This largely equivalent to running \code{\link[=unload]{unload()}}, however the old namespaces are not completely removed and no \code{.onUnload()} hooks are called. Use \code{reset = FALSE} may be faster for large code bases, but is a significantly less accurate approximation.} \item{compile}{If \code{TRUE} always recompiles the package; if \code{NA} recompiles if needed (as determined by \code{\link[pkgbuild:needs_compile]{pkgbuild::needs_compile()}}); if \code{FALSE}, never recompiles.} \item{attach}{Whether to attach a package environment to the search path. If \code{FALSE} \code{load_all()} behaves like \code{loadNamespace()}. If \code{TRUE} (the default), it behaves like \code{library()}. If \code{FALSE}, the \code{export_all}, \code{export_imports}, and \code{helpers} arguments have no effect.} \item{export_all}{If \code{TRUE} (the default), export all objects. If \code{FALSE}, export only the objects that are listed as exports in the NAMESPACE file.} \item{export_imports}{If \code{TRUE} (the default), export all objects that are imported by the package. If \code{FALSE} export only objects defined in the package.} \item{helpers}{if \code{TRUE} loads \pkg{testthat} test helpers.} \item{attach_testthat}{If \code{TRUE}, attach \pkg{testthat} to the search path, which more closely mimics the environment within test files.} \item{quiet}{if \code{TRUE} suppresses output from this function.} \item{recompile}{DEPRECATED. force a recompile of DLL from source code, if present. This is equivalent to running \code{\link[pkgbuild:clean_dll]{pkgbuild::clean_dll()}} before \code{load_all()}} \item{warn_conflicts}{If \code{TRUE}, issues a warning if a function in the global environment masks a function in the package. This can happen when you accidentally source a \code{.R} file, rather than using \code{load_all()}, or if you define a function directly in the R console. This is frustrating to debug, as it feels like the changes you make to the package source aren't having the expected effect.} \item{pkg}{If supplied, \code{is_loading()} only returns \code{TRUE} if the package being loaded is \code{pkg}.} } \description{ \code{load_all()} loads a package. It roughly simulates what happens when a package is installed and loaded with \code{\link[=library]{library()}}, without having to first install the package. It: \itemize{ \item Loads all data files in \verb{data/}. See \code{\link[=load_data]{load_data()}} for more details. \item Sources all R files in the R directory, storing results in environment that behaves like a regular package namespace. See \code{\link[=load_code]{load_code()}} for more details. \item Adds a shim from \code{\link[=system.file]{system.file()}} to \code{\link[=shim_system.file]{shim_system.file()}} in the imports environment of the package. This ensures that \code{system.file()} works with both development and installed packages despite their differing directory structures. \item Adds shims from \code{help()} and \verb{?} to \code{\link[=shim_help]{shim_help()}} and \code{\link[=shim_question]{shim_question()}} to make it easier to preview development documentation. \item Compiles any C, C++, or Fortran code in the \verb{src/} directory and connects the generated DLL into R. See \code{\link[pkgbuild:compile_dll]{pkgbuild::compile_dll()}} for more details. \item Loads any compiled translations in \code{inst/po}. \item Runs \code{.onAttach()}, \code{.onLoad()} and \code{.onUnload()} functions at the correct times. \item If you use \pkg{testthat}, will load all test helpers so you can access them interactively. devtools sets the \code{DEVTOOLS_LOAD} environment variable to the package name to let you check whether the helpers are run during package loading. } \code{is_loading()} returns \code{TRUE} when it is called while \code{load_all()} is running. This may be useful e.g. in \code{.onLoad} hooks. } \section{Differences to regular loading}{ \code{load_all()} tries its best to reproduce the behaviour of \code{\link[=loadNamespace]{loadNamespace()}} and \code{\link[=library]{library()}}. However it deviates from normal package loading in several ways. \itemize{ \item \code{load_all()} doesn't install the package to a library, so \code{\link[=system.file]{system.file()}} doesn't work. pkgload fixes this for the package itself installing a shim, \code{\link[=shim_system.file]{shim_system.file()}}. However, this shim is not visible to third party packages, so they will fail if they attempt to find files within your package. One potential workaround is to use \code{\link[fs:path_package]{fs::path_package()}} instead of \code{system.file()}, since that understands the mechanisms that devtools uses to load packages. \item \code{load_all()} loads all packages referenced in \code{Imports} at load time, but \code{loadNamespace()} and \code{library()} only load package dependencies as they are needed. \item \code{load_all()} copies all objects (not just the ones listed as exports) into the package environment. This is useful during development because it makes internal objects easy to access. To export only the objects listed as exports, use \code{export_all = FALSE}. This more closely simulates behavior when loading an installed package with \code{\link[=library]{library()}}, and can be useful for checking for missing exports. } } \examples{ \dontrun{ # Load the package in the current directory load_all("./") # Running again loads changed files load_all("./") # With reset=TRUE, unload and reload the package for a clean start load_all("./", TRUE) # With export_all=FALSE, only objects listed as exports in NAMESPACE # are exported load_all("./", export_all = FALSE) } } \keyword{programming} pkgload/man/help.Rd0000644000176200001440000000406514247353057013704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dev-help.R \name{help} \alias{help} \alias{shim_help} \alias{?} \alias{shim_question} \title{Drop-in replacements for help and ? functions} \usage{ # help(topic, package = NULL, ...) # ?e2 # e1?e2 } \arguments{ \item{topic}{A name or character string specifying the help topic.} \item{package}{A name or character string specifying the package in which to search for the help topic. If NULL, search all packages.} \item{...}{Additional arguments to pass to \code{\link[utils:help]{utils::help()}}.} \item{e1}{First argument to pass along to \verb{utils::}?``.} \item{e2}{Second argument to pass along to \verb{utils::}?``.} } \description{ The \verb{?} and \code{help} functions are replacements for functions of the same name in the utils package. They are made available when a package is loaded with \code{\link[=load_all]{load_all()}}. } \details{ The \verb{?} function is a replacement for \code{\link[utils:Question]{utils::?()}} from the utils package. It will search for help in devtools-loaded packages first, then in regular packages. The \code{help} function is a replacement for \code{\link[utils:help]{utils::help()}} from the utils package. If \code{package} is not specified, it will search for help in devtools-loaded packages first, then in regular packages. If \code{package} is specified, then it will search for help in devtools-loaded packages or regular packages, as appropriate. } \examples{ \dontrun{ # This would load devtools and look at the help for load_all, if currently # in the devtools source directory. load_all() ?load_all help("load_all") } # To see the help pages for utils::help and utils::`?`: help("help", "utils") help("?", "utils") \dontrun{ # Examples demonstrating the multiple ways of supplying arguments # NB: you can't do pkg <- "ggplot2"; help("ggplot2", pkg) help(lm) help(lm, stats) help(lm, 'stats') help('lm') help('lm', stats) help('lm', 'stats') help(package = stats) help(package = 'stats') topic <- "lm" help(topic) help(topic, stats) help(topic, 'stats') } } pkgload/man/check_dep_version.Rd0000644000176200001440000000105614247353057016423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package-deps.R \name{check_dep_version} \alias{check_dep_version} \title{Check that the version of an imported package satisfies the requirements} \usage{ check_dep_version(dep_name, dep_ver = "*") } \arguments{ \item{dep_name}{The name of the package with objects to import} \item{dep_ver}{The version of the package, this includes the specified comparison operator.} } \description{ Check that the version of an imported package satisfies the requirements } \keyword{internal} pkgload/man/dev_meta.Rd0000644000176200001440000000114014502515617014523 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dev-meta.R \name{dev_meta} \alias{dev_meta} \title{Return devtools metadata environment} \usage{ dev_meta(name) } \arguments{ \item{name}{The name of a loaded package} } \description{ If the package was not loaded with devtools, returns \code{NULL}. } \examples{ dev_meta("stats") # NULL if (has_tests()) { # Load the test package in directory "testLoadHooks" load_all(pkgtest("testLoadHooks")) # Get metadata for the package x <- dev_meta("testLoadHooks") as.list(x) # Clean up. unload("testLoadHooks") } } \keyword{internal} pkgload/man/parse_deps.Rd0000644000176200001440000000124714247353057015100 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package-deps.R \name{parse_deps} \alias{parse_deps} \title{Parse package dependency strings.} \usage{ parse_deps(string) } \arguments{ \item{string}{to parse. Should look like \code{"R (>= 3.0), ggplot2"} etc.} } \value{ list of two character vectors: \code{name} package names, and \code{version} package versions. If version is not specified, it will be stored as NA. } \description{ Parse package dependency strings. } \examples{ parse_deps("httr (< 2.1),\nRCurl (>= 3)") # only package dependencies are returned parse_deps("utils (== 2.12.1),\ntools,\nR (>= 2.10),\nmemoise") } \keyword{internal} pkgload/man/ns_env.Rd0000644000176200001440000000143114247353057014236 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/namespace-env.R \name{ns_env} \alias{ns_env} \title{Return the namespace environment for a package.} \usage{ ns_env(package) } \arguments{ \item{package}{package name.} } \description{ Contains all (exported and non-exported) objects, and is a descendant of \code{R_GlobalEnv}. The hierarchy is \verb{}, \verb{}, \verb{}, and then \code{R_GlobalEnv}. } \details{ If the package is not loaded, this function returns \code{NULL}. } \seealso{ \code{\link[=pkg_env]{pkg_env()}} for the attached environment that contains the exported objects. \code{\link[=imports_env]{imports_env()}} for the environment that contains imported objects for the package. } \keyword{internal} pkgload/man/pkg_env.Rd0000644000176200001440000000211714247353057014401 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package-env.R \name{pkg_env} \alias{pkg_env} \title{Return package environment} \usage{ pkg_env(package) } \arguments{ \item{package}{package name.} } \description{ This is an environment like \verb{}. The package environment contains the exported objects from a package. It is attached, so it is an ancestor of \code{R_GlobalEnv}. } \details{ When a package is loaded the normal way, using \code{\link[=library]{library()}}, this environment contains only the exported objects from the namespace. However, when loaded with \code{\link[=load_all]{load_all()}}, this environment will contain all the objects from the namespace, unless \code{load_all} is used with \code{export_all=FALSE}. If the package is not attached, this function returns \code{NULL}. } \seealso{ \code{\link[=ns_env]{ns_env()}} for the namespace environment that all the objects (exported and not exported). \code{\link[=imports_env]{imports_env()}} for the environment that contains imported objects for the package. } \keyword{internal} pkgload/man/parse_ns_file.Rd0000644000176200001440000000066514247353057015567 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/namespace-env.R \name{parse_ns_file} \alias{parse_ns_file} \title{Parses the NAMESPACE file for a package} \usage{ parse_ns_file(path = ".") } \arguments{ \item{path}{Path to a package, or within a package.} } \description{ Parses the NAMESPACE file for a package } \examples{ if (has_tests()) { parse_ns_file(pkgtest("testLoadHooks")) } } \keyword{internal} pkgload/man/pkgtest.Rd0000644000176200001440000000071314247353057014431 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/has_tests.R \name{pkgtest} \alias{pkgtest} \title{Return the path to one of the packages in the devtools test dir} \usage{ pkgtest(package) } \arguments{ \item{package}{Name of the test package.} } \description{ devtools comes with some simple packages for testing. This function returns the path to them. } \examples{ if (has_tests()) { pkgtest("testData") } } \keyword{internal} pkgload/DESCRIPTION0000644000176200001440000000313714551472164013416 0ustar liggesusersPackage: pkgload Title: Simulate Package Installation and Attach Version: 1.3.4 Authors@R: c( person("Hadley", "Wickham", role = "aut"), person("Winston", "Chang", role = "aut"), person("Jim", "Hester", role = "aut"), person("Lionel", "Henry", , "lionel@posit.co", role = c("aut", "cre")), person("Posit Software, PBC", role = c("cph", "fnd")), person("R Core team", role = "ctb", comment = "Some namespace and vignette code extracted from base R") ) Description: Simulates the process of installing a package and then attaching it. This is a key part of the 'devtools' package as it allows you to rapidly iterate while developing a package. License: GPL-3 URL: https://github.com/r-lib/pkgload, https://pkgload.r-lib.org BugReports: https://github.com/r-lib/pkgload/issues Depends: R (>= 3.4.0) Imports: cli (>= 3.3.0), crayon, desc, fs, glue, methods, pkgbuild, rlang (>= 1.1.1), rprojroot, utils, withr (>= 2.4.3) Suggests: bitops, covr, mathjaxr, mockr, pak, Rcpp, remotes, rstudioapi, testthat (>= 3.1.0) Config/Needs/website: tidyverse/tidytemplate, ggplot2 Config/testthat/edition: 3 Config/testthat/parallel: TRUE Config/testthat/start-first: dll Encoding: UTF-8 RoxygenNote: 7.2.3 NeedsCompilation: no Packaged: 2024-01-16 10:14:57 UTC; lionel Author: Hadley Wickham [aut], Winston Chang [aut], Jim Hester [aut], Lionel Henry [aut, cre], Posit Software, PBC [cph, fnd], R Core team [ctb] (Some namespace and vignette code extracted from base R) Maintainer: Lionel Henry Repository: CRAN Date/Publication: 2024-01-16 12:20:04 UTC pkgload/tests/0000755000176200001440000000000014551453441013043 5ustar liggesuserspkgload/tests/testthat/0000755000176200001440000000000014551472164014706 5ustar liggesuserspkgload/tests/testthat/testLoadHooks/0000755000176200001440000000000014247353057017472 5ustar liggesuserspkgload/tests/testthat/testLoadHooks/DESCRIPTION0000644000176200001440000000031114247353057021173 0ustar liggesusersPackage: testLoadHooks Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testLoadHooks/R/0000755000176200001440000000000014247655327017700 5ustar liggesuserspkgload/tests/testthat/testLoadHooks/R/a.r0000644000176200001440000000177214247655327020312 0ustar liggesusersns_locked <- TRUE pkg_locked <- TRUE the <- new.env() the$a <- 1 the$b <- 1 the$c <- 1 the$onload_lib <- "" the$onattach_lib <- "" .onLoad <- function(lib, pkg) { hook <- getOption("pkgload:::testLoadHooks::.onLoad") if (is.function(hook)) { hook() } # Namespace is not sealed at this point ns_locked <<- FALSE the$onload_lib <- lib the$a <- the$a + 1 } .onAttach <- function(lib, pkg) { the$onattach_lib <- lib # Attempt to modify b in namespace. This throws an error because the # namespace is sealed at this point. expect_error(pkg_locked <<- FALSE) the$b <- the$b + 1 # The package env is not populated with internal helpers when the # hook is run env <- as.environment("package:testLoadHooks") if (!is.null(env$the)) { the$c <- the$c + 1 } } .onUnload <- function(libpath) { # Increment this variable if it exists in the global env if (exists(".__testLoadHooks__", .GlobalEnv)) { .GlobalEnv$.__testLoadHooks__ <- .GlobalEnv$.__testLoadHooks__ + 1 } } pkgload/tests/testthat/testImportMissing/0000755000176200001440000000000014247353057020413 5ustar liggesuserspkgload/tests/testthat/testImportMissing/DESCRIPTION0000644000176200001440000000035514247353057022124 0ustar liggesusersPackage: testImportMissing Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Imports: missingpackage Collate: a.r b.r pkgload/tests/testthat/testImportMissing/R/0000755000176200001440000000000014024277455020614 5ustar liggesuserspkgload/tests/testthat/testImportMissing/R/a.r0000644000176200001440000000000713046675565021223 0ustar liggesusersa <- 1 pkgload/tests/testthat/test-examples.Rd0000644000176200001440000000022413046675565017776 0ustar liggesusers\name{foo} \alias{foo} \title{foo} \usage{ foo() } \description{ } \examples{ a <- 1 \donttest{a <- 2} \dontrun{a <- 3} } \keyword{internal} pkgload/tests/testthat/test-depend.R0000644000176200001440000000357314247353057017256 0ustar liggesuserslocal_load_all_quiet() test_that("Warn about mismatched version", { # Should give a warning about grid version expect_snapshot({ (expect_error( load_all("testImportVersion"), class = "rlib_error_package_not_found" )) }) unload("testImportVersion") }) test_that("Error on missing dependencies", { expect_snapshot({ (expect_error( load_all("testImportMissing"), class = "rlib_error_package_not_found" )) }) # Loading process will be partially done; unload it unload("testImportMissing") }) test_that("Packages in depends are required", { load_all("testDependMissing") expect_true("package:bitops" %in% search()) unload("testDependMissing") detach("package:bitops", unload = TRUE) }) test_that("Parse dependencies", { deps <- parse_deps("\nhttr (< 2.1),\nRCurl (>= 3),\nutils (== 2.12.1),\ntools,\nR (>= 2.10),\nmemoise") expect_equal(nrow(deps), 5) expect_false("R" %in% deps$name) expect_equal(deps$compare, c("<", ">=", "==", NA, NA)) expect_equal(deps$version, c("2.1", "3", "2.12.1", NA, NA)) # Invalid version specifications expect_snapshot({ (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (3.0)"))) (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl ( 3.0)"))) (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (==3.0)"))) (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (==3.0 )"))) (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl ( ==3.0)"))) }) # This should be OK (no error) deps <- parse_deps("\nhttr (< 2.1),\nRCurl (== 3.0.1)") expect_equal(deps$compare, c("<", "==")) expect_equal(deps$version, c("2.1", "3.0.1")) }) test_that("Declared dependencies are added to .Depends object", { skip_if_not_installed("httr") load_all("testDependsExists") expect_equal(get(".Depends", "package:testDependsExists", inherits = FALSE), "httr") unload("testDependsExists") }) pkgload/tests/testthat/test-examples.R0000644000176200001440000000217114247353057017626 0ustar liggesuserslocal_load_all_quiet() test_that("default run_example ignores donttest and dontrun ", { env <- run_example(test_path("test-examples.Rd"), quiet = TRUE) expect_equal(env$a, 1) }) test_that("run donttest when requested", { env <- run_example(test_path("test-examples.Rd"), run_donttest = TRUE, quiet = TRUE) expect_equal(env$a, 2) }) test_that("run dontrun when requested", { env <- run_example(test_path("test-examples.Rd"), run_dontrun = TRUE, quiet = TRUE) expect_equal(env$a, 3) }) test_that("can run example package", { load_all(test_path("testHelp")) on.exit(unload(test_path("testHelp"))) env <- dev_example("foofoo", quiet = TRUE) expect_equal(env$a, 101) }) test_that("can use system macros", { load_all(test_path("testHelp")) on.exit(unload(test_path("testHelp"))) expect_silent( run_example( test_path("testHelp", "man", "testSysMacro.Rd"), quiet = TRUE ) ) }) test_that("can use extra Rd macros", { macros <- load_rd_macros("testHelp") expect_silent( run_example( test_path("testHelp", "man", "testCustomMacro.Rd"), quiet = TRUE, macros = macros ) ) }) pkgload/tests/testthat/test-source.R0000644000176200001440000000021014247353057017300 0ustar liggesuserstest_that("multiplication works", { expect_snapshot(error = TRUE, { source_many(test_path("testSource", c("a.R", "b.R"))) }) }) pkgload/tests/testthat/test-load-hooks.R0000644000176200001440000001173114247655327020057 0ustar liggesuserslocal_load_all_quiet() test_that("hooks called in correct order", { record_use <- function(hook) { function(...) { h <- globalenv()$hooks h$events <- c(h$events, hook) } } reset_events <- function() { assign("hooks", new.env(parent = emptyenv()), envir = globalenv()) h <- globalenv()$hooks h$events <- character() } setHook(packageEvent("testHooks", "attach"), record_use("user_attach")) setHook(packageEvent("testHooks", "detach"), record_use("user_detach")) setHook(packageEvent("testHooks", "onLoad"), record_use("user_load")) setHook(packageEvent("testHooks", "onUnload"), record_use("user_unload")) reset_events() load_all("testHooks") expect_equal(globalenv()$hooks$events, c("pkg_load", "user_load", "pkg_attach", "user_attach") ) reset_events() load_all("testHooks", reset = FALSE) expect_equal(globalenv()$hooks$events, character()) reset_events() unload("testHooks") expect_equal(globalenv()$hooks$events, c("user_detach", "pkg_detach", "user_unload", "pkg_unload") ) rm(list = "hooks", envir = globalenv()) setHook(packageEvent("testHooks", "attach"), NULL, "replace") setHook(packageEvent("testHooks", "detach"), NULL, "replace") setHook(packageEvent("testHooks", "onLoad"), NULL, "replace") setHook(packageEvent("testHooks", "onUnload"), NULL, "replace") }) test_that("onLoad and onAttach", { ran <- FALSE with_options( "pkgload:::testLoadHooks::.onLoad" = function() { expect_true(is_loading()) expect_true(is_loading("testLoadHooks")) expect_false(is_loading("foobar")) ran <<- TRUE }, load_all("testLoadHooks") ) expect_true(ran) nsenv <- ns_env("testLoadHooks") pkgenv <- pkg_env("testLoadHooks") the <- nsenv$the expect_true(is_reference(the, pkgenv$the)) # normalizePath is needed so that capitalization differences on # case-insensitive platforms won't cause errors. expect_equal(normalizePath(the$onload_lib), normalizePath(getwd())) expect_equal(normalizePath(the$onattach_lib), normalizePath(getwd())) expect_false(nsenv$ns_locked) expect_true(nsenv$pkg_locked) # a: modified by onLoad in namespace env # b: modified by onAttach in namespace env # c: modified by onAttach in package env (no longer the case because # internal bindings are no longer populated at the time the `onAttach` # hook is run) expect_equal(the$a, 2) expect_equal(the$b, 2) expect_equal(the$c, 1) # =================================================================== # Loading again without reset won't change a, b, and c in the # namespace env, and also shouldn't trigger onload or onattach. But # the existing namespace values will be copied over to the package # environment load_all("testLoadHooks", reset = FALSE) # Shouldn't form new environments expect_identical(nsenv, ns_env("testLoadHooks")) expect_identical(pkgenv, pkg_env("testLoadHooks")) expect_equal(the$a, 2) expect_equal(the$b, 2) expect_equal(the$c, 1) # =================================================================== # With reset=TRUE, there should be new package and namespace # environments, and the values should be the same as the first # load_all. load_all("testLoadHooks", reset = TRUE) nsenv2 <- ns_env("testLoadHooks") pkgenv2 <- pkg_env("testLoadHooks") the2 <- nsenv2$the # Should form new environments expect_false(identical(nsenv, nsenv2)) expect_false(identical(pkgenv, pkgenv2)) # Values should be same as first time expect_equal(the2$a, 2) expect_equal(the2$b, 2) expect_equal(the2$c, 1) unload("testLoadHooks") # =================================================================== # Unloading and reloading should create new environments and same # values as first time load_all("testLoadHooks") nsenv3 <- ns_env("testLoadHooks") pkgenv3 <- pkg_env("testLoadHooks") the3 <- nsenv3$the # Should form new environments expect_false(identical(nsenv, nsenv3)) expect_false(identical(pkgenv, pkgenv3)) # Values should be same as first time expect_equal(the3$a, 2) expect_equal(the3$b, 2) expect_equal(the3$c, 1) unload("testLoadHooks") }) test_that("onUnload", { load_all("testLoadHooks") # The onUnload function in testLoadHooks increments this variable .GlobalEnv$.__testLoadHooks__ <- 1 unload("testLoadHooks") expect_equal(.GlobalEnv$.__testLoadHooks__, 2) # Clean up rm(".__testLoadHooks__", envir = .GlobalEnv) }) test_that("user onLoad hooks are properly run", { load_all("testUserLoadHook") expect_condition( load_all("testUserLoadHookUpstream"), class = "hook_was_run" ) unload("testUserLoadHook") unload("testUserLoadHookUpstream") }) test_that("user onLoad hooks are properly run", { load_all("testUserLoadHookError") expect_snapshot({ (expect_warning( expect_condition( load_all("testUserLoadHookUpstream"), class = "hook_was_run_error" ) )) }) unload("testUserLoadHookError") unload("testUserLoadHookUpstream") }) pkgload/tests/testthat/test-namespace.R0000644000176200001440000001071214547266765017760 0ustar liggesuserslocal_load_all_quiet() # Is e an ancestor environment of x? is_ancestor_env <- function(e, x) { if (identical(e, x)) return(TRUE) else if (identical(x, emptyenv())) return(FALSE) else is_ancestor_env(e, parent.env(x)) } # Get parent environment n steps deep parent_env <- function(e, n = 1) { if (n == 0) e else parent_env(parent.env(e), n-1) } test_that("Loaded namespaces have correct version", { load_all("testNamespace") expect_identical(c(version="0.1"), getNamespaceVersion("testNamespace")) unload("testNamespace") }) test_that("Exported objects are visible from global environment", { # a is listed as an export in NAMESPACE, b is not. But with load_all(), # they should both be visible in the global env. load_all("testNamespace") expect_equal(a, 1) expect_equal(b, 2) unload("testNamespace") # With export_all = FALSE, only the listed export should be visible # in the global env. load_all("testNamespace", export_all = FALSE) expect_equal(a, 1) expect_false(exists("b")) unload("testNamespace") }) test_that("Missing exports don't result in error", { expect_warning(load_all("testMissingNsObject")) nsenv <- ns_env("testMissingNsObject") expect_equal(nsenv$a, 1) unload("testMissingNsObject") }) test_that("All objects are loaded into namespace environment", { load_all("testNamespace") nsenv <- ns_env("testNamespace") expect_equal(nsenv$a, 1) expect_equal(nsenv$b, 2) unload("testNamespace") }) test_that("All objects are copied to package environment", { load_all("testNamespace") pkgenv <- pkg_env("testNamespace") expect_equal(pkgenv$a, 1) expect_equal(pkgenv$b, 2) unload("testNamespace") # With export_all = FALSE, only the listed export should be copied load_all("testNamespace", export_all = FALSE) pkgenv <- pkg_env("testNamespace") expect_equal(pkgenv$a, 1) expect_false(exists("b", envir = pkgenv)) unload("testNamespace") }) test_that("Unloading and reloading a package works", { load_all("testNamespace") expect_equal(a, 1) # A load_all() again without unloading shouldn't change things load_all("testNamespace") expect_equal(a, 1) # Unloading should remove objects unload("testNamespace") expect_false(exists('a')) # Loading again should work load_all("testNamespace") expect_equal(a, 1) # Loading with reset should work load_all("testNamespace", reset = TRUE) expect_equal(a, 1) unload("testNamespace") }) test_that("Namespace, imports, and package environments have correct hierarchy", { load_all("testNamespace") pkgenv <- pkg_env("testNamespace") nsenv <- ns_env("testNamespace") impenv <- imports_env("testNamespace") expect_identical(parent_env(nsenv, 1), impenv) expect_identical(parent_env(nsenv, 2), .BaseNamespaceEnv) expect_identical(parent_env(nsenv, 3), .GlobalEnv) # pkgenv should be an ancestor of the global environment expect_true(is_ancestor_env(pkgenv, .GlobalEnv)) unload("testNamespace") }) test_that("unload() removes package environments from search", { load_all("testNamespace") pkgenv <- pkg_env("testNamespace") nsenv <- ns_env("testNamespace") unload("testNamespace") suppressWarnings(unload("compiler")) unload("bitops") # Should report not loaded for package and namespace environments expect_false(is_attached("testNamespace")) expect_false(is_loaded("testNamespace")) # pkgenv should NOT be an ancestor of the global environment # This is what makes the objects inaccessible from global env expect_false(is_ancestor_env(pkgenv, .GlobalEnv)) # Another check of same thing expect_false(pkg_env_name("testNamespace") %in% search()) # R's asNamespace function should error skip_if_not_installed("base", "3.6.0") expect_snapshot({ (expect_error(asNamespace("testNamespace"))) }) }) test_that("Environments have the correct attributes", { load_all("testNamespace") pkgenv <- pkg_env("testNamespace") impenv <- imports_env("testNamespace") # as.environment finds the same package environment expect_identical(pkgenv, as.environment("package:testNamespace")) # Check name attribute of package environment expect_identical(attr(pkgenv, "name"), "package:testNamespace") # Check path attribute of package environment wd <- normalizePath("testNamespace", winslash = "/") expect_identical(wd, attr(pkgenv, "path")) # Check name attribute of imports environment expect_identical(attr(impenv, "name"), "imports:testNamespace") unload("testNamespace") }) pkgload/tests/testthat/testDependsExists/0000755000176200001440000000000014247353057020371 5ustar liggesuserspkgload/tests/testthat/testDependsExists/DESCRIPTION0000644000176200001440000000037714247353057022106 0ustar liggesusersPackage: testDependsExists Title: Packages in Depends are assigned to .Depends object of package environment License: GPL-2 Description: Author: Yiufung Maintainer: Yiufung Version: 0.1 Depends: R, httr pkgload/tests/testthat/testLoadImportUpstreamAlt/0000755000176200001440000000000014551453441022037 5ustar liggesuserspkgload/tests/testthat/testLoadImportUpstreamAlt/NAMESPACE0000644000176200001440000000007714247655327023273 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(internal) pkgload/tests/testthat/testLoadImportUpstreamAlt/DESCRIPTION0000644000176200001440000000070214247655327023555 0ustar liggesusersPackage: testLoadImportUpstreamAlt Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 pkgload/tests/testthat/testLoadImportUpstreamAlt/R/0000755000176200001440000000000014247655327022251 5ustar liggesuserspkgload/tests/testthat/testLoadImportUpstreamAlt/R/upstream-alt.R0000644000176200001440000000004714247655327025013 0ustar liggesusers#' @export internal <- function() NULL pkgload/tests/testthat/test-s4-export.R0000644000176200001440000000135414247353057017657 0ustar liggesuserslocal_load_all_quiet() test_that("importing an S4 exported by another pkg with export_all = FALSE", { load_all("testS4export", export_all = FALSE) # this used to crash with error: # class "class_to_export" is not exported by 'namespace:testS4export' load_all("testS4import", export_all = FALSE) expect_true(isClassDef(getClass("derived"))) load_all("testS4import", export_all = FALSE) cl <- getClass("derived") expect_true(isClassDef(cl)) expect_s4_class(cl@contains$class_to_export, "SClassExtension") expect_equal(cl@contains$class_to_export@distance, 1) expect_s4_class(cl@contains$foo, "SClassExtension") expect_equal(cl@contains$foo@distance, 2) # cleanup unload('testS4import') unload('testS4export') }) pkgload/tests/testthat/testS4sort/0000755000176200001440000000000014247353057017005 5ustar liggesuserspkgload/tests/testthat/testS4sort/NAMESPACE0000644000176200001440000000004413046675565020231 0ustar liggesusersexportClass(A, B, C, D, E, F, G, H) pkgload/tests/testthat/testS4sort/DESCRIPTION0000644000176200001440000000041314247353057020511 0ustar liggesusersPackage: testS4sort Title: Test package for sorting S4 classes License: GPL (>= 2) Description: Author: Facundo Munoz Maintainer: Facundo Munoz Version: 0.1 Collate: 'classes.r' Imports: methods pkgload/tests/testthat/testS4sort/R/0000755000176200001440000000000014024305733017175 5ustar liggesuserspkgload/tests/testthat/testS4sort/R/classes.r0000644000176200001440000000060713046675565021040 0ustar liggesusers## Define a graph of classes with complex inheritance pattern ## example taken from wikipedia: ## https://en.wikipedia.org/wiki/Topological_sorting#Examples setClass("A") setClass("B") setClass("C") setClassUnion("D", members = c("A", "B", "C")) setClass("E") setIs("B", "E") setClassUnion("F", members = c("D", "E")) setClass("G") setIs("D", "G") setClassUnion("H", members = c("C", "E")) pkgload/tests/testthat/test-dll.R0000644000176200001440000000717314247353057016572 0ustar liggesuserslocal_load_all_quiet() test_that("unload() unloads DLLs from packages loaded with library()", { # Make a temp lib directory to install test package into old_libpaths <- .libPaths() tmp_libpath = file.path(tempdir(), "devtools_test") if (!dir.exists(tmp_libpath)) dir.create(tmp_libpath) .libPaths(c(tmp_libpath, .libPaths())) # Reset the libpath on exit on.exit(.libPaths(old_libpaths), add = TRUE) # Install package install.packages(test_path("testDllLoad"), repos = NULL, type = "source", INSTALL_opts = "--no-multiarch", quiet = TRUE) expect_true(require(testDllLoad, quietly = TRUE)) # Check that it's loaded properly, by running a function from the package. # nulltest() calls a C function which returns null. expect_true(is.null(nulltest())) # DLL should be listed in .dynLibs() dynlibs <- vapply(.dynLibs(), `[[`, "name", FUN.VALUE = character(1)) expect_true(any(grepl("testDllLoad", dynlibs))) unload("testDllLoad") # DLL should not be listed in .dynLibs() dynlibs <- vapply(.dynLibs(), `[[`, "name", FUN.VALUE = character(1)) expect_false(any(grepl("testDllLoad", dynlibs))) # Clean out compiled objects pkgbuild::clean_dll("testDllLoad") }) test_that("load_all() compiles and loads DLLs", { pkgbuild::clean_dll("testDllLoad") load_all("testDllLoad", reset = TRUE, quiet = TRUE) # Check that it's loaded properly, by running a function from the package. # nulltest() calls a C function which returns null. expect_true(is.null(nulltest())) # DLL should be listed in .dynLibs() dynlibs <- vapply(.dynLibs(), `[[`, "name", FUN.VALUE = character(1)) expect_true(any(grepl("testDllLoad", dynlibs))) unload("testDllLoad") # DLL should not be listed in .dynLibs() dynlibs <- vapply(.dynLibs(), `[[`, "name", FUN.VALUE = character(1)) expect_false(any(grepl("testDllLoad", dynlibs))) # Loading again, and reloading # Should not re-compile (don't have a proper test for this) load_all("testDllLoad", quiet = TRUE) expect_true(is.null(nulltest())) # load_all when already loaded # Should not re-compile (don't have a proper test for this) load_all("testDllLoad", quiet = TRUE) expect_true(is.null(nulltest())) # Should re-compile (don't have a proper test for this) load_all("testDllLoad", recompile = TRUE, quiet = TRUE) expect_true(is.null(nulltest())) unload("testDllLoad") # Clean out compiled objects pkgbuild::clean_dll("testDllLoad") }) test_that("Specific functions from DLLs listed in NAMESPACE can be called", { load_all("testDllLoad", quiet = TRUE) # nulltest() uses the calling convention: # .Call("null_test", PACKAGE = "testDllLoad") expect_true(is.null(nulltest())) # nulltest2() uses a specific C function listed in NAMESPACE, null_test2 # null_test2 is an object in the packg_env # It uses this calling convention: # .Call(null_test2) expect_true(is.null(nulltest2())) nt2 <- ns_env("testDllLoad")$null_test2 expect_s3_class(nt2, "NativeSymbolInfo") expect_equal(nt2$name, "null_test2") unload("testDllLoad") # Clean out compiled objects pkgbuild::clean_dll("testDllLoad") }) test_that("load_all() can compile and load DLLs linked to Rcpp", { pkgbuild::clean_dll("testDllRcpp") load_all("testDllRcpp", reset = TRUE, quiet = TRUE) # Check that it's loaded properly by calling the hello world function # which returns a list expect_true(is.list(rcpp_hello_world())) # Check whether attribute compilation occurred and that exported # names are available from load_all expect_true(rcpp_test_attributes()) # Unload and clean out compiled objects unload("testDllRcpp") pkgbuild::clean_dll("testDllRcpp") }) pkgload/tests/testthat/test-load.R0000644000176200001440000001074614502255306016726 0ustar liggesuserslocal_load_all_quiet() test_that("Package root and subdirectory is working directory when loading", { expect_message(load_all("testLoadDir"), "[|].*/testLoadDir[|]") expect_message(load_all(file.path("testLoadDir", "R")), "[|].*/testLoadDir[|]") }) test_that("helpers are available after load_all", { load_all("testLoadHelpers") # object defined R/ expect_equal(baz, 1) # object defined in a helper expect_equal(foo, 1) # object defined in helper, referencing lazy data object mtcars2 expect_equal(head_mtcars, head(mtcars2)) # object defined in helper using explicitly qualified package name expect_equal(helper_baz, baz) unload("testLoadHelpers") }) test_that("`quiet` argument works (#213)", { expect_message(load_all(test_path("testLoadHelpers"), quiet = FALSE), "Loading") expect_no_message(load_all(test_path("testLoadHelpers"), quiet = TRUE)) }) test_that("warn_if_conflicts warns for conflicts and both objects are functions", { e1 <- new.env(parent = emptyenv()) e2 <- new.env(parent = emptyenv()) e1$foo <- function() "foo" e2$bar <- function() "bar" # no warning if no conflicts expect_warning(warn_if_conflicts("pkg", e1, e2), NA) e2$foo <- function() "foo2" # warning for a conflict expect_snapshot({ (expect_warning(warn_if_conflicts("pkg", e1, e2))) }) }) test_that("warn_if_conflicts does not warn for conflicts when one of the objects is not a function", { e1 <- new.env(parent = emptyenv()) e2 <- new.env(parent = emptyenv()) e1$foo <- function() "foo" e2$foo <- "foo" expect_warning(warn_if_conflicts("pkg", e1, e2), NA) }) test_that("unloading or reloading forces bindings", { forced <- FALSE withCallingHandlers( forced = function(...) forced <<- TRUE, { # Allow running test interactively on.exit(unload("testLoadLazy")) # On older R versions, `env_coalesce()` forces bindings attach <- getRversion() >= "4.0.0" load_all("testLoadLazy", attach = attach) expect_false(forced) load_all("testLoadLazy") expect_true(forced) } ) }) test_that("unloading or reloading does not call active bindings", { on.exit(unload("testActiveBindings")) expect_no_error(load_all(test_path("testActiveBindings"))) }) test_that("reloading a package unloads deleted S3 methods", { x <- structure(list(), class = "pkgload_foobar") load_all("testS3removed") expect_equal(as.character(x), "registered") # Hold a reference to the generic in the currently loaded namespace stale_generic <- testS3removed::my_generic load_all("testS3removed2") expect_equal(as.character(x), character()) # Still works because we don't unregister methods for the package # being unloaded (r-lib/vctrs#1341) expect_equal(stale_generic(x), "registered") }) test_that("reloading a package reloads foreign methods (#163)", { x <- structure(list(), class = "foreign_foobar") load_all("testS3removed") registerS3method( "my_generic", "foreign_foobar", function(...) "OK", envir = ns_env("testS3removed") ) expect_equal(my_generic(x), "OK") load_all("testS3removed") expect_equal(my_generic(x), "OK") }) test_that("reloading a package reloads own methods", { x <- structure(list(), class = "pkgload_foobar") load_all("testS3removed") ns <- ns_env("testS3removed") method <- function(...) "Not OK" environment(method) <- ns registerS3method( "my_generic", "pkgload_foobar", method, envir = ns ) # `registerS3method()` doesn't seem to overwrite methods on older # versions of R < 3.5.0. if (is_installed("base", "3.5.0")) { expect_equal(my_generic(x), "Not OK") } load_all("testS3removed") expect_equal(my_generic(x), "registered") }) test_that("load_all() errors when no DESCRIPTION found", { withr::with_tempdir({ (expect_error(load_all(), class = "pkgload_no_desc")) }) }) test_that("can load without attaching", { load_all("testLoadAttach", attach = FALSE) expect_false(is_attached("testLoadAttach")) load_all("testLoadAttach", attach = TRUE) expect_true(is_attached("testLoadAttach")) }) test_that("internal functions exported to the search path are not imported in downstream packages", { # This package has an internal function called `internal` load_all(test_path("testLoadImportUpstream")) # This package exports a function called `internal` load_all(test_path("testLoadImportUpstreamAlt")) # This package imports both packages above expect_no_warning( load_all(test_path("testLoadImportDownstream")) ) }) pkgload/tests/testthat/testDataLazy/0000755000176200001440000000000014024405505017305 5ustar liggesuserspkgload/tests/testthat/testDataLazy/NAMESPACE0000644000176200001440000000002713046675565020545 0ustar liggesusersexport(sysdata_export) pkgload/tests/testthat/testDataLazy/data/0000755000176200001440000000000014024324120020207 5ustar liggesuserspkgload/tests/testthat/testDataLazy/data/b.r0000644000176200001440000000000713046675565020641 0ustar liggesusersb <- 2 pkgload/tests/testthat/testDataLazy/data/a.rda0000644000176200001440000000007313046675565021150 0ustar liggesusers‹ r‰0âŠàb```b`âbf “… H02°0p‚èD ÁbØ`€(+ýL8pkgload/tests/testthat/testDataLazy/DESCRIPTION0000644000176200001440000000031213046675565021031 0ustar liggesusersPackage: testDataLazy Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 LazyData: true pkgload/tests/testthat/testDataLazy/R/0000755000176200001440000000000014024302255017504 5ustar liggesuserspkgload/tests/testthat/testDataLazy/R/sysdata.rda0000644000176200001440000000013013046675565021662 0ustar liggesusers‹ r‰0âŠàb```b`âgf`b2Y˜€# 'æ+®,NI,IŒO­(È/*‰€d8 Eµ Lu^~š˜†5µÝvpkgload/tests/testthat/testS4import/0000755000176200001440000000000014024307730017316 5ustar liggesuserspkgload/tests/testthat/testS4import/NAMESPACE0000644000176200001440000000006213046675565020554 0ustar liggesusersimportClassesFrom(testS4export, class_to_export) pkgload/tests/testthat/testS4import/DESCRIPTION0000644000176200001440000000060213046675565021043 0ustar liggesusersPackage: testS4import Title: reproduce S4 import bug with devtools Version: 0.1 Description: reproduce S4 import bug with devtools. See testS4export Author: Karl Forner Maintainer: Karl Forner Depends: R (>= 2.15) Imports: methods, testS4export Suggests: testthat (>= 0.7.1.99), License: GPL (>= 2) Collate: all.r pkgload/tests/testthat/testS4import/R/0000755000176200001440000000000014210101433017504 5ustar liggesuserspkgload/tests/testthat/testS4import/R/all.r0000644000176200001440000000006114210101433020434 0ustar liggesuserssetClass('derived', contains='class_to_export') pkgload/tests/testthat/testLoadDir/0000755000176200001440000000000014024300017017102 5ustar liggesuserspkgload/tests/testthat/testLoadDir/DESCRIPTION0000644000176200001440000000030713046675565020642 0ustar liggesusersPackage: testLoadDir Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testLoadDir/R/0000755000176200001440000000000014024303732017312 5ustar liggesuserspkgload/tests/testthat/testLoadDir/R/a.r0000644000176200001440000000003313046675565017734 0ustar liggesusersmessage("|", getwd(), "|") pkgload/tests/testthat/testS3removed/0000755000176200001440000000000014551453441017452 5ustar liggesuserspkgload/tests/testthat/testS3removed/NAMESPACE0000644000176200001440000000021314247353057020671 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.character,pkgload_foobar) S3method(my_generic,pkgload_foobar) export(my_generic) pkgload/tests/testthat/testS3removed/DESCRIPTION0000644000176200001440000000032014247353057021157 0ustar liggesusersPackage: testS3removed Title: Test package with S3 method removed (before) License: MIT Author: Lionel Henry Maintainer: Lionel Henry Version: 1.0 RoxygenNote: 7.1.1 pkgload/tests/testthat/testS3removed/R/0000755000176200001440000000000014247353057017657 5ustar liggesuserspkgload/tests/testthat/testS3removed/R/S3.r0000644000176200001440000000033114247353057020324 0ustar liggesusers#' @export as.character.pkgload_foobar <- function(x, ...) { "registered" } #' @export my_generic <- function(x) { UseMethod("my_generic") } #' @export my_generic.pkgload_foobar <- function(x) { "registered" } pkgload/tests/testthat/helper-pkgload.R0000644000176200001440000000150114547270266017730 0ustar liggesuserslocal_load_all_quiet <- function(value = TRUE, frame = caller_env()) { local_options("testthat:::load_all_quiet_default" = value, .frame = frame) } expect_no_warning <- function(object) { expect_warning({{ object }}, NA) } expect_no_message <- function(object) { expect_message({{ object }}, NA) } suppress_output <- function(expr) { capture.output( capture.output( expr, type = "message" ), type = "output" ) } # Used to skip tests that will fail when locale is set to C, for # instance `with_language()` tests. These tests should only be run # when using a locale like `en_US`. skip_if_c_locale <- function() { lc_all <- Sys.getenv("LC_ALL", "") skip_if(lc_all %in% c("C", "C.UTF-8")) if (lc_all == "") { lang <- Sys.getenv("LANG", "") skip_if(lang %in% c("C", "C.UTF-8")) } } pkgload/tests/testthat/test-metadata.R0000644000176200001440000000265114247353057017573 0ustar liggesuserslocal_load_all_quiet() test_that("devtools metadata for load hooks", { # testLoadHooks test package has .onLoad and .onAttach load_all("testLoadHooks") md <- dev_meta("testLoadHooks") expect_true(md$.onLoad) expect_true(md$.onAttach) unload("testLoadHooks") # testNamespace test package doesn't have .onLoad and .onAttach load_all("testNamespace") md <- dev_meta("testNamespace") expect_false(exists("onLoad", envir = md)) expect_false(exists("onAttach", envir = md)) unload("testNamespace") }) test_that("NULL metadata for non-devtools-loaded packages", { expect_true(is.null(dev_meta("stats"))) }) test_that("dev_packages() lists devtools-loaded packages", { expect_false(any(c("testNamespace", "testLoadHooks") %in% dev_packages())) expect_false("testNamespace" %in% dev_packages()) expect_false("testLoadHooks" %in% dev_packages()) load_all("testNamespace") expect_true("testNamespace" %in% dev_packages()) expect_false("testLoadHooks" %in% dev_packages()) load_all("testLoadHooks") expect_true("testNamespace" %in% dev_packages()) expect_true("testLoadHooks" %in% dev_packages()) unload("testNamespace") expect_false("testNamespace" %in% dev_packages()) expect_true("testLoadHooks" %in% dev_packages()) unload("testLoadHooks") expect_false("testNamespace" %in% dev_packages()) expect_false("testLoadHooks" %in% dev_packages()) expect_false("stats" %in% dev_packages()) }) pkgload/tests/testthat/testSource/0000755000176200001440000000000014247353057017047 5ustar liggesuserspkgload/tests/testthat/testSource/a.R0000644000176200001440000000000714247353057017407 0ustar liggesusersa <- 1 pkgload/tests/testthat/testSource/b.R0000644000176200001440000000000514247353057017406 0ustar liggesusersb <- pkgload/tests/testthat/testMissingNsObject/0000755000176200001440000000000014024306643020640 5ustar liggesuserspkgload/tests/testthat/testMissingNsObject/NAMESPACE0000644000176200001440000000002313046675565022071 0ustar liggesusersexport(a) export(b)pkgload/tests/testthat/testMissingNsObject/DESCRIPTION0000644000176200001440000000031513046675565022364 0ustar liggesusersPackage: testMissingNsObject Title: Tools to make developing R code easier. This package lists 'b' as an export in NAMESPACE, but the 'b' object doesn't exist. License: GPL-2 Description: Version: 0.1 pkgload/tests/testthat/testMissingNsObject/R/0000755000176200001440000000000014024310177021036 5ustar liggesuserspkgload/tests/testthat/testMissingNsObject/R/a.r0000644000176200001440000000000713046675565021460 0ustar liggesusersa <- 1 pkgload/tests/testthat/test-extraction.R0000644000176200001440000000215014247353057020165 0ustar liggesusersf <- function(x) { a <- 1:10 for (i in seq_along(a)) { print(i) } } test_that("extract_lang issues warning if nothing found", { expect_warning(extract_lang(body(f), comp_lang, quote(j)), "pkgload is incompatible") }) test_that("extract_lang and comp_lang finds full statements", { expect_equal(extract_lang(body(f), comp_lang, quote(a <- 1:10)), quote(a <- 1:10)) }) test_that("extract_lang and comp_lang find child calls", { expect_equal(extract_lang(body(f), comp_lang, quote(seq_along(a))), quote(seq_along(a))) }) test_that("extract_lang and comp_lang finds partial statements", { expect_equal(extract_lang(body(f), comp_lang, quote(a <- NULL), 1:2), quote(a <- 1:10)) }) test_that("extract_lang and comp_lang finds partial statements from for conditionals", { expect_equal(extract_lang(body(f), comp_lang, quote(for (i in seq_along(a)) NULL), 1:3), quote(for (i in seq_along(a)) { print(i) })) }) test_that("modify_lang modifies properly", { expect_equal(modify_lang(quote(a <- 1:10), function(x) if (comp_lang(x, quote(a))) quote(b) else x), quote(b <- 1:10)) }) pkgload/tests/testthat/testUnknownMacro/0000755000176200001440000000000014247353057020230 5ustar liggesuserspkgload/tests/testthat/testUnknownMacro/NAMESPACE0000644000176200001440000000005614247353057021450 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testUnknownMacro/man/0000755000176200001440000000000014247353057021003 5ustar liggesuserspkgload/tests/testthat/testUnknownMacro/man/macros/0000755000176200001440000000000014247353057022267 5ustar liggesuserspkgload/tests/testthat/testUnknownMacro/man/macros/macros.Rd0000644000176200001440000000004014247353057024034 0ustar liggesusers\newcommand{\known}{well-known} pkgload/tests/testthat/testUnknownMacro/man/testUnknownMacro.Rd0000644000176200001440000000037514247353057024620 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/testUnknownMacro.R \name{testUnknownMacro} \alias{testUnknownMacro} \title{Topic} \usage{ testUnknownMacro() } \description{ This macro is \unknown{}. This one is \known{}. } pkgload/tests/testthat/testUnknownMacro/DESCRIPTION0000644000176200001440000000067114247353057021742 0ustar liggesusersPackage: testUnknownMacro Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 pkgload/tests/testthat/testUnknownMacro/R/0000755000176200001440000000000014247353057020431 5ustar liggesuserspkgload/tests/testthat/testUnknownMacro/R/testUnknownMacro.R0000644000176200001440000000014114247353057024071 0ustar liggesusers#' Topic #' #' This macro is \unknown{}. This one is \known{}. testUnknownMacro <- function() {} pkgload/tests/testthat/testS4union/0000755000176200001440000000000014551453441017142 5ustar liggesuserspkgload/tests/testthat/testS4union/NAMESPACE0000644000176200001440000000011013046675565020364 0ustar liggesusersexportClass(A, B, AB, mle2, mleA, mle2A) importClassesFrom(stats4, mle) pkgload/tests/testthat/testS4union/DESCRIPTION0000644000176200001440000000037313046675565020666 0ustar liggesusersPackage: testS4union Title: Test package for S4 class unions License: GPL-2 Description: Author: Winston Chang Maintainer: Winston Chang Version: 0.1 Collate: 'classes.r' Imports: stats4, methods pkgload/tests/testthat/testS4union/R/0000755000176200001440000000000014247353057017347 5ustar liggesuserspkgload/tests/testthat/testS4union/R/classes.r0000644000176200001440000000046314247353057021172 0ustar liggesuserssetClass("A") setClass("B") setClassUnion("AB", members = c("A", "B")) setClass("mle2", contains = "mle") setClassUnion("mleA", members = c("mle", "A")) setClassUnion("mle2A", members = c("mle2", "A")) setClassUnion("AOrNull", members = c("A", "NULL")) setClassUnion("BOrNull", members = c("B", "NULL")) pkgload/tests/testthat/test-package.R0000644000176200001440000000053714247353057017407 0ustar liggesuserslocal_load_all_quiet() test_that("it can load from outside of package root", { expect_false('testHooks' %in% loadedNamespaces()) load_all(file.path("testHooks")) expect_true('testHooks' %in% loadedNamespaces()) expect_true(is_dev_package("testHooks")) unload(file.path("testHooks")) expect_false('testHooks' %in% loadedNamespaces()) }) pkgload/tests/testthat/testImportVersion/0000755000176200001440000000000014247353057020427 5ustar liggesuserspkgload/tests/testthat/testImportVersion/NAMESPACE0000644000176200001440000000001213046675565021646 0ustar liggesusersexport(a) pkgload/tests/testthat/testImportVersion/DESCRIPTION0000644000176200001440000000040714247353057022136 0ustar liggesusersPackage: testImportVersion Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Imports: grid (>= 100.0), compiler (>= 2.0-0) Collate: a.r b.r pkgload/tests/testthat/testImportVersion/R/0000755000176200001440000000000014024305433020614 5ustar liggesuserspkgload/tests/testthat/testImportVersion/R/a.r0000644000176200001440000000000713046675565021237 0ustar liggesusersa <- 1 pkgload/tests/testthat/testImportVersion/R/b.r0000644000176200001440000000000713046675565021240 0ustar liggesusersb <- 2 pkgload/tests/testthat/testLibDynam/0000755000176200001440000000000014247353057017306 5ustar liggesuserspkgload/tests/testthat/testLibDynam/NAMESPACE0000644000176200001440000000004414247353057020523 0ustar liggesusersexport(nulltest3) export(nulltest4) pkgload/tests/testthat/testLibDynam/DESCRIPTION0000644000176200001440000000034714247353057021020 0ustar liggesusersPackage: testLibDynam Title: Test package for loading precompiled DLL/SO placed within inst/libs/ License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testLibDynam/R/0000755000176200001440000000000014247353057017507 5ustar liggesuserspkgload/tests/testthat/testLibDynam/R/a.r0000644000176200001440000000020314247353057020105 0ustar liggesusersa <- 1 nulltest3 <- function() { .Call("null_test", PACKAGE = "testDllLoad") } nulltest4 <- function() { .Call(null_test2) } pkgload/tests/testthat/testLibDynam/R/zzz.R0000644000176200001440000000011314247353057020462 0ustar liggesusers.onLoad <- function(lib, pkg){ library.dynam("testDllLoad", pkg, lib) } pkgload/tests/testthat/testDllLoad/0000755000176200001440000000000014024307371017111 5ustar liggesuserspkgload/tests/testthat/testDllLoad/NAMESPACE0000644000176200001440000000013413046675565020346 0ustar liggesusersuseDynLib(testDllLoad) useDynLib(testDllLoad,null_test2) export(nulltest) export(nulltest2) pkgload/tests/testthat/testDllLoad/DESCRIPTION0000644000176200001440000000031413046675565020635 0ustar liggesusersPackage: testDllLoad Title: Test package for loading and unloading DLLs License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testDllLoad/src/0000755000176200001440000000000014547270342017707 5ustar liggesuserspkgload/tests/testthat/testDllLoad/src/null-test.c0000644000176200001440000000020113046675565022004 0ustar liggesusers#include #include SEXP null_test() { return R_NilValue; } SEXP null_test2() { return R_NilValue; } pkgload/tests/testthat/testDllLoad/R/0000755000176200001440000000000014024304036017305 5ustar liggesuserspkgload/tests/testthat/testDllLoad/R/a.r0000644000176200001440000000020213046675565017727 0ustar liggesusersa <- 1 nulltest <- function() { .Call("null_test", PACKAGE = "testDllLoad") } nulltest2 <- function() { .Call(null_test2) } pkgload/tests/testthat/testDependMissing/0000755000176200001440000000000014247353057020340 5ustar liggesuserspkgload/tests/testthat/testDependMissing/DESCRIPTION0000644000176200001440000000033314247353057022045 0ustar liggesusersPackage: testDependMissing Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Depends: bitops, R pkgload/tests/testthat/testDependMissing/R/0000755000176200001440000000000014024321247020526 5ustar liggesuserspkgload/tests/testthat/testDependMissing/R/a.r0000644000176200001440000000000713046675565021150 0ustar liggesusersa <- 1 pkgload/tests/testthat/testHooks/0000755000176200001440000000000014247353057016672 5ustar liggesuserspkgload/tests/testthat/testHooks/DESCRIPTION0000644000176200001440000000030514247353057020376 0ustar liggesusersPackage: testHooks Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testHooks/R/0000755000176200001440000000000014210101433017046 5ustar liggesuserspkgload/tests/testthat/testHooks/R/a.r0000644000176200001440000000041314210101433017447 0ustar liggesusersrecord_use <- function(hook) { function(...) { h <- globalenv()$hooks h$events <- c(h$events, hook) } } .onLoad <- record_use("pkg_load") .onUnload <- record_use("pkg_unload") .onAttach <- record_use("pkg_attach") .onDetach <- record_use("pkg_detach") pkgload/tests/testthat/testUserLoadHookError/0000755000176200001440000000000014247353057021160 5ustar liggesuserspkgload/tests/testthat/testUserLoadHookError/NAMESPACE0000644000176200001440000000005614247353057022400 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testUserLoadHookError/DESCRIPTION0000644000176200001440000000070314247353057022666 0ustar liggesusersPackage: testUserLoadHookError Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.2.9000 pkgload/tests/testthat/testUserLoadHookError/R/0000755000176200001440000000000014247651401021353 5ustar liggesuserspkgload/tests/testthat/testUserLoadHookError/R/testUserLoadHookError.R0000644000176200001440000000063614247651401025754 0ustar liggesusersthe <- new.env() # Can't fully reset onLoad hook so only run once in case of repeated # `test()` calls the$ran_already <- FALSE .onLoad <- function(...) { setHook( packageEvent("testUserLoadHookUpstream", "onLoad"), function(...) { if (the$ran_already) { return() } the$ran_already <- TRUE rlang::signal("", "hook_was_run_error") stop("The message.") } ) } pkgload/tests/testthat/testCollateExtra/0000755000176200001440000000000014247353057020176 5ustar liggesuserspkgload/tests/testthat/testCollateExtra/DESCRIPTION0000644000176200001440000000032014247353057021677 0ustar liggesusersPackage: testCollateExtra Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r b.r pkgload/tests/testthat/testCollateExtra/R/0000755000176200001440000000000014210101433020352 5ustar liggesuserspkgload/tests/testthat/testCollateExtra/R/a.r0000644000176200001440000000000614210101433020751 0ustar liggesusersa <- 1pkgload/tests/testthat/test-po.R0000644000176200001440000000227114547270167016432 0ustar liggesuserslocal_load_all_quiet() test_that("translation domain correctly loaded", { skip_if_c_locale() load_all(test_path("testTranslations")) withr::defer(unload("testTranslations")) expect_equal(withr::with_language("fr", hello()), "Bonjour") load_all(test_path("testTranslations")) expect_equal(length(temp_po_dirs("testTranslations")), 1) }) test_that("modified translations are correctly reloaded", { skip_if_c_locale() pkg <- withr::local_tempdir() file.copy(dir(test_path("testTranslations"), full.names = TRUE), pkg, recursive = TRUE) # Load package and generate translation load_all(pkg) withr::defer(unload("testTranslations")) withr::with_language("fr", hello()) # Modify .po file po_path <- file.path(pkg, "po", "R-fr.po") po <- readLines(po_path) po[length(po)] <- "msgstr \"Salut\"" writeLines(po, po_path) # Update .mo mo_path <- file.path(pkg, "inst/po/fr/LC_MESSAGES/R-testTranslations.mo") out <- system(paste0("msgfmt -c --statistics -o", mo_path, " ", po_path), ignore.stderr = TRUE) if (out != 0) { stop("Failed to run msgfmt") } # Re-load and re-translate load_all(pkg) expect_equal(withr::with_language("fr", hello()), "Salut") }) pkgload/tests/testthat/testDllRcpp/0000755000176200001440000000000014247353057017147 5ustar liggesuserspkgload/tests/testthat/testDllRcpp/NAMESPACE0000644000176200001440000000014314247353057020364 0ustar liggesusersuseDynLib(testDllRcpp, .registration = TRUE) export(rcpp_hello_world) export(rcpp_test_attributes) pkgload/tests/testthat/testDllRcpp/DESCRIPTION0000644000176200001440000000035714247353057020662 0ustar liggesusersPackage: testDllRcpp Title: Test package for compiling DLLs that link to Rcpp License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Depends: Rcpp (>= 0.10.0) LinkingTo: Rcpp pkgload/tests/testthat/testDllRcpp/src/0000755000176200001440000000000014551453441017732 5ustar liggesuserspkgload/tests/testthat/testDllRcpp/src/rcpp_hello_world.cpp0000644000176200001440000000047414247353057024005 0ustar liggesusers#include // [[Rcpp::export]] SEXP rcpp_hello_world() { using namespace Rcpp; CharacterVector x = CharacterVector::create("foo", "bar"); NumericVector y = NumericVector::create(0.0, 1.0); List z = List::create(x, y); return z; } // [[Rcpp::export]] bool rcpp_test_attributes() { return true; } pkgload/tests/testthat/testDllRcpp/src/RcppExports.cpp0000644000176200001440000000241114547270342022727 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; #ifdef RCPP_USE_GLOBAL_ROSTREAM Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif // rcpp_hello_world SEXP rcpp_hello_world(); RcppExport SEXP _testDllRcpp_rcpp_hello_world() { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; rcpp_result_gen = Rcpp::wrap(rcpp_hello_world()); return rcpp_result_gen; END_RCPP } // rcpp_test_attributes bool rcpp_test_attributes(); RcppExport SEXP _testDllRcpp_rcpp_test_attributes() { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; rcpp_result_gen = Rcpp::wrap(rcpp_test_attributes()); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_testDllRcpp_rcpp_hello_world", (DL_FUNC) &_testDllRcpp_rcpp_hello_world, 0}, {"_testDllRcpp_rcpp_test_attributes", (DL_FUNC) &_testDllRcpp_rcpp_test_attributes, 0}, {NULL, NULL, 0} }; RcppExport void R_init_testDllRcpp(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } pkgload/tests/testthat/testDllRcpp/R/0000755000176200001440000000000014551453441017344 5ustar liggesuserspkgload/tests/testthat/testDllRcpp/R/RcppExports.R0000644000176200001440000000044514547270342021765 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 rcpp_hello_world <- function() { .Call(`_testDllRcpp_rcpp_hello_world`) } rcpp_test_attributes <- function() { .Call(`_testDllRcpp_rcpp_test_attributes`) } pkgload/tests/testthat/test-shim.R0000644000176200001440000001502514247353057016752 0ustar liggesuserslocal_load_all_quiet() # Utility functions ----------------------------- # Take file paths and split them into pieces expand_path <- function(path) { strsplit(path, .Platform$file.sep) } # Return the last n elements of vector x last_n <- function(x, n = 1) { len <- length(x) x[(len-n+1):len] } # Tests ----------------------------------------- test_that("system.file returns correct values when used with load_all", { load_all("testShim") shim_ns <- ns_env("testShim") # The devtools::system.file function should return modified values. files <- shim_system.file(c("A.txt", "B.txt", "C.txt", "D.txt"), package = "testShim") files <- expand_path(files) expect_true(all(last_n(files[[1]], 3) == c("testShim", "inst", "A.txt"))) expect_true(all(last_n(files[[2]], 3) == c("testShim", "inst", "B.txt"))) # Note that C.txt wouldn't be returned by base::system.file (see comments # in shim_system.file for explanation) expect_true(all(last_n(files[[3]], 2) == c("testShim", "C.txt"))) # D.txt should be dropped expect_equal(length(files), 3) # If all files are not present, return "" files <- shim_system.file("nonexistent", package = "testShim") expect_equal(files, "") # Test packages loaded the usual way - should just pass through to # base::system.file expect_identical(base::system.file("Meta", "Rd.rds", package = "stats"), shim_system.file("Meta", "Rd.rds", package = "stats")) expect_identical(base::system.file("INDEX", package = "stats"), shim_system.file("INDEX", package = "stats")) expect_identical(base::system.file("nonexistent", package = "stats"), shim_system.file("nonexistent", package = "stats")) unload("testShim") }) test_that("shimmed system.file respects mustWork", { load_all("testShim") find_missing <- function(mustWork) { shim_system.file("missing.txt", package = "testShim", mustWork = mustWork) } expect_equal(find_missing(FALSE), "") expect_snapshot({ (expect_error(find_missing(TRUE), "Can't find package file.")) }) }) test_that("Shimmed system.file returns correct values when used with load_all", { load_all("testShim") shim_ns <- ns_env("testShim") # Make sure the version of system.file inserted into the namespace's imports # is the same as devtools::system.file expect_identical(get("system.file", envir = shim_ns), shim_system.file) # Another check expect_identical(get_system.file(), shim_system.file) unload("testShim") }) test_that("Replacement system.file returns correct values when installed", { # This set of tests is mostly a sanity check - it doesn't use the special # version of system.file, but it's useful to make sure we know what to look # for in the other tests. # Make a temp lib directory to install test package into old_libpaths <- .libPaths() tmp_libpath = file.path(tempdir(), "devtools_test") if (!dir.exists(tmp_libpath)) dir.create(tmp_libpath) .libPaths(c(tmp_libpath, .libPaths())) install.packages(test_path("testShim"), repos = NULL, type = "source", quiet = TRUE) expect_true(require(testShim, quietly = TRUE)) # The special version of system.file shouldn't exist - this get() will fall # through to the base namespace expect_identical(get("system.file", pos = asNamespace("testShim")), base::system.file) # Test within package testShim files <- get_system.file()(c("A.txt", "B.txt", "C.txt", "D.txt"), package = "testShim") files <- expand_path(files) expect_true(all(last_n(files[[1]], 2) == c("testShim", "A.txt"))) expect_true(all(last_n(files[[2]], 2) == c("testShim", "B.txt"))) expect_equal(length(files), 2) # Third and fourth should be dropped # If all files are not present, return "" files <- get_system.file()("nonexistent", package = "testShim") expect_equal(files, "") detach("package:testShim", unload = TRUE) # Reset the libpath .libPaths(old_libpaths) }) test_that("division operator is not interpreted as a path (#198)", { expect_null(dev_topic_find("/")) }) test_that("system.file() fails if path starts with `inst` (#104)", { expect_true( is_string(shim_system.file(package = "pkgload", mustWork = TRUE)) ) skip_if_not("pkgload" %in% dev_packages()) expect_snapshot({ (expect_error(shim_system.file("inst/WORDLIST", package = "pkgload", mustWork = TRUE))) (expect_error(shim_system.file("inst", "WORDLIST", package = "pkgload", mustWork = TRUE))) }) }) test_that("shim_library.dynam loads compiled dll/so from inst/src/", { skip_on_cran() # Most of the code below is overhead to create a package that contains # a compiled .dll (or .so) within inst/libs/ # The process: # 1. Install the testDllLoad test package (we are going to use its .dll) # 2. Copy the testLibDynam package to a temporary directory # 3. Copy the contents of the libs/ directory from the installed testDllLoad # package into the temporary testLibDynam/inst/libs # 4. test that we can use load_all on the package and that the dll can be used # Make a temp lib directory to install test package into tmp_libpath = file.path(tempdir(), "library-dynam-test") if (!dir.exists(tmp_libpath)) { dir.create(tmp_libpath) } old_libpaths <- .libPaths() .libPaths(c(tmp_libpath, .libPaths())) on.exit(.libPaths(old_libpaths), add = TRUE) # Create temp directory for assembling testLibDynam with dll or so in inst/libs/ temp_dir <-tempdir() file.copy(test_path("testLibDynam"), temp_dir, recursive = TRUE) pkg_dir <- file.path(temp_dir, "testLibDynam") expect_true(file.exists(pkg_dir)) # Install testDllLoad package install.packages( test_path("testDllLoad"), repos = NULL, type = "source", INSTALL_opts = "--no-multiarch", quiet = TRUE ) expect_true(rlang::is_installed("testDllLoad")) pkgbuild::clean_dll("testDllLoad") unload("testDllLoad") # Copy libs/ from installed testDllLoad packageinto testDynLib/inst/libs/ inst_dir <-file.path(pkg_dir, "inst") compiled_libs <- file.path(tmp_libpath, "testDllLoad", "libs") dir.create(file.path(inst_dir, "libs"), recursive = TRUE, showWarnings = FALSE) file.copy(compiled_libs, inst_dir, recursive = TRUE, overwrite = TRUE) load_all(pkg_dir, quiet = TRUE) expect_true(rlang::is_installed("testLibDynam")) # Check that it's loaded properly, by running a function from the package. # nulltest3() calls a C function which returns null. expect_true(is.null(nulltest3())) # Clean out compiled objects pkgbuild::clean_dll("testLibDynam") unload("testLibDynam") # Unlink temporary package dir unlink(pkg_dir, recursive = TRUE) }) pkgload/tests/testthat/test-s4-sort.R0000644000176200001440000000176414247353057017332 0ustar liggesuserslocal_load_all_quiet() load_all("testS4sort") classes <- methods::getClasses(ns_env('testS4sort')) test_that("Example classes are not topologically sorted", { ## there are some superclasses of the first class ## later in the list superclasses <- extends(getClass(classes[1]))[-1] expect_true(any(superclasses %in% classes[-1])) }) test_that("topological sorting s4 classes", { sorted_classes <- sort_s4classes(classes, 'testS4sort') for (idx in seq_along(classes)) { ## for each class in the sorted list ## all its superclasses are before superclasses <- extends(getClass(sorted_classes[idx])) expect_true(all(superclasses %in% head(sorted_classes, idx))) } }) test_that("sorting extreme cases", { ## no classes to sort classes <- vector('character', 0) expect_identical(classes, sort_s4classes(classes, 'testS4sort')) ## only one class to sort classes <- "A" expect_identical(classes, sort_s4classes(classes, 'testS4sort')) }) # cleanup unload('testS4sort') pkgload/tests/testthat/test-namespace-env.R0000644000176200001440000000034014451474005020520 0ustar liggesuserstest_that("respects version separator", { ns <- create_ns_env(test_path("testVersionSep")) withr::defer(unregister_namespace("testVersionSep")) expect_equal(getNamespaceInfo(ns, "spec")[["version"]], "0.0.0-9000") }) pkgload/tests/testthat/testLoadLazy/0000755000176200001440000000000014551453441017322 5ustar liggesuserspkgload/tests/testthat/testLoadLazy/NAMESPACE0000644000176200001440000000007214247353057020544 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(bar) pkgload/tests/testthat/testLoadLazy/DESCRIPTION0000644000176200001440000000026214247353057021034 0ustar liggesusersPackage: testLoadLazy Title: Test package with delayed bindings License: MIT Author: Lionel Henry Maintainer: Lionel Henry Version: 1.0 pkgload/tests/testthat/testLoadLazy/R/0000755000176200001440000000000014247437030017521 5ustar liggesuserspkgload/tests/testthat/testLoadLazy/R/bindings.r0000644000176200001440000000016114247437030021477 0ustar liggesusers delayedAssign("foo", rlang::signal("", "forced")) #' @export delayedAssign("bar", rlang::signal("", "forced")) pkgload/tests/testthat/_snaps/0000755000176200001440000000000014451231442016160 5ustar liggesuserspkgload/tests/testthat/_snaps/source.md0000644000176200001440000000044214547270335020014 0ustar liggesusers# multiplication works Code source_many(test_path("testSource", c("a.R", "b.R"))) Condition Error in `load_all()`: ! Failed to load 'testSource/b.R' Caused by error in `parse()`: ! testSource/b.R:2:0: unexpected end of input 1: b <- ^ pkgload/tests/testthat/_snaps/shim.md0000644000176200001440000000145514547270341017456 0ustar liggesusers# shimmed system.file respects mustWork Code (expect_error(find_missing(TRUE), "Can't find package file.")) Output Error: ! Can't find package file. # system.file() fails if path starts with `inst` (#104) Code (expect_error(shim_system.file("inst/WORDLIST", package = "pkgload", mustWork = TRUE)) ) Output Error in `shim_system.file()`: ! Paths can't start with `inst` i Files in `inst` are installed at top-level. Code (expect_error(shim_system.file("inst", "WORDLIST", package = "pkgload", mustWork = TRUE))) Output Error in `shim_system.file()`: ! Paths can't start with `inst` i Files in `inst` are installed at top-level. pkgload/tests/testthat/_snaps/help.md0000644000176200001440000000170014547270333017440 0ustar liggesusers# shim_question behaves the same as utils::? for nonexistent objects Code (expect_error(utils::`?`(foofoo(123)))) Output Code (expect_error(shim_question(foofoo(123)))) Output # dev_help gives clear error if no packages loaded Code dev_help("foo") Condition Error in `dev_help()`: ! Can't find development documentation because no in-development packages loaded. i Do you need to run `pkgload::load_all()`? # complex expressions are checked Code (expect_error(shim_help({ foo bar }), "must be a name")) Output Error in `shim_help()`: ! `topic` must be a name. pkgload/tests/testthat/_snaps/load-hooks.md0000644000176200001440000000065214547270333020555 0ustar liggesusers# user onLoad hooks are properly run Code (expect_warning(expect_condition(load_all("testUserLoadHookUpstream"), class = "hook_was_run_error")) ) Output Warning: Problem while running user `onLoad` hook for package testUserLoadHookUpstream. i The hook inherits from `namespace:testUserLoadHookError`. Caused by error in `fun()`: ! The message. pkgload/tests/testthat/_snaps/load.md0000644000176200001440000000070614547270333017434 0ustar liggesusers# warn_if_conflicts warns for conflicts and both objects are functions Code (expect_warning(warn_if_conflicts("pkg", e1, e2))) Output Warning: -- Conflicts -------------------------------------------------- pkg conflicts -- x `foo` masks `pkg::foo()`. i Did you accidentally source a file rather than using `load_all()`? Run `rm(list = c("foo"))` to remove the conflicts. pkgload/tests/testthat/_snaps/depend.md0000644000176200001440000000312514547270331017750 0ustar liggesusers# Warn about mismatched version Code (expect_error(load_all("testImportVersion"), class = "rlib_error_package_not_found") ) Output Error in `load_imports()`: ! The package "grid" (>= 100.0) is required. # Error on missing dependencies Code (expect_error(load_all("testImportMissing"), class = "rlib_error_package_not_found") ) Output Error in `load_imports()`: ! The package "missingpackage" is required. # Parse dependencies Code (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (3.0)"))) Output Error in `parse_deps()`: ! Invalid comparison operator in dependency: RCurl (3.0). Code (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl ( 3.0)"))) Output Error in `parse_deps()`: ! Invalid comparison operator in dependency: RCurl ( 3.0). Code (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (==3.0)"))) Output Error in `parse_deps()`: ! Invalid comparison operator in dependency: RCurl (==3.0). Code (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl (==3.0 )"))) Output Error in `parse_deps()`: ! Invalid comparison operator in dependency: ==3.0. Code (expect_error(parse_deps("\nhttr (< 2.1),\nRCurl ( ==3.0)"))) Output Error in `parse_deps()`: ! Invalid comparison operator in dependency: RCurl ( ==3.0). pkgload/tests/testthat/_snaps/namespace.md0000644000176200001440000000033514547270335020451 0ustar liggesusers# unload() removes package environments from search Code (expect_error(asNamespace("testNamespace"))) Output pkgload/tests/testthat/testUserLoadHook/0000755000176200001440000000000014247353057020146 5ustar liggesuserspkgload/tests/testthat/testUserLoadHook/NAMESPACE0000644000176200001440000000005614247353057021366 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testUserLoadHook/DESCRIPTION0000644000176200001440000000067614247353057021665 0ustar liggesusersPackage: testUserLoadHook Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.2.9000 pkgload/tests/testthat/testUserLoadHook/R/0000755000176200001440000000000014247353057020347 5ustar liggesuserspkgload/tests/testthat/testUserLoadHook/R/testUserLoadHook.R0000644000176200001440000000067514247353057023741 0ustar liggesusers.onLoad <- function(...) { stopifnot(!environmentIsLocked(asNamespace("testUserLoadHook"))) setHook( packageEvent("testUserLoadHookUpstream", "onLoad"), function(...) { stopifnot(environmentIsLocked(asNamespace("testUserLoadHookUpstream"))) # The package exports are populated when user onLoad hooks are run stopifnot(is.null(testUserLoadHookUpstream::foo())) rlang::signal("", "hook_was_run") } ) } pkgload/tests/testthat/test-help.R0000644000176200001440000001235214334441036016732 0ustar liggesuserslocal_load_all_quiet() test_that("shim_help behaves the same as utils::help for non-devtools-loaded packages", { # stats wasn't loaded with devtools. There are many combinations of calling # with quotes and without; make sure they're the same both ways. Need to index # in using [1] to drop attributes for which there are unimportant differences. expect_identical(shim_help(lm)[1], utils::help(lm)[1]) expect_identical(shim_help(lm, stats)[1], utils::help(lm, stats)[1]) expect_identical(shim_help(lm, 'stats')[1], utils::help(lm, 'stats')[1]) expect_identical(shim_help('lm')[1], utils::help('lm')[1]) expect_identical(shim_help('lm', stats)[1], utils::help('lm', stats)[1]) expect_identical(shim_help('lm', 'stats')[1], utils::help('lm', 'stats')[1]) expect_identical(shim_help(, "stats")[1], utils::help(, "stats")[1]) # Works for :: and ::: as well (#72) expect_identical(shim_help("::")[1], utils::help("::")[1]) expect_identical(shim_help(":::")[1], utils::help(":::")[1]) }) test_that("shim_help behaves the same as utils::help for nonexistent objects", { expect_equal(length(shim_help(foofoo)), 0) expect_equal(length(shim_help("foofoo")), 0) }) test_that("shim_question behaves the same as utils::? for non-devtools-loaded packages", { expect_identical(shim_question(lm)[1], utils::`?`(lm)[1]) expect_identical(shim_question(stats::lm)[1], utils::`?`(stats::lm)[1]) expect_identical(shim_question(lm(123))[1], utils::`?`(lm(123))[1]) expect_identical(shim_question(`lm`)[1], utils::`?`(`lm`)[1]) expect_identical(shim_question('lm')[1], utils::`?`('lm')[1]) expect_identical(shim_question(base::min)[1], utils::`?`(base::min)[1]) }) test_that("shim_question behaves like util::? for searches", { expect_identical(shim_question(?lm), utils::`?`(?lm)) }) test_that("shim_question behaves the same as utils::? for nonexistent objects", { expect_equal(length(shim_question(foofoo)), 0) expect_equal(length(shim_question(`foofoo`)), 0) expect_equal(length(shim_question("foofoo")), 0) # If given a function call with nonexistent function, error expect_snapshot({ (expect_error(utils::`?`(foofoo(123)))) (expect_error(shim_question(foofoo(123)))) }) }) test_that("show_help and shim_question files for devtools-loaded packages", { load_all(test_path('testHelp')) on.exit(unload(test_path('testHelp'))) h1 <- shim_help("foofoo") expect_s3_class(h1, "dev_topic") expect_equal(h1$topic, "foofoo") expect_equal(h1$pkg, "testHelp") expect_identical(shim_help(foofoo), h1) expect_identical(shim_help(foofoo, "testHelp"), h1) expect_identical(shim_question(testHelp::foofoo), h1) pager_fun <- function(files, header, title, delete.file) { expect_equal(title, "testHelp:foofoo.Rd") } withr::with_options( c(pager = pager_fun), suppressMessages( print(h1, type = 'text') )) }) test_that("shim_help and shim_questions works if topic moves", { load_all(test_path('testHelp')) on.exit(unload(test_path('testHelp'))) path_man <- test_path("testHelp/man/") base_rd_path <- function(x) basename(x$path) expect_equal(base_rd_path(shim_help("foofoo")), "foofoo.Rd") expect_equal(base_rd_path(shim_question("foofoo")), "foofoo.Rd") fs::file_move(fs::path(path_man, "foofoo.Rd"), fs::path(path_man, "barbar.Rd")) on.exit( fs::file_move(fs::path(path_man, "barbar.Rd"), fs::path(path_man, "foofoo.Rd")), add = TRUE ) expect_equal(base_rd_path(shim_help("foofoo")), "barbar.Rd") expect_equal(base_rd_path(shim_question("foofoo")), "barbar.Rd") }) test_that("dev_help works with package and function help with the same name", { load_all(test_path('testHelp')) on.exit(unload(test_path('testHelp'))) h1 <- dev_help("testHelp") expect_identical(shim_question(testHelp::testHelp), h1) }) test_that("dev_help gives clear error if no packages loaded", { mockr::local_mock(dev_packages = function() character()) expect_snapshot(dev_help("foo"), error = TRUE) }) test_that("unknown macros don't trigger warnings (#119)", { load_all(test_path("testUnknownMacro")) expect_no_warning( out <- dev_help("testUnknownMacro") ) # Because we're testing internal behaviour in `tools` skip_on_cran() # Because on RStudio the print method uses a different method skip_if(is_rstudio()) # We should still be displaying a warning when rendering the documentation local_options(pager = function(...) "") suppress_output( expect_warning(print(out), "unknown macro") ) }) test_that("complex expressions are checked", { expect_snapshot({ (expect_error(shim_help({ foo; bar }), "must be a name")) }) }) test_that("can use macros in other packages (#120)", { expect_true(has_rd_macros(test_path("testMacroDownstream/"))) skip_if_not_installed("mathjaxr") load_all(test_path("testMacroDownstream")) topic <- dev_help("macro_downstream") text_lines <- topic_lines(topic, "text") html_lines <- topic_lines(topic, "html") expect_true(any(grepl("foreign macro success", text_lines))) expect_true(any(grepl("foreign macro.*success", html_lines))) }) test_that("httpdPort() is available", { skip_on_cran() # We're using this unexported function to open help pages in RStudio expect_true(is.function(httpdPort)) }) pkgload/tests/testthat/testTranslations/0000755000176200001440000000000014247353057020270 5ustar liggesuserspkgload/tests/testthat/testTranslations/DESCRIPTION0000644000176200001440000000027714247353057022004 0ustar liggesusersPackage: testTranslations Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 pkgload/tests/testthat/testTranslations/R/0000755000176200001440000000000014247353057020471 5ustar liggesuserspkgload/tests/testthat/testTranslations/R/hello.r0000644000176200001440000000011214247353057021751 0ustar liggesusershello <- function() { gettext("Hello", domain = "R-testTranslations") } pkgload/tests/testthat/testTranslations/inst/0000755000176200001440000000000014247353057021245 5ustar liggesuserspkgload/tests/testthat/testTranslations/inst/po/0000755000176200001440000000000014247353057021663 5ustar liggesuserspkgload/tests/testthat/testTranslations/inst/po/fr/0000755000176200001440000000000014247353057022272 5ustar liggesuserspkgload/tests/testthat/testTranslations/inst/po/fr/LC_MESSAGES/0000755000176200001440000000000014247353057024057 5ustar liggesuserspkgload/tests/testthat/testTranslations/inst/po/fr/LC_MESSAGES/R-testTranslations.mo0000644000176200001440000000062614247353057030200 0ustar liggesusersÞ•,<PQ6WŽHelloProject-Id-Version: R 4.0.5 Report-Msgid-Bugs-To: bugs.r-project.org PO-Revision-Date: 2021-10-28 15:02 Last-Translator: Automatically generated Language-Team: none MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Language: fr Plural-Forms: nplurals=2; plural=(n > 1); Bonjourpkgload/tests/testthat/testTranslations/po/0000755000176200001440000000000014247353057020706 5ustar liggesuserspkgload/tests/testthat/testTranslations/po/R-testTranslations.pot0000644000176200001440000000061514247353057025214 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: R 4.0.5\n" "Report-Msgid-Bugs-To: bugs.r-project.org\n" "POT-Creation-Date: 2021-10-28 15:02\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "Hello" msgstr "" pkgload/tests/testthat/testTranslations/po/R-fr.po0000644000176200001440000000067114247353057022060 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: R 4.0.5\n" "Report-Msgid-Bugs-To: bugs.r-project.org\n" "POT-Creation-Date: 2021-10-28 15:02\n" "PO-Revision-Date: 2021-10-28 15:02\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "Hello" msgstr "Bonjour" pkgload/tests/testthat/testLoadImportUpstream/0000755000176200001440000000000014551453441021376 5ustar liggesuserspkgload/tests/testthat/testLoadImportUpstream/NAMESPACE0000644000176200001440000000007714247655327022632 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(exported) pkgload/tests/testthat/testLoadImportUpstream/DESCRIPTION0000644000176200001440000000067714247655327023127 0ustar liggesusersPackage: testLoadImportUpstream Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 pkgload/tests/testthat/testLoadImportUpstream/R/0000755000176200001440000000000014247655327021610 5ustar liggesuserspkgload/tests/testthat/testLoadImportUpstream/R/upstream.R0000644000176200001440000000010414247655327023566 0ustar liggesusers#' @export exported <- function() NULL internal <- function() NULL pkgload/tests/testthat/testLoadImportDownstream/0000755000176200001440000000000014551453441021721 5ustar liggesuserspkgload/tests/testthat/testLoadImportDownstream/NAMESPACE0000644000176200001440000000015714247655327023154 0ustar liggesusers# Generated by roxygen2: do not edit by hand import(testLoadImportUpstream) import(testLoadImportUpstreamAlt) pkgload/tests/testthat/testLoadImportDownstream/DESCRIPTION0000644000176200001440000000070114247655327023436 0ustar liggesusersPackage: testLoadImportDownstream Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 pkgload/tests/testthat/testLoadImportDownstream/R/0000755000176200001440000000000014247655327022133 5ustar liggesuserspkgload/tests/testthat/testLoadImportDownstream/R/downstream.R0000644000176200001440000000011414247655327024435 0ustar liggesusers#' @import testLoadImportUpstream #' @import testLoadImportUpstreamAlt NULL pkgload/tests/testthat/testShim/0000755000176200001440000000000014247353057016507 5ustar liggesuserspkgload/tests/testthat/testShim/NAMESPACE0000644000176200001440000000003013046675565017726 0ustar liggesusersexport(get_system.file) pkgload/tests/testthat/testShim/A.txt0000644000176200001440000000001413046675565017432 0ustar liggesusersfile /A.txt pkgload/tests/testthat/testShim/DESCRIPTION0000644000176200001440000000037214247353057020217 0ustar liggesusersPackage: testShim Title: Tools to make developing R code easier License: GPL-2 Description: This package is for testing the devtools shim system. Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r pkgload/tests/testthat/testShim/C.txt0000644000176200001440000000001413046675565017434 0ustar liggesusersfile /C.txt pkgload/tests/testthat/testShim/R/0000755000176200001440000000000014024310526016673 5ustar liggesuserspkgload/tests/testthat/testShim/R/a.r0000644000176200001440000000045513046675565017326 0ustar liggesusersa <- 1 # When this package is loaded with load_all, devtools should add a # replacement system.file function. # When the package is loaded with load_all, this returns devtools::system.file # When installed and loaded, this returns base:system.file. get_system.file <- function(...) { system.file } pkgload/tests/testthat/testShim/inst/0000755000176200001440000000000014024421220017441 5ustar liggesuserspkgload/tests/testthat/testShim/inst/B.txt0000644000176200001440000000001713046675565020413 0ustar liggesusersfile inst/B.txtpkgload/tests/testthat/testShim/inst/A.txt0000644000176200001440000000002013046675565020404 0ustar liggesusersfile inst/A.txt pkgload/tests/testthat/testLoadHelpers/0000755000176200001440000000000014247353057020011 5ustar liggesuserspkgload/tests/testthat/testLoadHelpers/NAMESPACE0000644000176200001440000000005614247353057021231 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testLoadHelpers/data/0000755000176200001440000000000014247353057020722 5ustar liggesuserspkgload/tests/testthat/testLoadHelpers/data/mtcars2.rda0000644000176200001440000000247014247353057022770 0ustar liggesusersBZh91AY&SY Ž%¿ÿÿÿÿþqÔwÿÿÿöýÝ?ÿÿþB 4L@Y`aKsИ/`ÎÛjšUFì2DhSšˆÓ1OÓ 2zžPi£Ôȵ ShƒCMPÐÐ4=CG¨Bh‰´)´ÑGˆê= 46 =M=@d¦ MHЧêySG”z†ƒz£56‘µA Ä44d¦€4ƒÔ4È4z€ƒ ‚2`&0LÀÀÓb0£ÂhÐ ™2H¤Ñêbh=F4€MC@@ Ä †€ê{§'çüm;zýíkŸz^÷¶6)”ã{»[Úø“dÁ`(¸h[EUB%Ð)K”¥9Ógt+=è¸ÑC* µªn:íÏZîw[ýnœpøû šZ*Í0·M! 4 &˜jT 6”Q!ÕÆÖ3!ññòï¸LMZ&N³*BƒÐÿvÖ$„3²~%Iô ’o G;K®î—qš7ÎSåÕ™)A¾ì'kFÐeç/4%®ÛµyÐEzÔR"!d@0""âîkAÎc#R)) a¥alÀ˜†I&,€‚”1U *РއQä1!7ÛZ=d—aƒÚhB `À#T=ŸÊBÐ:D/XÌZ‚ÁÍEJ«›Ú `‹›-XŸT8JÉ—–M£ Ê€mpq$¸&Ë’ÔgI`#MS@¸ø®¦2b$0‡|\ k#Ô„0êÝ*JÈ¢&æâ1ªXf¥$h_Fæ(‹À‚g´ŠP¿0âümÌZ.P–y”Ñ%{iyÍÍz›_ÂÙ/Gy7æ|õçEÆÝLØQ¨å{7M P°¦%•( 9[Ík^<T^æpsî¦^Ý­~ö"Á1 ô›ãkŸêcÊp8׉›¼®Žê(¥D=‚¡S ©L-¡“—±ØQŒ<ßrŒ©!¤ô> ZšZr[ çtª¾ãXɧHÚ#e#hÔòÑÕh$Ô*„æFÀ†¤X¦J¬- d¸…$¬¾ÞuE‰(‘uYB£Œuè‚ÿQð¸"ñåKnLÚ+Pu]Òk•5ï´îSœH‘¡¨_Wj¤öS©­Ü[µœbôIö°ÙÒ¾q×\dJí¬–Š 1£( ©zØ„Êb-r 1g ª¢yBÓ;Æ-Я"7K,-–< ÞµåE0muê@}•.ÞJ8Í:¸­PlCxuˆä ,Üϰ‘(Ê+·ôL»±ÉJÖÛ$ëƒÏ¬Qå¢nz ´õ˜8öµ~‘Øi¡â <øBêÙû(K.u?2\«Ÿ_=»ˆ ¥“3ÁÅD×ý‰™›ÆC™Í} ‚n[_ù™y‡U÷i¨(‰7œ<5Ïñ°¡P@3¼—§I="àɘ*B5Sà‚`ÄCaž µð UaþO¥†²KdbÿrE8P Ž%pkgload/tests/testthat/testLoadHelpers/DESCRIPTION0000644000176200001440000000043214247353057021516 0ustar liggesusersPackage: testLoadHelpers Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: a.r Suggests: testthat RoxygenNote: 6.0.1.9000 Encoding: UTF-8 LazyData: true pkgload/tests/testthat/testLoadHelpers/tests/0000755000176200001440000000000014247353057021153 5ustar liggesuserspkgload/tests/testthat/testLoadHelpers/tests/testthat/0000755000176200001440000000000014551472164023012 5ustar liggesuserspkgload/tests/testthat/testLoadHelpers/tests/testthat/helpers.R0000644000176200001440000000007214247655327024604 0ustar liggesusersfoo <- 1 head_mtcars <- head(mtcars2) helper_baz <- baz pkgload/tests/testthat/testLoadHelpers/tests/testthat/test-foo.R0000644000176200001440000000010014247353057024665 0ustar liggesuserstest_that("multiplication works", { expect_equal(2 * 2, 4) }) pkgload/tests/testthat/testLoadHelpers/tests/testthat.R0000644000176200001440000000011214247353057023130 0ustar liggesuserslibrary(testthat) library(testLoadHelpers) test_check("testLoadHelpers") pkgload/tests/testthat/testLoadHelpers/R/0000755000176200001440000000000014247353057020212 5ustar liggesuserspkgload/tests/testthat/testLoadHelpers/R/a.r0000644000176200001440000000001114247353057020605 0ustar liggesusersbaz <- 1 pkgload/tests/testthat/test-load-collate.R0000644000176200001440000000130114247353057020342 0ustar liggesuserslocal_load_all_quiet() test_that("If collate absent, load in alphabetical order", { load_all("testCollateAbsent") expect_equal(a, 3) unload("testCollateAbsent") }) test_that("Warned about files missing from collate, but they're still loaded", { with_options( "testthat:::load_code_quiet_override" = FALSE, expect_message(load_all("testCollateMissing"), "a.r") ) expect_equal(a, 1) expect_equal(b, 2) unload("testCollateMissing") }) test_that("Extra files in collate don't error, but warn", { with_options( "testthat:::load_code_quiet_override" = FALSE, expect_message(load_all("testCollateExtra"), "b.r") ) expect_equal(a, 1) unload("testCollateExtra") }) pkgload/tests/testthat/testCollateMissing/0000755000176200001440000000000014247353057020524 5ustar liggesuserspkgload/tests/testthat/testCollateMissing/DESCRIPTION0000644000176200001440000000031614247353057022232 0ustar liggesusersPackage: testCollateMissing Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Collate: b.r pkgload/tests/testthat/testCollateMissing/R/0000755000176200001440000000000014210101433020700 5ustar liggesuserspkgload/tests/testthat/testCollateMissing/R/a.r0000644000176200001440000000000614210101433021277 0ustar liggesusersa <- 1pkgload/tests/testthat/testCollateMissing/R/b.r0000644000176200001440000000000614210101433021300 0ustar liggesusersb <- 2pkgload/tests/testthat/test-description.R0000644000176200001440000000034214247353057020331 0ustar liggesuserslocal_load_all_quiet() test_that("Parse DESCRIPTION file", { pkg <- pkg_desc("testNamespace") expect_identical(package_version("0.1"), pkg$get_version()) expect_identical("testNamespace", pkg_name("testNamespace")) }) pkgload/tests/testthat/testUserLoadHookUpstream/0000755000176200001440000000000014551453441021663 5ustar liggesuserspkgload/tests/testthat/testUserLoadHookUpstream/NAMESPACE0000644000176200001440000000007214247353057023105 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(foo) pkgload/tests/testthat/testUserLoadHookUpstream/DESCRIPTION0000644000176200001440000000070614247353057023400 0ustar liggesusersPackage: testUserLoadHookUpstream Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.1.2.9000 pkgload/tests/testthat/testUserLoadHookUpstream/R/0000755000176200001440000000000014247353057022070 5ustar liggesuserspkgload/tests/testthat/testUserLoadHookUpstream/R/testUserLoadHookUpstream.R0000644000176200001440000000004214247353057027167 0ustar liggesusers#' @export foo <- function() NULL pkgload/tests/testthat/testS3removed2/0000755000176200001440000000000014551453441017534 5ustar liggesuserspkgload/tests/testthat/testS3removed2/NAMESPACE0000644000176200001440000000005614247353057020760 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testS3removed2/DESCRIPTION0000644000176200001440000000031714247353057021247 0ustar liggesusersPackage: testS3removed Title: Test package with S3 method removed (after) License: MIT Author: Lionel Henry Maintainer: Lionel Henry Version: 1.0 RoxygenNote: 7.1.1 pkgload/tests/testthat/testS3removed2/R/0000755000176200001440000000000014247353057017741 5ustar liggesuserspkgload/tests/testthat/testS3removed2/R/S3.r0000644000176200001440000000000014247353057020377 0ustar liggesuserspkgload/tests/testthat/test-s4-unload.R0000644000176200001440000000550714502515617017620 0ustar liggesuserslocal_load_all_quiet() # Returns a named vector of this class's superclasses. # Results are sorted so they can be compared easily to a vector. # A contains B == A is a superclass of B get_superclasses <- function(class) { superclasses <- vapply(getClass(class)@contains, methods::slot, "superClass", FUN.VALUE = character(1)) sort(unname(superclasses)) } # Returns a named vector of this class's subclasses # Results are sorted so they can be compared easily to a vector. # A extends B == A is a subclass of B get_subclasses <- function(class) { subclasses <- vapply(getClass(class)@subclasses, methods::slot, "subClass", FUN.VALUE = character(1)) sort(unname(subclasses)) } test_that("loading and reloading s4 classes", { run_tests <- function() { # Check class hierarchy expect_equal(get_superclasses("A"), c("AB", "AOrNull", "mle2A", "mleA")) expect_equal(get_subclasses("AB"), c("A", "B")) expect_equal(get_superclasses("mle2"), c("mle", "mle2A", "mleA")) expect_equal(get_subclasses("mleA"), c("A", "mle", "mle2")) expect_equal(get_subclasses("mle2A"), c("A", "mle2")) expect_equal(get_subclasses("AOrNull"), c(".NULL", "A", "NULL")) expect_equal(get_subclasses("BOrNull"), c(".NULL", "B", "NULL")) # Check that package is registered correctly expect_equal(getClassDef("A")@package, "testS4union") expect_equal(getClassDef("AB")@package, "testS4union") expect_equal(getClassDef("mle2")@package, "testS4union") expect_equal(getClassDef("AOrNull")@package, "testS4union") expect_equal(getClassDef("BOrNull")@package, "testS4union") # Unloading shouldn't result in any errors or warnings expect_warning(unload("testS4union"), NA) # Check that classes are unregistered expect_true(is.null(getClassDef("A"))) expect_true(is.null(getClassDef("B"))) expect_true(is.null(getClassDef("AB"))) expect_true(is.null(getClassDef("AorNULL"))) expect_true(is.null(getClassDef("BorNULL"))) } load_all("testS4union") run_tests() # Load again and repeat tests -------------------------------------------- load_all("testS4union") run_tests() # Install package then load and run tests withr::with_temp_libpaths({ install.packages("testS4union", repos = NULL, type = "source", quiet = TRUE) library("testS4union") load_all("testS4union") run_tests() }) # Loading again shouldn't result in any errors or warnings expect_warning(load_all("testS4union", reset = FALSE), NA) unload("testS4union") unloadNamespace("stats4") # This was imported by testS4union # Check that classes are unregistered # This test on A fails for some bizarre reason - bug in R? But it doesn't # to cause any practical problems. expect_true(is.null(getClassDef("A"))) expect_true(is.null(getClassDef("B"))) expect_true(is.null(getClassDef("AB"))) }) pkgload/tests/testthat/testCollateAbsent/0000755000176200001440000000000014024307360020314 5ustar liggesuserspkgload/tests/testthat/testCollateAbsent/DESCRIPTION0000644000176200001440000000030013046675565022035 0ustar liggesusersPackage: testCollateAbsent Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 pkgload/tests/testthat/testCollateAbsent/R/0000755000176200001440000000000014210101433020503 5ustar liggesuserspkgload/tests/testthat/testCollateAbsent/R/a.r0000644000176200001440000000000614210101433021102 0ustar liggesusersa <- 1pkgload/tests/testthat/testCollateAbsent/R/b.r0000644000176200001440000000000614210101433021103 0ustar liggesusersa <- 2pkgload/tests/testthat/testCollateAbsent/R/c.r0000644000176200001440000000000614210101433021104 0ustar liggesusersa <- 3pkgload/tests/testthat/testVersionSep/0000755000176200001440000000000014451231442017672 5ustar liggesuserspkgload/tests/testthat/testVersionSep/DESCRIPTION0000644000176200001440000000067314451231442021406 0ustar liggesusersPackage: testVersionSep Title: What the Package Does (One Line, Title Case) Version: 0.0.0-9000 Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = c("cph", "fnd")) ) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 pkgload/tests/testthat/testS4export/0000755000176200001440000000000014024401437017324 5ustar liggesuserspkgload/tests/testthat/testS4export/NAMESPACE0000644000176200001440000000003713046675565020565 0ustar liggesusersexportClasses(class_to_export) pkgload/tests/testthat/testS4export/DESCRIPTION0000644000176200001440000000053613046675565021060 0ustar liggesusersPackage: testS4export Title: reproduce S4 export bug with devtools Version: 0.1 Description: reproduce S4 export bug with devtools Author: Karl Forner Maintainer: Karl Forner Depends: R (>= 2.15) Imports: methods Suggests: testthat (>= 0.7.1.99), License: GPL (>= 2) Collate: all.r pkgload/tests/testthat/testS4export/R/0000755000176200001440000000000014247353057017540 5ustar liggesuserspkgload/tests/testthat/testS4export/R/all.r0000644000176200001440000000007614247353057020476 0ustar liggesuserssetClass("foo") setClass('class_to_export', contains = "foo") pkgload/tests/testthat/testMacroDownstream/0000755000176200001440000000000014551453441020710 5ustar liggesuserspkgload/tests/testthat/testMacroDownstream/NAMESPACE0000644000176200001440000000007714247353057022137 0ustar liggesusers# Generated by roxygen2: do not edit by hand import(mathjaxr) pkgload/tests/testthat/testMacroDownstream/man/0000755000176200001440000000000014247353057021467 5ustar liggesuserspkgload/tests/testthat/testMacroDownstream/man/macro_downstream.Rd0000644000176200001440000000036414247353057025325 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/macro.R \name{macro_downstream} \alias{macro_downstream} \title{Topic} \usage{ macro_downstream() } \description{ This is a foreign macro \mjeqn{success}{success}. } pkgload/tests/testthat/testMacroDownstream/DESCRIPTION0000644000176200001440000000074114247353057022424 0ustar liggesusersPackage: testMacroDownstream Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 Imports: mathjaxr RdMacros: mathjaxr pkgload/tests/testthat/testMacroDownstream/R/0000755000176200001440000000000014247353057021115 5ustar liggesuserspkgload/tests/testthat/testMacroDownstream/R/macro.R0000644000176200001440000000017114247353057022340 0ustar liggesusers#' Topic #' #' This is a foreign macro \mjeqn{success}{success}. #' @import mathjaxr macro_downstream <- function() NULL pkgload/tests/testthat/testData/0000755000176200001440000000000014024322107016441 5ustar liggesuserspkgload/tests/testthat/testData/NAMESPACE0000644000176200001440000000002713046675565017705 0ustar liggesusersexport(sysdata_export) pkgload/tests/testthat/testData/data/0000755000176200001440000000000014024311031017344 5ustar liggesuserspkgload/tests/testthat/testData/data/b.r0000644000176200001440000000000713046675565020001 0ustar liggesusersb <- 2 pkgload/tests/testthat/testData/data/a.rda0000644000176200001440000000007313046675565020310 0ustar liggesusers‹ r‰0âŠàb```b`âbf “… H02°0p‚èD ÁbØ`€(+ýL8pkgload/tests/testthat/testData/DESCRIPTION0000644000176200001440000000026713046675565020202 0ustar liggesusersPackage: testData Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 pkgload/tests/testthat/testData/R/0000755000176200001440000000000014024323123016641 5ustar liggesuserspkgload/tests/testthat/testData/R/sysdata.rda0000644000176200001440000000013013046675565021022 0ustar liggesusers‹ r‰0âŠàb```b`âgf`b2Y˜€# 'æ+®,NI,IŒO­(È/*‰€d8 Eµ Lu^~š˜†5µÝvpkgload/tests/testthat/testActiveBindings/0000755000176200001440000000000014502255306020470 5ustar liggesuserspkgload/tests/testthat/testActiveBindings/NAMESPACE0000644000176200001440000000007214502255306021706 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(bar) pkgload/tests/testthat/testActiveBindings/DESCRIPTION0000644000176200001440000000030714502255306022176 0ustar liggesusersPackage: testActiveBindings Title: Test package with active bindings License: MIT Author: Konrad Rudolph Maintainer: Konrad Rudolph Version: 1.0 pkgload/tests/testthat/testActiveBindings/R/0000755000176200001440000000000014502255306020671 5ustar liggesuserspkgload/tests/testthat/testActiveBindings/R/bindings.r0000644000176200001440000000023514502255306022651 0ustar liggesusers makeActiveBinding("foo", function() rlang::abort("foo"), environment()) #' @export makeActiveBinding("bar", function() rlang::abort("bar"), environment()) pkgload/tests/testthat/testHelp/0000755000176200001440000000000014247353057016477 5ustar liggesuserspkgload/tests/testthat/testHelp/NAMESPACE0000644000176200001440000000017314247353057017717 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(foofoo) export(testCustomMacro) export(testHelp) export(testSysMacro) pkgload/tests/testthat/testHelp/man/0000755000176200001440000000000014547270332017247 5ustar liggesuserspkgload/tests/testthat/testHelp/man/testCustomMacro.Rd0000644000176200001440000000042214247353057022673 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/foofoo.r \name{testCustomMacro} \alias{testCustomMacro} \title{Function that has a system and a custom macro} \usage{ testCustomMacro() } \description{ This is \CRANpkg{pkgload}. \foobar{Yeah!} } pkgload/tests/testthat/testHelp/man/testSysMacro.Rd0000644000176200001440000000035514247353057022204 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/foofoo.r \name{testSysMacro} \alias{testSysMacro} \title{Function that has a system macro} \usage{ testSysMacro() } \description{ This is \CRANpkg{pkgload}. } pkgload/tests/testthat/testHelp/man/macros/0000755000176200001440000000000014247353057020536 5ustar liggesuserspkgload/tests/testthat/testHelp/man/macros/macros.Rd0000644000176200001440000000004014247353057022303 0ustar liggesusers\newcommand{\foobar}{\emph{#1}} pkgload/tests/testthat/testHelp/man/testHelp.Rd0000644000176200001440000000034714247353057021335 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/foofoo.r \name{testHelp} \alias{testHelp} \title{Function level help for testHelp} \usage{ testHelp() } \description{ Function level help for testHelp } pkgload/tests/testthat/testHelp/man/foofoo.Rd0000644000176200001440000000044014247353057021026 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/foofoo.r \name{foofoo} \alias{foofoo} \title{Test function for help} \usage{ foofoo() } \description{ The purpose of this function is to test out \code{help} and \code{?} from devtools. } \examples{ a <- 101 } pkgload/tests/testthat/testHelp/man/testHelp-package.Rd0000644000176200001440000000063614247353057022727 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/foofoo.r \docType{package} \name{testHelp-package} \alias{testHelp} \alias{testHelp-package} \title{testHelp: some title Some description} \description{ testHelp: some title Some description } \author{ \strong{Maintainer}: Hadley Wickham \email{hadley@rstudio.com} Other contributors: \itemize{ \item RStudio [copyright holder] } } pkgload/tests/testthat/testHelp/DESCRIPTION0000644000176200001440000000044314247353057020206 0ustar liggesusersPackage: testHelp Title: Tools to make developing R code easier License: GPL-2 Description: Test package for devtools help. Authors@R: c( person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre")), person("RStudio", role = "cph") ) Version: 0.1 RoxygenNote: 6.0.1 pkgload/tests/testthat/testHelp/R/0000755000176200001440000000000014247353057016700 5ustar liggesuserspkgload/tests/testthat/testHelp/R/foofoo.r0000644000176200001440000000120514247353057020350 0ustar liggesusers#' Test function for help #' #' The purpose of this function is to test out \code{help} and \code{?} from #' devtools. #' #' @export #' @examples #' a <- 101 foofoo <- function() "You called foofoo." #' testHelp: some title #' Some description "_PACKAGE" #' Function level help for testHelp #' #' @export testHelp <- function() "You called testHelp" #' Function that has a system macro #' #' This is \CRANpkg{pkgload}. #' #' @export testSysMacro <- function() "It is all good" #' Function that has a system and a custom macro #' #' This is \CRANpkg{pkgload}. \foobar{Yeah!} #' #' @export testCustomMacro <- function() "It is still all good" pkgload/tests/testthat/testLoadAttach/0000755000176200001440000000000014551453441017607 5ustar liggesuserspkgload/tests/testthat/testLoadAttach/NAMESPACE0000644000176200001440000000005614247400533021023 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/testthat/testLoadAttach/DESCRIPTION0000644000176200001440000000066714247400533021322 0ustar liggesusersPackage: testLoadAttach Title: What the Package Does (One Line, Title Case) Version: 0.0.0.9000 Authors@R: person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), comment = c(ORCID = "YOUR-ORCID-ID")) Description: What the package does (one paragraph). License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a license Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.0 pkgload/tests/testthat/testCollateOrder/0000755000176200001440000000000014024305037020152 5ustar liggesuserspkgload/tests/testthat/testCollateOrder/NAMESPACE0000644000176200001440000000003113046675565021406 0ustar liggesusersexportPattern("^[^\\.]") pkgload/tests/testthat/testCollateOrder/DESCRIPTION0000644000176200001440000000030113046675565021675 0ustar liggesusersPackage: testCollateOrder Title: Tools to make developing R code easier License: GPL-2 Description: Author: Geoff Maintainer: Geoff Version: 0.1 pkgload/tests/testthat/testCollateOrder/R/0000755000176200001440000000000014024410301020342 5ustar liggesuserspkgload/tests/testthat/testCollateOrder/R/a.r0000644000176200001440000000003013046675565020772 0ustar liggesusers#' @include b.r a <- 1 pkgload/tests/testthat/testCollateOrder/R/b.r0000644000176200001440000000000713046675565020777 0ustar liggesusersa <- 2 pkgload/tests/testthat/test-imports.R0000644000176200001440000000327614247353057017514 0ustar liggesuserslocal_load_all_quiet() test_that("Imported objects are copied to package environment", { load_all("testNamespace") # This package imports the whole 'compiler' package, bitops::bitAnd, and # bitops::bitOr. imp_env <- imports_env("testNamespace") # cmpfun is exported from compiler, so it should be in imp_env expect_identical(imp_env$cmpfun, compiler::cmpfun) # cmpSpecial is NOT exported from compiler, so it should not be in imp_env expect_true(exists("cmpSpecial", asNamespace("compiler"))) expect_false(exists("cmpSpecial", imp_env)) # 'bitAnd' is a single object imported specifically from bitops expect_true(exists("bitAnd", imp_env)) # 'bitFlip' is not imported from bitops expect_false(exists("bitFlip", imp_env)) unload("testNamespace") # Suppress warning from compiler for R 3.4 and above suppressWarnings(unload("compiler")) unload("bitops") }) test_that("Imported objects are be re-exported", { load_all("testNamespace", export_imports = FALSE) # bitAnd is imported and re-exported expect_identical(bitAnd, bitops::bitAnd) # bitOr is imported but not re-exported expect_false(exists("bitOr", .GlobalEnv)) unload("testNamespace") unload("compiler") unload("bitops") # Same as previous, but with export_all = FALSE load_all("testNamespace", export_all = FALSE) expect_identical(bitAnd, bitops::bitAnd) expect_false(exists("bitOr", .GlobalEnv)) unload("testNamespace") unload("compiler") unload("bitops") # If exports_imports = TRUE all imports are exported load_all("testNamespace", export_imports = TRUE) expect_true(exists("bitOr", .GlobalEnv)) # This is from the import(compiler) expect_true(exists("compile", .GlobalEnv)) }) pkgload/tests/testthat/test-data.R0000644000176200001440000000467214247353057016731 0ustar liggesuserslocal_load_all_quiet() test_that("data available when lazydata not true", { load_all("testData") # a and b are in data/ and shouldn't be available yet # sysdata_export and sysdata_nonexport are in R/sysdata.rda, and should be available expect_false(exists("a")) expect_false(exists("b")) expect_equal(sysdata_export, 3) expect_equal(sysdata_nonexport, 4) # Load the data objects (into the local environment) data(a, envir = environment()) data(b, envir = environment()) expect_equal(a, 1) expect_equal(b, 2) unload("testData") # Objects loaded with data() should still be available expect_equal(a, 1) expect_equal(b, 2) # Objects loaded in sysdata.rda shouldn't be available expect_false(exists("sysdata_export")) expect_false(exists("sysdata_nonexport")) }) test_that("data available when lazydata is true", { load_all("testDataLazy") # a and b are in data/ and should be available because of lazydata # sysdata_export and sysdata_nonexport are in R/sysdata.rda, and should be available expect_equal(a, 1) expect_equal(b, 2) expect_equal(sysdata_export, 3) expect_equal(sysdata_nonexport, 4) unload("testDataLazy") }) test_that("data available when lazydata not true, and export_all is FALSE", { load_all("testData", export_all = FALSE) # a and b are in data/ and shouldn't be available yet # sysdata_export is exported; sysdata_nonexport isn't expect_false(exists("a")) expect_false(exists("b")) expect_equal(sysdata_export, 3) expect_false(exists("sysdata_nonexport")) # Load the data objects (into the local environment) data(a, envir = environment()) data(b, envir = environment()) expect_equal(a, 1) expect_equal(b, 2) # Shouldn't be able to load objects in R/sysdata.rda with data() expect_warning(data(sysdata_export, envir = environment())) expect_false(exists("sysdata_nonexport")) unload("testData") }) test_that("data available when lazydata is true, and export_all is FALSE", { load_all("testDataLazy", export_all = FALSE) # a and b are in data/ and should be available because of lazydata # sysdata_export is exported; sysdata_nonexport isn't expect_equal(a, 1) expect_equal(b, 2) expect_equal(sysdata_export, 3) expect_false(exists("sysdata_nonexport")) # Shouldn't be able to load objects in R/sysdata.rda with data() expect_warning(data(sysdata_export, envir = environment())) expect_false(exists("sysdata_nonexport")) unload("testDataLazy") }) pkgload/tests/testthat/testNamespace/0000755000176200001440000000000014247353057017503 5ustar liggesuserspkgload/tests/testthat/testNamespace/NAMESPACE0000644000176200001440000000013513046675565020730 0ustar liggesusersexport(a) export(bitAnd) import(compiler) importFrom(bitops,bitAnd) importFrom(bitops,bitOr) pkgload/tests/testthat/testNamespace/DESCRIPTION0000644000176200001440000000035714247353057021216 0ustar liggesusersPackage: testNamespace Title: Tools to make developing R code easier License: GPL-2 Description: Author: Hadley Maintainer: Hadley Version: 0.1 Imports: compiler, bitops Collate: a.r b.r pkgload/tests/testthat/testNamespace/R/0000755000176200001440000000000014024415611017670 5ustar liggesuserspkgload/tests/testthat/testNamespace/R/a.r0000644000176200001440000000000713046675565020313 0ustar liggesusersa <- 1 pkgload/tests/testthat/testNamespace/R/b.r0000644000176200001440000000000713046675565020314 0ustar liggesusersb <- 2 pkgload/tests/empty/0000755000176200001440000000000014247353057014205 5ustar liggesuserspkgload/tests/empty/NAMESPACE0000644000176200001440000000005614247353057015425 0ustar liggesusers# Generated by roxygen2: do not edit by hand pkgload/tests/empty/DESCRIPTION0000644000176200001440000000052114247353057015711 0ustar liggesusersPackage: empty Version: 1.0.0 Title: title Description: desc Authors@R: c( person("Gábor", "Csárdi", email = "csardi.gabor@gmail.com", role = c("aut", "cre")) ) License: MIT Encoding: UTF-8 LazyData: true ByteCompile: true RoxygenNote: 7.1.2 Roxygen: list(markdown = TRUE) Depends: R (>= 3.2) Imports: tools, utils pkgload/tests/empty/R/0000755000176200001440000000000014247353057014406 5ustar liggesuserspkgload/tests/empty/R/foo.R0000644000176200001440000000000014247353057015302 0ustar liggesuserspkgload/tests/wipe.R0000644000176200001440000000035214247353057014136 0ustar liggesusersstopifnot(length(.dynLibs()) > 0) pkgload::load_all("empty") stopifnot(length(.dynLibs()) > 0) gc() stopifnot(length(.dynLibs()) > 0) pkgload::load_all("empty") stopifnot(length(.dynLibs()) > 0) gc() stopifnot(length(.dynLibs()) > 0) pkgload/tests/testthat.R0000644000176200001440000000021014246140057015014 0ustar liggesuserslibrary(testthat) library(pkgload) # Needed so that install.packages works correctly Sys.setenv("R_TESTS" = "") test_check("pkgload") pkgload/R/0000755000176200001440000000000014547266765012122 5ustar liggesuserspkgload/R/load-code.R0000644000176200001440000000333614326232547014063 0ustar liggesusers#' Load R code. #' #' Sources all `.R`/`.r` files in the `R/` directory, storing results into #' the package namespace. #' #' @inheritParams load_all #' @keywords programming #' @export load_code <- function(path = ".", quiet = NULL) { quiet <- load_all_quiet(quiet, "load_code") path <- pkg_path(path) package <- pkg_name(path) encoding <- pkg_desc(path)$get("Encoding") # Set encoding to ASCII if it is not explicitly defined if (is.na(encoding)) { encoding <- "ASCII" } env <- ns_env(package) r_files <- find_code(path, quiet = quiet) paths <- changed_files(r_files) if (length(paths) == 0L) return() success <- FALSE cleanup <- function() { if (success) return() clear_cache() unload(package) } on.exit(cleanup()) withr_with_dir(path, source_many(paths, encoding, env)) success <- TRUE invisible(r_files) } # Find all R files in given directory. find_code <- function(path = ".", quiet = FALSE) { path_r <- package_file("R", path = path) r_files <- withr_with_collate( "C", tools::list_files_with_type(path_r, "code", full.names = TRUE) ) collate <- pkg_desc(path)$get_collate() if (length(collate) > 0) { # `r_files` have full paths, so add the package path to the collated files as # well. collate <- file.path(path_r, collate) missing <- setdiff(collate, r_files) if (!quiet && length(missing) > 0) { cli::cli_inform(c("!" = "Skipping missing files: {.file {missing}}")) } collate <- setdiff(collate, missing) extra <- setdiff(r_files, collate) if (!quiet && length(extra) > 0) { cli::cli_inform(c("!" = "Adding files missing in collate: {.file {extra}}")) } r_files <- union(collate, r_files) } r_files } pkgload/R/package-deps.R0000644000176200001440000000714214277202147014555 0ustar liggesusers#' Parse package dependency strings. #' #' @param string to parse. Should look like `"R (>= 3.0), ggplot2"` etc. #' @return list of two character vectors: `name` package names, #' and `version` package versions. If version is not specified, #' it will be stored as NA. #' @keywords internal #' @export #' @examples #' parse_deps("httr (< 2.1),\nRCurl (>= 3)") #' # only package dependencies are returned #' parse_deps("utils (== 2.12.1),\ntools,\nR (>= 2.10),\nmemoise") parse_deps <- function(string) { if (is.null(string)) { return() } stopifnot(is_string(string)) if (grepl("^\\s*$", string)) { return() } pieces <- strsplit(string, "[[:space:]]*,[[:space:]]*")[[1]] # Get the names names <- gsub("\\s*\\(.*?\\)", "", pieces) names <- gsub("^\\s+|\\s+$", "", names) # Get the versions and comparison operators versions_str <- pieces have_version <- grepl("\\(.*\\)", versions_str) versions_str[!have_version] <- NA compare <- sub(".*\\((\\S+)\\s+.*\\)", "\\1", versions_str) versions <- sub(".*\\(\\S+\\s+(.*)\\)", "\\1", versions_str) # Check that non-NA comparison operators are valid compare_nna <- compare[!is.na(compare)] compare_valid <- compare_nna %in% c(">", ">=", "==", "<=", "<") if(!all(compare_valid)) { deps <- paste(compare_nna[!compare_valid], collapse = ", ") cli::cli_abort("Invalid comparison operator in dependency: {deps}.") } deps <- data.frame( name = names, compare = compare, version = versions, stringsAsFactors = FALSE ) # Remove R dependency deps[names != "R", ] } # Takes a dependency data frame generated by the `desc` package. deps_check_installed <- function(path, deps, call = caller_env()) { if (!nrow(deps)) { return() } pkg <- deps$package ver <- deps$version # Recreate `pkg (>= ver)` strings has_version <- ver != "*" pkg[has_version] <- sprintf( "%s (%s)", pkg[has_version], ver[has_version] ) # Outdated and missing dependencies are installed using pak if # installed. If not, the remotes package is used if installed. # Otherwise `install.packages()` is used as a last resort but this # method does not support Remotes fields. action <- function(pkg, ...) { if (is_installed("pak")) { deps <- pak::pkg_deps(path, upgrade = FALSE) deps <- deps[deps$package %in% pkg, ] pak::pkg_install(deps$ref, ask = FALSE) } else if (is_installed("remotes")) { deps <- remotes::dev_package_deps(path) deps <- deps[deps$package %in% pkg, ] stats::update(deps, upgrade = TRUE) } else { utils::install.packages(pkg) } } check_installed(pkg, action = action, call = call) } #' Check that the version of an imported package satisfies the requirements #' #' @param dep_name The name of the package with objects to import #' @param dep_ver The version of the package, this includes the specified #' comparison operator. #' @export #' @keywords internal check_dep_version <- function(dep_name, dep_ver = "*") { if (dep_name == "R") { return(TRUE) } if (!requireNamespace(dep_name, quietly = TRUE)) { cli::cli_warn("Dependency package {.pkg {dep_name}} is not available.") return(FALSE) } if (dep_ver == "*") { return(TRUE) } pieces <- strsplit(dep_ver, "[[:space:]]+")[[1]] dep_compare <- pieces[[1]] dep_ver <- pieces[[2]] compare <- match.fun(dep_compare) if (!compare( as.numeric_version(getNamespaceVersion(dep_name)), as.numeric_version(dep_ver))) { cli::cli_warn("Need {.pkg {dep_name}} {dep_compare} {dep_ver} but loaded version is {getNamespaceVersion(dep_name)}.") } return(TRUE) } pkgload/R/load.R0000644000176200001440000003141514547266765013170 0ustar liggesusers#' Load complete package #' #' @description #' `load_all()` loads a package. It roughly simulates what happens #' when a package is installed and loaded with [library()], without #' having to first install the package. It: #' #' - Loads all data files in `data/`. See [load_data()] for more #' details. #' #' - Sources all R files in the R directory, storing results in #' environment that behaves like a regular package namespace. See #' [load_code()] for more details. #' #' - Adds a shim from [system.file()] to [shim_system.file()] in #' the imports environment of the package. This ensures that `system.file()` #' works with both development and installed packages despite their differing #' directory structures. #' #' - Adds shims from `help()` and `?` to [shim_help()] and [shim_question()] #' to make it easier to preview development documentation. #' #' - Compiles any C, C++, or Fortran code in the `src/` directory and #' connects the generated DLL into R. See [pkgbuild::compile_dll()] #' for more details. #' #' - Loads any compiled translations in `inst/po`. #' #' - Runs `.onAttach()`, `.onLoad()` and `.onUnload()` functions at #' the correct times. #' #' - If you use \pkg{testthat}, will load all test helpers so you can #' access them interactively. devtools sets the `DEVTOOLS_LOAD` #' environment variable to the package name to let you check whether the #' helpers are run during package loading. #' #' `is_loading()` returns `TRUE` when it is called while `load_all()` #' is running. This may be useful e.g. in `.onLoad` hooks. #' #' # Differences to regular loading #' #' `load_all()` tries its best to reproduce the behaviour of #' [loadNamespace()] and [library()]. However it deviates from normal #' package loading in several ways. #' #' - `load_all()` doesn't install the package to a library, so [system.file()] #' doesn't work. pkgload fixes this for the package itself installing a shim, #' [shim_system.file()]. However, this shim is not visible to third party #' packages, so they will fail if they attempt to find files within your #' package. One potential workaround is to use [fs::path_package()] #' instead of `system.file()`, since that understands the mechanisms that #' devtools uses to load packages. #' #' - `load_all()` loads all packages referenced in `Imports` at load time, #' but `loadNamespace()` and `library()` only load package dependencies as #' they are needed. #' #' - `load_all()` copies all objects (not just the ones listed as exports) #' into the package environment. This is useful during development because #' it makes internal objects easy to access. To export only the objects #' listed as exports, use `export_all = FALSE`. This more closely simulates #' behavior when loading an installed package with [library()], and can #' be useful for checking for missing exports. #' #' @param path Path to a package, or within a package. #' @param reset clear package environment and reset file cache before loading #' any pieces of the package. This largely equivalent to running #' [unload()], however the old namespaces are not completely removed and no #' `.onUnload()` hooks are called. Use `reset = FALSE` may be faster for #' large code bases, but is a significantly less accurate approximation. #' @param compile If `TRUE` always recompiles the package; if `NA` #' recompiles if needed (as determined by [pkgbuild::needs_compile()]); #' if `FALSE`, never recompiles. #' @param attach Whether to attach a package environment to the search #' path. If `FALSE` `load_all()` behaves like `loadNamespace()`. If #' `TRUE` (the default), it behaves like `library()`. If `FALSE`, #' the `export_all`, `export_imports`, and `helpers` arguments have #' no effect. #' @param export_all If `TRUE` (the default), export all objects. #' If `FALSE`, export only the objects that are listed as exports #' in the NAMESPACE file. #' @param export_imports If `TRUE` (the default), export all objects that are #' imported by the package. If `FALSE` export only objects defined in the #' package. #' @param attach_testthat If `TRUE`, attach \pkg{testthat} to the search path, #' which more closely mimics the environment within test files. #' @param helpers if \code{TRUE} loads \pkg{testthat} test helpers. #' @param quiet if `TRUE` suppresses output from this function. #' @param recompile DEPRECATED. force a recompile of DLL from source code, if #' present. This is equivalent to running [pkgbuild::clean_dll()] before #' `load_all()` #' @param warn_conflicts If `TRUE`, issues a warning if a function in the global #' environment masks a function in the package. This can happen when you #' accidentally source a `.R` file, rather than using `load_all()`, or if you #' define a function directly in the R console. This is frustrating to debug, #' as it feels like the changes you make to the package source aren't having #' the expected effect. #' @keywords programming #' @examples #' \dontrun{ #' # Load the package in the current directory #' load_all("./") #' #' # Running again loads changed files #' load_all("./") #' #' # With reset=TRUE, unload and reload the package for a clean start #' load_all("./", TRUE) #' #' # With export_all=FALSE, only objects listed as exports in NAMESPACE #' # are exported #' load_all("./", export_all = FALSE) #' } #' @export load_all <- function(path = ".", reset = TRUE, compile = NA, attach = TRUE, export_all = TRUE, export_imports = export_all, helpers = export_all, attach_testthat = uses_testthat(path), quiet = NULL, recompile = FALSE, warn_conflicts = TRUE) { path <- pkg_path(path) package <- pkg_name(path) description <- pkg_desc(path) withr::local_envvar(c(DEVTOOLS_LOAD = package)) quiet <- load_all_quiet(quiet, "load_all") if (!quiet) { cli::cli_inform(c("i" = "Loading {.pkg {package}}")) } if (package == "compiler") { # Disable JIT while loading the compiler package to avoid interference # (otherwise the compiler package would be loaded as a side effect of # JIT compilation and it would be locked before we can insert shims into # it). oldEnabled <- compiler::enableJIT(0) on.exit(compiler::enableJIT(oldEnabled), TRUE) } if (missing(compile) && !missing(recompile)) { compile <- if (isTRUE(recompile)) TRUE else NA } if (isTRUE(compile)) { pkgbuild::clean_dll(path) pkgbuild::compile_dll(path, quiet = quiet) } else if (identical(compile, NA)) { pkgbuild::compile_dll(path, quiet = quiet) } else if (identical(compile, FALSE)) { # don't compile } else { cli::cli_abort("{.arg compile} must be a logical vector of length 1.") } old_methods <- list() if (reset) { clear_cache() # Remove package from known namespaces. We don't unload it to allow # safe usage of dangling references. if (is_loaded(package)) { patch_colon(package) methods_env <- ns_s3_methods(package) unregister(package) # Save foreign methods after unregistering the package's own # methods. We'll restore the foreign methods but let the package # register its own methods again. old_methods <- as.list(methods_env) old_methods <- Filter(function(x) is_foreign_method(x, package), old_methods) } } if (is_loaded(package)) { rlang::env_unlock(ns_env(package)) } else { create_ns_env(path) } out <- list(env = ns_env(package)) # Load dependencies load_depends(path, quiet = quiet) load_imports(path) # Add shim objects to imports environment insert_imports_shims(package) out$data <- load_data(path) out$code <- load_code(path, quiet = quiet) register_s3(path) if (identical(compile, FALSE)) { out$dll <- try_load_dll(path) } else { out$dll <- load_dll(path) } # attach testthat to the search path if (isTRUE(attach_testthat) && package != "testthat") { ("base" %:::% "library")("testthat", warn.conflicts = FALSE) } load_po(package, path) # Run namespace load hooks run_pkg_hook(package, "load") # Set up the exports in the namespace metadata (this must happen after # the objects are loaded) setup_ns_exports(path) run_ns_load_actions(package) ns <- ns_env(package) lockEnvironment(ns) for (nm in names(ns)) { lockBinding(nm, ns) } run_user_hook(package, "load") # Set up the package environment ------------------------------------ # Create the package environment if needed if (attach) { setup_pkg_env(package) } env_bind(ns_s3_methods(package), !!!old_methods) if (attach) { run_pkg_hook(package, "attach") run_user_hook(package, "attach") populate_pkg_env(package, path, export_all, export_imports, helpers) } # Replace help and ? in utils package environment insert_global_shims() if (isTRUE(warn_conflicts)) { warn_if_conflicts( package, out$env, globalenv() ) } invisible(out) } # The override logic is somewhat complicated but allows changing the # global verbosity default to `FALSE` during unit tests, as well as # turning on or off verbosity selectively in different loading phases. load_all_quiet <- function(quiet, fn = NULL) { if (!is_null(fn)) { # This overwrites the `quiet` setting quiet <- peek_option(sprintf("testthat:::%s_quiet_override", fn)) %||% quiet } # This doesn't overwrite the `quiet` setting, only changes the default quiet %||% peek_option("testthat:::load_all_quiet_default") %||% FALSE } is_function_in_environment <- function(name, env) { vapply(name, exists, logical(1), where = env, mode = "function", inherits = FALSE) } warn_if_conflicts <- function(package, env1, env2) { nms1 <- get_exports(env1) nms2 <- get_exports(env2) both <- sort(intersect(nms1, nms2)) # Verify are functions in both environments both <- both[ is_function_in_environment(both, env1) & is_function_in_environment(both, env2) ] if (length(both) == 0) { return(invisible()) } header <- cli::rule( left = crayon::bold("Conflicts"), right = paste0(package, " ", "conflicts") ) bullets <- conflict_bullets(package, both) objects <- paste0('"', both, '"', collapse = ", ") run_rm <- sprintf("rm(list = c(%s))", objects) run_rm <- style_hyperlink_run(run_rm) directions <- c( "i" = cli::col_silver("Did you accidentally source a file rather than using `load_all()`?"), " " = cli::col_silver(glue::glue("Run {run_rm} to remove the conflicts.")) ) cli::cli_warn( c(header, bullets, directions), class = "pkgload::conflict" ) } get_exports <- function(ns) { if (isNamespace(ns)) { nms <- getNamespaceExports(ns) } else { nms <- names(ns) } nms } conflict_bullets <- function(package, both) { # Show three bullets plus ellipsis if more than four bullets. # The output size is limited, also the bullets are vers repetitive. MAX_BULLETS <- 3 if (length(both) > MAX_BULLETS + 1) { more <- c(" " = glue::glue("{cli::symbol$ellipsis} and more.")) both <- utils::head(both, MAX_BULLETS) } else { more <- NULL } bullets <- glue::glue("`{crayon::green(both)}` masks `{crayon::blue(package)}::{both}()`.") c(set_names(bullets, "x"), more) } uses_testthat <- function(path = ".") { paths <- c( package_file("inst", "tests", path = path), package_file("tests", "testthat", path = path) ) any(dir.exists(paths)) && requireNamespace("testthat", quietly = TRUE) } find_test_dir <- function(path) { testthat <- package_file("tests", "testthat", path = path) if (dir.exists(testthat)) { return(testthat) } inst <- package_file("inst", "tests", path = path) if (dir.exists(inst)) { return(inst) } cli::cli_abort("No testthat directories found in {.path {path}}.") } is_foreign_method <- function(x, package) { env <- environment(x) !is_namespace(env) || !is_string(ns_env_name(env), package) } #' @rdname load_all #' @param pkg If supplied, `is_loading()` only returns `TRUE` if the #' package being loaded is `pkg`. #' @export is_loading <- function(pkg = NULL) { var <- Sys.getenv("DEVTOOLS_LOAD") if (is_null(pkg)) { nzchar(var) } else { is_string(var, pkg) } } # Ensure that calls to `::` resolve to the original unregistered # namespace patch_colon <- function(package) { ns <- asNamespace(package) rlang::env_unlock(ns) ns[["::"]] <- function(lhs, rhs) { lhs <- as.character(substitute(lhs)) rhs <- as.character(substitute(rhs)) if (identical(lhs, package)) { if (!exists(rhs, envir = ns, inherits = FALSE)) { stop(sprintf("Can't find `%s` in %s.", rhs, lhs)) } ns[[rhs]] } else { eval(bquote(base::`::`(.(lhs), .(rhs))), baseenv()) } } lockEnvironment(ns) } pkgload/R/has_tests.R0000644000176200001440000000125114247353057014225 0ustar liggesusers#' Was devtools installed with tests? #' #' @keywords internal #' @export has_tests <- function() { system.file("tests", package = "pkgload") != "" } #' Return the path to one of the packages in the devtools test dir #' #' devtools comes with some simple packages for testing. This function #' returns the path to them. #' #' @param package Name of the test package. #' @keywords internal #' @examples #' if (has_tests()) { #' pkgtest("testData") #' } #' @export pkgtest <- function(package) { stopifnot(has_tests()) path <- system.file(package = "pkgload", "tests", "testthat", package) if (path == "") { cli::cli_abort("Can't find {.pkg {package}}.") } path } pkgload/R/po.R0000644000176200001440000000137114247353057012651 0ustar liggesusersload_po <- function(package, path) { po_path <- file.path(path, "inst", "po") if (!file.exists(po_path)) { return() } # Clean up previous copies unlink(temp_po_dirs(package), recursive = TRUE, force = TRUE) # Create new copy of translations in temp dir tmp <- tempfile(temp_po_prefix(package)) dir.create(tmp, showWarnings = FALSE) tmp_po <- file.path(tmp, "po") file.copy(po_path, tmp, recursive = TRUE) bindtextdomain(paste0("R-", package), tmp_po) # R level messages bindtextdomain(package, tmp_po) # C level messages invisible() } temp_po_prefix <- function(package) { paste0("pkgload-po-", package, "-") } temp_po_dirs <- function(package) { dir(tempdir(), paste0("^", temp_po_prefix(package)), full.names = TRUE) } pkgload/R/remove-s4-class.R0000644000176200001440000001206514502515617015155 0ustar liggesusers# Remove s4 classes created by this package. # This is only necessary if the package was loaded with devtools. If the # package was NOT loaded by devtools, it's not necessary to remove the # classes this way, and attempting to do so will result in errors. remove_s4_classes <- function(package) { nsenv <- ns_env(package) if (is.null(nsenv)) { return() } classes <- methods::getClasses(nsenv, FALSE) classes <- sort_s4classes(classes, package) lapply(classes, remove_s4_class, package) } # Sort S4 classes for hierarchical removal # Derived classes must be removed **after** their parents. # This reduces to a topological sorting on the S4 dependency class # https://en.wikipedia.org/wiki/Topological_sorting sort_s4classes <- function(classes, package) { nsenv <- ns_env(package) sorted_classes <- vector(mode = 'character', length = 0) ## Return the parent class, if any within domestic classes extends_first <- function(x, classes) { ext <- methods::extends(methods::getClass(x, where = nsenv)) parent <- ext[2] classes %in% parent } ## Matrix of classes in columns, extending classes in rows extended_classes <- vapply( classes, extends_first, rep(TRUE, length(classes)), classes ) if (!is.matrix(extended_classes)) extended_classes <- as.matrix(extended_classes) ## Dynamic set of orphan classes (safe to remove) start_idx <- which(apply(extended_classes, 2, sum) == 0) while (length(start_idx) > 0) { ## add node to sorted list (and remove from pending list) i <- start_idx[1] start_idx <- utils::tail(start_idx, -1) sorted_classes <- c(sorted_classes, classes[i]) ## check its derived classes if any for (j in which(extended_classes[i, ])) { extended_classes[i, j] <- FALSE if (sum(extended_classes[, j]) == 0) { start_idx <- c(start_idx, j) } } } if (any(extended_classes)) { ## Graph has a cycle. This should not happen ## Stop or try to continue? idx <- !classes %in% sorted_classes sorted_classes <- c(sorted_classes, classes[idx]) } sorted_classes } # Remove an s4 class from a package loaded by devtools # # For classes loaded with devtools, this is necessary so that R doesn't try to # modify superclasses that don't have references to this class. For example, # suppose you have package pkgA with class A, and pkgB with class B, which # contains A. If pkgB is loaded with load_all(), then class B will have a # reference to class A, and unloading pkgB the normal way, with # unloadNamespace("pkgB"), will result in some errors. They happen because R # will look at B, see that it is a superclass of A, then it will try to modify # A by removing subclass references to B. # # This function sidesteps the problem by modifying B. It finds all the classes # in B@contains which also have references back to B, then modifies B to keep # references to those classes, but remove references to all other classes. # Finally, it removes B. Calling removeClass("B") tells the classes referred to # in B@contains to remove their references back to B. # # It is entirely possible that this code is necessary only because of bugs in # R's S4 implementation. # # @param classname The name of the class. # @param package The package object which contains the class. remove_s4_class <- function(classname, package) { nsenv <- ns_env(package) # Make a copy of the class class <- methods::getClassDef(classname, package = package, inherits = FALSE) # If the class is not defined in this package do not try to remove it if (!identical(class@package, package)) { return() } # Find all the references to classes that (this one contains/extends AND # have backreferences to this class) so that R doesn't try to modify them. keep_idx <- contains_backrefs(classname, package, class@contains) class@contains <- class@contains[keep_idx] # Assign the modified class back into the package methods::assignClassDef(classname, class, where = nsenv, force = TRUE) # Remove the class, ignoring failures due to potentially locked environments. tryCatch(methods::removeClass(classname, where = nsenv), error = function(e) NULL) } # Given a list of SClassExtension objects, this returns a logical vector of the # same length. Each element is TRUE if the corresponding object has a reference # to this class, FALSE otherwise. contains_backrefs <- function(classname, pkgname, contains) { # If class_a in pkg_a has class_b in pkg_b as a subclass, return TRUE, # otherwise FALSE. has_subclass_ref <- function(class_a, pkg_a, class_b, pkg_b) { x <- methods::getClassDef(class_a, package = pkg_a) if (is.null(x)) return(FALSE) subclass_ref <- x@subclasses[[class_b]] if (!is.null(subclass_ref) && subclass_ref@package == pkg_b) { return(TRUE) } FALSE } if (length(contains) == 0) { return() } # Get a named vector of 'contains', where each item's name is the class, # and the value is the package. contain_pkgs <- sapply(contains, methods::slot, "package") mapply(has_subclass_ref, names(contain_pkgs), contain_pkgs, classname, pkgname) } pkgload/R/namespace-env.R0000644000176200001440000001656614502255306014761 0ustar liggesusers#' Return the namespace environment for a package. #' #' Contains all (exported and non-exported) objects, and is a descendant of #' `R_GlobalEnv`. The hierarchy is ``, #' ``, ``, and then #' `R_GlobalEnv`. #' #' If the package is not loaded, this function returns `NULL`. #' #' @param package package name. #' @keywords internal #' @seealso [pkg_env()] for the attached environment that #' contains the exported objects. #' @seealso [imports_env()] for the environment that contains #' imported objects for the package. #' @export ns_env <- function(package) { if (!is_loaded(package)) return(NULL) asNamespace(package) } ns_path <- function(package) { ns <- asNamespace(package) if (isBaseNamespace(ns)) return(path.package(package)) getNamespaceInfo(ns, "path") } # Create the namespace environment for a package create_ns_env <- function(path = ".", call = caller_env()) { path <- pkg_path(path) package <- pkg_name(path) version <- pkg_version_raw(path) if (is_loaded(package)) { cli::cli_abort( "Namespace for {.pkg {package}} can't already exist.", call = call ) } env <- makeNamespace(package, version) methods::setPackageName(package, env) # Create devtools metadata in namespace create_dev_meta(package) setNamespaceInfo(env, "path", path) setup_ns_imports(path) env } # This is taken directly from base::loadNamespace() # https://github.com/wch/r-source/blob/tags/R-3-3-0/src/library/base/R/namespace.R#L235-L258 onload_assign("makeNamespace", eval( modify_lang( extract_lang(body(loadNamespace), # Find makeNamespace definition comp_lang, y = quote(makeNamespace <- NULL), idx = 1:2)[[3]], # Replace call to .Internal(registerNamespace()) is replaced by a call to # register_namespace function(x) { if (comp_lang(x, quote(.Internal(registerNamespace(name, env))))) { quote(register_namespace(name, env)) } else { x } })) ) # Read the NAMESPACE file and set up the imports metadata. # (which is stored in .__NAMESPACE__.) setup_ns_imports <- function(path = ".") { path <- pkg_path(path) package <- pkg_name(path) nsInfo <- parse_ns_file(path) setNamespaceInfo(package, "imports", nsInfo$imports) } # Read the NAMESPACE file and set up the exports metadata. This must be # run after all the objects are loaded into the namespace because # namespaceExport throw errors if the objects are not present. setup_ns_exports <- function(path = ".") { path <- pkg_path(path) package <- pkg_name(path) nsInfo <- parse_ns_file(path) nsenv <- ns_env(package) # This code is from base::loadNamespace exports <- nsInfo$exports for (p in nsInfo$exportPatterns) { # FIXME! Needs a test for `exportPatterns` exports <- c(ls(nsenv, pattern = p, all.names = TRUE), exports) } # Don't try to export objects that are missing from the namespace and imports ns_and_imports <- c( env_names(nsenv), env_names(imports_env(package)) ) extra_exports <- setdiff(exports, ns_and_imports) if (length(extra_exports) > 0) { cli::cli_warn(c( "Objects listed as exports, but not present in namespace: ", set_names(extra_exports, "*") )) exports <- intersect(ns_and_imports, exports) } # Add any S4 methods or classes, this needs to be done after checking for # missing exports as S4 methods with generics imported from other packages # are not defined in the namespace. exports <- add_classes_to_exports( ns = nsenv, package = package, exports = exports, nsInfo = nsInfo ) # Update the exports metadata for the namespace with base::namespaceExport # It will throw warnings if objects are already listed in the exports # metadata, so catch those warnings and ignore them. suppressWarnings( namespaceExport(nsenv, exports) ) invisible() } # Lookup S4 classes for export # # This function uses code from base::loadNamespace. Previously this code was # copied directly, now it is dynamically looked up instead, to prevent drift as # base::loadNamespace changes. onload_assign("add_classes_to_exports", { pattern <- if (getRversion() >= "4.1.0") { quote(if (.isMethodsDispatchOn() && hasS4m && !identical(package, "methods")) NULL) } else { quote(if (.isMethodsDispatchOn() && .hasS4MetaData(ns) && !identical(package, "methods")) NULL) } make_function(alist(ns =, package =, exports =, nsInfo =), call("{", quote(lev <- 0L), quote(hasS4m <- .hasS4MetaData(ns)), extract_lang( f = comp_lang, y = pattern, idx = c(1, 2), modify_lang(body(base::loadNamespace), strip_internal_calls, "methods") ), quote(exports) ), asNamespace("methods") ) } ) #' Parses the NAMESPACE file for a package #' #' @inheritParams load_all #' @examples #' if (has_tests()) { #' parse_ns_file(pkgtest("testLoadHooks")) #' } #' @keywords internal #' @export parse_ns_file <- function(path = ".") { path <- pkg_path(path) parseNamespaceFile(basename(path), dirname(path), mustExist = FALSE) } # Register the S3 methods for this package register_s3 <- function(path = ".") { path <- pkg_path(path) package <- pkg_name(path) nsInfo <- parse_ns_file(path) # Adapted from loadNamespace try(registerS3methods(nsInfo$S3methods, package, ns_env(package))) } # Reports whether a package is loaded into a namespace. It may be # attached or not attached. is_loaded <- function(package) { package %in% loadedNamespaces() } # Register a namespace register_namespace <- function(name = NULL, env = NULL) { if (!is.character(name) || name == "" || length(name) != 1) { cli::cli_abort("{.arg name} must be a non-empty character string.") } if (!is.environment(env)) { cli::cli_abort("{.arg env} must be an environment.") } if (name %in% loadedNamespaces()) { cli::cli_abort("Namespace {.arg {name}} can't be already registered.") } # Add the environment to the registry nsr <- ns_registry_env() nsr[[name]] <- env env } # Unregister a namespace - should be used only if unloadNamespace() # fails for some reason unregister_namespace <- function(name = NULL) { if (!is_string(name) || name == "") { cli::cli_abort("{.arg name} must be a non-empty character string.") } if (!(name %in% loadedNamespaces())) { cli::cli_abort("{.pkg {name}} must be a registered namespace.") } # Force all bindings of the namespace in case of dangling # references. If lazy bindings are forced after the namespace is # unloaded, it might lead to decompress errors if unloaded or to # inconsistencies if reloaded (the bindings are resolved in the new # namespace). # # We take precautions not to trigger active bindings in case these # have side effects such as throwing an error. ns <- ns_env(name) active_bindings <- env_binding_are_active(ns) env_get_list(ns, names(active_bindings)[!active_bindings]) # Remove the item from the registry env_unbind(ns_registry_env(), name) invisible() } unregister_methods <- function(package) { # Unloading S3 methods manually avoids lazy-load errors when the new # package is loaded overtop the old one. It also prevents removed # methods from staying registered. s3_unregister(package) # S4 classes that were created by the package need to be removed in a special way. remove_s4_classes(package) } pkgload/R/utils.R0000644000176200001440000001203514472326506013371 0ustar liggesusers# Given the name or vector of names, returns a named vector reporting # whether each exists and is a directory. dir.exists <- function(x) { res <- file.exists(x) & file.info(x)$isdir stats::setNames(res, x) } compact <- function(x) { is_empty <- vapply(x, function(x) length(x) == 0, logical(1)) x[!is_empty] } "%||%" <- function(a, b) if (!is.null(a)) a else b "%:::%" <- function(p, f) { get(f, envir = asNamespace(p)) } is_installed <- function(package, version = "0") { installed_version <- tryCatch(utils::packageVersion(package), error = function(e) NA) !is.na(installed_version) && installed_version >= version } #' Check that the version of an suggested package satisfies the requirements #' #' @param package The name of the suggested package #' @param version The version of the package #' @param compare The comparison operator used to check the version #' @keywords internal #' @export check_suggested <- function(package, version = NULL, compare = NA, path = inst("pkgload")) { if (is.null(version)) { if (!is.na(compare)) { cli::cli_abort("Must provide both {.arg compare} and {.arg version}.") } version <- suggests_dep(package, path = path) } if (!is_installed(package) || !check_dep_version(package, version)) { cli_version <- if (is_na(version)) "" else paste0(" ", version) msg <- c("{.pkg package}{cli_version} must be installed for this functionality.") if (interactive()) { cli::cli_inform(c("i" = msg)) cli::cli_inform(c("!" = "Would you like to install it?")) if (utils::menu(c("Yes", "No")) == 1) { utils::install.packages(package) return() } } cli::cli_abort(msg) } } suggests_dep <- function(package, path = inst("pkgload")) { desc <- pkg_desc(path)$get_deps() found <- desc[desc$type == "Suggests" & desc$package == package, "version"] if (!length(found)) { cli::cli_abort("{.pkg {package}} is not in {.code Suggests:} for {.pkg {pkg_name(path)}}.") } found } all_named <- function (x) { if (length(x) == 0) return(TRUE) !is.null(names(x)) && all(names(x) != "") } make_function <- function (args, body, env = parent.frame()) { args <- as.pairlist(args) stopifnot(all_named(args), is.language(body)) eval(call("function", args, body), env) } comp_lang <- function(x, y, idx = seq_along(y)) { if (is.symbol(x) || is.symbol(y)) { return(identical(x, y)) } if (length(x) < length(idx)) return(FALSE) identical(x[idx], y[idx]) } extract_lang <- function(x, f, ...) { recurse <- function(y) { unlist(compact(lapply(y, extract_lang, f = f, ...)), recursive = FALSE) } # if x matches predicate return it if (isTRUE(f(x, ...))) { return(x) } if (is.call(x)) { res <- recurse(x)[[1]] if (top_level_call <- identical(sys.call()[[1]], as.symbol("extract_lang")) && is.null(res)) { cli::cli_warn(c( "pkgload is incompatible with the current version of R.", "i" = "{.code load_all()} may function incorrectly." )) } return(res) } NULL } modify_lang <- function(x, f, ...) { recurse <- function(x) { lapply(x, modify_lang, f = f, ...) } x <- f(x, ...) if (is.call(x)) { as.call(recurse(x)) } else if (is.function(x)) { formals(x) <- modify_lang(formals(x), f, ...) body(x) <- modify_lang(body(x), f, ...) x } else { x } } strip_internal_calls <- function(x, package) { if (is.call(x) && identical(x[[1L]], as.name(":::")) && identical(x[[2L]], as.name(package))) { x[[3L]] } else { x } } sort_ci <- function(x) { withr_with_collate("C", x[order(tolower(x), x)]) } dev_packages <- function() { packages <- vapply(loadedNamespaces(), function(x) !is.null(dev_meta(x)), logical(1)) names(packages)[packages] } copy_env <- function(src, dest = new.env(parent = emptyenv()), ignore = NULL) { srclist <- as.list(src, all.names = TRUE) srclist <- srclist[ !(names(srclist) %in% ignore) ] list2env(srclist, envir = dest) dest } copy_env_lazy <- function(src, dest = new.env(parent = emptyenv()), ignore = NULL) { nms <- ls(src, all.names = TRUE) nms <- nms[ !(nms %in% ignore) ] for (nme in nms) { delayed_assign(nme, as.symbol(nme), eval.env = src, assign.env = dest) } dest } # A version of delayedAssign which does _not_ use substitute delayed_assign <- function(x, value, eval.env = parent.frame(1), assign.env = parent.frame(1)) { inject(delayedAssign(x, !!value, eval.env, assign.env)) } last <- function(x) utils::tail(x, n = 1L) single_quote <- function(x) { encodeString(x, quote = "'") } ns_s3_methods <- function(pkg) { ns_env(pkg)$.__S3MethodsTable__. } paste_line <- function(...) { paste(c(...), collapse = "\n") } style_hyperlink_run <- function(code) { if (nzchar(Sys.getenv("R_CLI_HAS_HYPERLINK_RUN"))) { link <- paste0("rstudio:run:", code) code <- cli::style_hyperlink(code, link) } cli::format_inline("{.code {code}}") } cat_line <- function(...) { cat(paste0(..., "\n", collapse = "")) } is_rstudio <- function() { is_string(.Platform$GUI, "RStudio") } pkgload/R/zzz.R0000644000176200001440000000331014547266765013077 0ustar liggesusers.onLoad <- function(libname, pkgname) { run_on_load() ns <- ns_env(pkgname) # Capture TEMPDIR for use in subproceses if (identical(Sys.getenv("PKGLOAD_PARENT_TEMPDIR"), "")) { Sys.setenv("PKGLOAD_PARENT_TEMPDIR" = tempdir()) } # Force reload global shims if developing pkgload itself if (is_loading()) { insert_global_shims(force = TRUE) } nms <- fn_env(onload_assign)$names funs <- fn_env(onload_assign)$funs for (i in seq_along(nms)) { env_poke(ns, nms[[i]], eval(funs[[i]], ns)) } } # These functions are used in load_all() so need to exist in the # devtools namespace so the withr namespace is not prematurely loaded # by `::` during a load_all() call. # # They are lazily assigned to avoid racing issues while installing in # parallel (see #89), and forced via `force_load_all_deps()` before # unregistering namespaces. on_load({ withr_with_dir %<~% withr::with_dir withr_with_collate %<~% withr::with_collate withr_with_envvar %<~% withr::with_envvar desc_desc %<~% desc::desc desc_desc_get_field %<~% desc::desc_get_field desc_desc_get_version %<~% desc::desc_get_version rprojroot_find_package_root_file %<~% rprojroot::find_package_root_file if (is_installed("testthat")) { testthat_source_test_helpers %<~% testthat::source_test_helpers } else { testthat_source_test_helpers %<~% function(...) TRUE } }) force_load_all_deps <- function() { list( withr_with_dir, withr_with_collate, withr_with_envvar, desc_desc, desc_desc_get_field, desc_desc_get_version, rprojroot_find_package_root_file, testthat_source_test_helpers ) } # R CMD check NOTE unused <- function() { desc::desc rprojroot::find_package_root_file } pkgload/R/inst.R0000644000176200001440000000150414247353057013206 0ustar liggesusers#' Get the installation path of a package #' #' Given the name of a package, this returns a path to the installed #' copy of the package, which can be passed to other devtools functions. #' #' It searches for the package in [.libPaths()]. If multiple #' dirs are found, it will return the first one. #' #' @param name the name of a package. #' #' @examples #' inst("pkgload") #' inst("grid") #' @export inst <- function(name) { # It would be nice to use find.package or system.file, but they # also search in the directory in the 'path' attribute of the # package environment. # Look in the library paths paths <- file.path(.libPaths(), name) paths <- paths[dir.exists(paths)] if (length(paths) > 0) { # If multiple matches, return the first one return(normalizePath(paths[1])) } else { return(NULL) } } pkgload/R/run-loadhooks.R0000644000176200001440000000341414247353057015020 0ustar liggesusers#' Run user and package hooks. #' #' #' @inheritParams ns_env #' @param hook hook name: one of "load", "unload", "attach", or "detach" #' @keywords internal run_pkg_hook <- function(package, hook) { trans <- c( "load" = ".onLoad", "unload" = ".onUnload", "attach" = ".onAttach", "detach" = ".onDetach") hook <- match.arg(hook, names(trans)) f_name <- trans[hook] metadata <- dev_meta(package) if (isTRUE(metadata[[f_name]])) return(FALSE) # Run hook function if defined, and not already run nsenv <- ns_env(package) ns_path <- ns_path(package) if (!exists(f_name, nsenv, inherits = FALSE)) return(FALSE) if (hook %in% c("load", "attach")) { nsenv[[f_name]](dirname(ns_path), package) } else { nsenv[[f_name]](dirname(ns_path)) } metadata[[f_name]] <- TRUE TRUE } #' @rdname run_pkg_hook run_user_hook <- function(package, hook) { nsenv <- ns_env(package) trans <- c( "load" = "onLoad", "unload" = "onUnload", "attach" = "attach", "detach" = "detach") hook <- match.arg(hook, names(trans)) hook_name <- trans[hook] metadata <- dev_meta(package) if (isTRUE(metadata[[hook_name]])) { return(FALSE) } hooks <- getHook(packageEvent(package, hook_name)) if (length(hooks) == 0) { return(FALSE) } for (fun in rev(hooks)) { try_fetch( fun(package), error = function(cnd) { msg <- sprintf( "Problem while running user `%s` hook for package %s.", hook_name, package ) name <- env_name(topenv(fn_env(fun))) if (nzchar(name)) { msg <- c(msg, i = sprintf("The hook inherits from `%s`.", name)) } cli::cli_warn(msg, parent = cnd) } ) } metadata[[hook_name]] <- TRUE invisible(TRUE) } pkgload/R/package-env.R0000644000176200001440000001055414502523250014403 0ustar liggesuserssetup_pkg_env <- function(pkg) { if (!is_attached(pkg)) { attach_ns(pkg) } # Copy over lazy data objects from the namespace environment export_lazydata(pkg) # Copy over objects from the namespace environment export_ns(pkg) # Assign .Depends, if any, to package environment from namespace assign_depends(pkg) } # Create the package environment where exported objects will be copied to attach_ns <- function(package) { nsenv <- ns_env(package) if (is_attached(package)) { cli::cli_abort("Package {.pkg {package}} can't be already attached.") } # This should be similar to attachNamespace pkgenv <- base::attach(NULL, name = pkg_env_name(package)) attr(pkgenv, "path") <- getNamespaceInfo(nsenv, "path") invisible(pkgenv) } populate_pkg_env <- function(pkg, path, export_all, export_imports, helpers) { pkg_env <- pkg_env(pkg) if (export_all) { env_coalesce(pkg_env, ns_env(pkg)) if (export_imports) { env_coalesce(pkg_env, imports_env(pkg)) } env_unbind(pkg_env, exports_exclusion_list) } # Source test helpers into pkg environment if (helpers && uses_testthat(path)) { withr_with_envvar( c(NOT_CRAN = "true"), testthat_source_test_helpers(find_test_dir(path), env = pkg_env) ) } } # Namespace and devtools bindings to exclude from package envs exports_exclusion_list <- c( ".__NAMESPACE__.", ".__S3MethodsTable__.", ".packageName", ".First.lib", ".onLoad", ".onAttach", ".conflicts.OK", ".noGenerics", ".__DEVTOOLS__", ".cache" ) # Invoke namespace load actions. According to the documentation for setLoadActions # these actions should be called at the end of processing of S4 metadata, after # dynamically linking any libraries, the call to .onLoad(), if any, and caching # method and class definitions, but before the namespace is sealed run_ns_load_actions <- function(package) { nsenv <- ns_env(package) actions <- methods::getLoadActions(nsenv) for (action in actions) action(nsenv) } # Copy over the objects from the namespace env to the package env export_ns <- function(package) { nsenv <- ns_env(package) pkgenv <- pkg_env(package) ns_path <- ns_path(nsenv) nsInfo <- parse_ns_file(ns_path) exports <- getNamespaceExports(nsenv) importIntoEnv(pkgenv, exports, nsenv, exports) } export_lazydata <- function(package) { nsenv <- ns_env(package) pkgenv <- pkg_env(package) desc <- pkg_desc(ns_path(package)) # If lazydata is true, manually copy data objects in $lazydata to package # environment lazydata <- desc$get("LazyData") if (!is.na(lazydata) && tolower(lazydata) %in% c("true", "yes")) { copy_env_lazy(src = nsenv$.__NAMESPACE__.$lazydata, dest = pkgenv) } } # Assign `.Depends` from namespace assign_depends <- function(package) { pkgenv <- pkg_env(package) desc <- pkg_desc(ns_path(package)) deps <- desc$get_deps() depends <- unique(deps[deps$type == "Depends" & deps$package != "R",]$package) if (length(depends) > 0L) pkgenv$.Depends <- depends } #' Return package environment #' #' This is an environment like ``. The package #' environment contains the exported objects from a package. It is #' attached, so it is an ancestor of `R_GlobalEnv`. #' #' When a package is loaded the normal way, using [library()], #' this environment contains only the exported objects from the #' namespace. However, when loaded with [load_all()], this #' environment will contain all the objects from the namespace, unless #' `load_all` is used with `export_all=FALSE`. #' #' If the package is not attached, this function returns `NULL`. #' #' @inheritParams ns_env #' @keywords internal #' @seealso [ns_env()] for the namespace environment that #' all the objects (exported and not exported). #' @seealso [imports_env()] for the environment that contains #' imported objects for the package. #' @export pkg_env <- function(package) { name <- pkg_env_name(package) if (!is_attached(package)) return(NULL) as.environment(name) } # Generate name of package environment # Contains exported objects pkg_env_name <- function(package) { paste("package:", package, sep = "") } # Reports whether a package is loaded and attached is_attached <- function(package) { pkg_env_name(package) %in% search() } pkgload/R/load-data.R0000644000176200001440000000227114247353057014061 0ustar liggesusers#' Load data. #' #' Loads all `.RData` files in the data subdirectory. #' #' @inheritParams load_all #' @keywords programming #' @export load_data <- function(path = ".") { # Note that this simulates normal R package loading by placing the data sets # in the .__NAMESPACE__.$lazydata environment, but unlike with proper lazy # loading via lazyLoad(), we'll need to manually copy these objects over to # the package environment later. path <- pkg_path(path) nsenv <- ns_env(pkg_name(path)) lazydata_env <- nsenv$.__NAMESPACE__.$lazydata objs <- character() sysdata <- package_file("R", "sysdata.rda", path = path) if (file.exists(sysdata)) { objs <- c(objs, load(sysdata, envir = nsenv)) } path_data <- package_file("data", path = path) if (file.exists(path_data)) { paths <- dir(path_data, "\\.[rR][dD]a(ta)?$", full.names = TRUE) paths <- changed_files(paths) objs <- c(objs, unlist(lapply(paths, load, envir = lazydata_env))) paths <- dir(path_data, "\\.[rR]$", full.names = TRUE) paths <- changed_files(paths) objs <- c(objs, unlist(lapply(paths, sys.source, envir = lazydata_env, chdir = TRUE, keep.source = TRUE))) } invisible(objs) } pkgload/R/unload.R0000644000176200001440000001205314247353057013514 0ustar liggesusers#' Unload a package #' #' @description #' #' `unload()` attempts to cleanly unload a package, including unloading #' its namespace, deleting S4 class definitions and unloading any loaded #' DLLs. Unfortunately S4 classes are not really designed to be cleanly #' unloaded, and so we have to manually modify the class dependency graph in #' order for it to work - this works on the cases for which we have tested #' but there may be others. Similarly, automated DLL unloading is best tested #' for simple scenarios (particularly with `useDynLib(pkgname)` and may #' fail in other cases. If you do encounter a failure, please file a bug report #' at \url{https://github.com/r-lib/pkgload/issues}. #' #' `unregister()` is a gentler version of `unload()` which removes the #' package from the search path, unregisters methods, and unregisters #' the namespace. It doesn't unload the namespace or its DLL to keep #' it in working order in case of dangling references. #' #' @inheritParams ns_env #' @param quiet if `TRUE` suppresses output from this function. #' #' @examples #' \dontrun{ #' # Unload package that is in current directory #' unload() #' #' # Unload package that is in ./ggplot2/ #' unload(pkg_name("ggplot2/")) #' #' library(ggplot2) #' # unload the ggplot2 package directly by name #' unload("ggplot2") #' } #' @export unload <- function(package = pkg_name(), quiet = FALSE) { if (package == "compiler") { # Disable JIT compilation as it could interfere with the compiler # unloading. Also, if the JIT was kept enabled, it would cause the # compiler package to be loaded again soon, anyway. Note if we # restored the JIT level after the unloading, the call to # enableJIT itself would load the compiler again. oldEnable <- compiler::enableJIT(0) if (oldEnable != 0) { cli::cli_warn("JIT automatically disabled when unloading the compiler.") } } if (!package %in% loadedNamespaces()) { cli::cli_abort("Package {.pkg {package}} not found in loaded packages or namespaces.") } unregister_methods(package) # unloadNamespace calls onUnload hook and .onUnload, and detaches the # package if it's attached. It will fail if a loaded package needs it. unloaded <- tryCatch({ unloadNamespace(package) TRUE }, error = function(e) FALSE) if (!unloaded) { # unloadNamespace() failed before we get to the detach, so need to # manually detach unload_pkg_env(package) # Can't use loadedNamespaces() and unloadNamespace() here because # things can be in a weird state. unregister_namespace(package) } # Clear so that loading the package again will re-read all files clear_cache() # Do this after detach, so that packages that have an .onUnload function # which unloads DLLs (like MASS) won't try to unload the DLL twice. unload_dll(package) } #' @rdname unload #' @export unregister <- function(package = pkg_name()) { # Before unregistering anything, force all imported functions that # might be needed during package reloading, in case they come from # `package` force_load_all_deps() unload_pkg_env(package) unregister_methods(package) unregister_namespace(package) } unload_pkg_env <- function(package) { if (is_attached(package)) { pos <- which(pkg_env_name(package) == search()) suppressWarnings(detach(pos = pos, force = TRUE)) } } # This unloads dlls loaded by either library() or load_all() unload_dll <- function(package) { # Always run garbage collector to force any deleted external pointers to # finalise gc() # Special case for devtools - don't unload DLL because we need to be able # to access nsreg() in the DLL in order to run makeNamespace. This means # that changes to compiled code in devtools can't be reloaded with # load_all -- it requires a reinstallation. if (package == "pkgload") { return(invisible()) } pkglibs <- loaded_dlls(package) for (lib in pkglibs) { dyn.unload(lib[["path"]]) } # Remove the unloaded dlls from .dynLibs() libs <- .dynLibs() .dynLibs(libs[!(libs %in% pkglibs)]) invisible() } s3_unregister <- function(package) { ns <- ns_env(package) # If the package is loaded, but not installed this will fail, so we bail out in that case. ns_defs <- suppressWarnings(try(parse_ns_file(system.file(package = package)), silent = TRUE)) if (inherits(ns_defs, "try-error")) { return() } methods <- ns_defs$S3methods[, 1:2, drop = FALSE] for (i in seq_len(nrow(methods))) { method <- methods[i, , drop = FALSE] generic <- env_get(ns, method[[1]], inherit = TRUE, default = NULL) if (is_null(generic)) { next } generic_ns <- topenv(fn_env(generic)) if (!is_namespace(generic_ns)) { next } # Don't remove methods for generics defined in the namespace being # unloaded. The stale namespace should still work as much as # possible. if (is_string(ns_env_name(generic_ns), package)) { next } table <- generic_ns$.__S3MethodsTable__. if (!is_environment(table)) { next } nm <- paste0(method, collapse = ".") env_unbind(table, nm) } } pkgload/R/source.R0000644000176200001440000000211614247353057013531 0ustar liggesuserssource_many <- function(files, encoding = "UTF-8", envir = parent.frame()) { stopifnot(is.character(files)) stopifnot(is.environment(envir)) oop <- options( keep.source = TRUE, show.error.locations = TRUE, topLevelEnvironment = as.environment(envir)) on.exit(options(oop)) for (file in files) { try_fetch( source_one(file, encoding, envir = envir), error = function(cnd) { path <- file.path(basename(dirname(file)), basename(file)) msg <- paste0("Failed to load {.file {path}}") cli::cli_abort(msg, parent = cnd, call = quote(load_all())) } ) } invisible() } source_one <- function(file, encoding, envir = parent.frame()) { stopifnot(file.exists(file)) stopifnot(is.environment(envir)) lines <- read_lines_enc(file, file_encoding = encoding) srcfile <- srcfilecopy(file, lines, file.info(file)[1, "mtime"], isFile = TRUE) exprs <- parse(text = lines, n = -1, srcfile = srcfile) n <- length(exprs) if (n == 0L) return(invisible()) for (i in seq_len(n)) { eval(exprs[i], envir) } invisible() } pkgload/R/imports-env.R0000644000176200001440000000677014502252337014517 0ustar liggesusers#' Return imports environment for a package #' #' Contains objects imported from other packages. Is the parent of the #' package namespace environment, and is a child of ``, #' which is a child of `R_GlobalEnv`. #' @keywords internal #' @param package The package name as a string. #' @seealso [ns_env()] for the namespace environment that #' all the objects (exported and not exported). #' @seealso [pkg_env()] for the attached environment that contains #' the exported objects. #' @export imports_env <- function(package) { if (!is_loaded(package)) { cli::cli_abort("Namespace environment must be created before accessing imports environment.") } env <- parent.env(ns_env(package)) if (attr(env, 'name') != imports_env_name(package)) { cli::cli_abort(c( "Imports environment does not have attribute {.arg name} with value {imports_env_name(package)}.", "i" = "This probably means that the namespace environment was not created correctly." )) } env } # Generate name of package imports environment # Contains exported objects imports_env_name <- function(package) { paste("imports:", package, sep = "") } #' Load all of the imports for a package #' #' The imported objects are copied to the imports environment, and are not #' visible from `R_GlobalEnv`. This will automatically load (but not attach) #' the dependency packages. #' #' @keywords internal load_imports <- function(path = ".") { package <- pkg_name(path) description <- pkg_desc(path) # Get data frame of dependency names and versions deps <- description$get_deps() imports <- deps[deps$type == "Imports", ] if (length(imports) == 0) { return(invisible()) } # If we've already loaded imports, don't load again (until load_all # is run with reset=TRUE). This is to avoid warnings when running # process_imports() if (length(ls(envir = imports_env(package))) > 0) { return(invisible(imports)) } deps_check_installed(path, imports) process_imports(path) invisible(deps) } # Load imported objects # The code in this function is taken and adapted from base::loadNamespace # Setup variables were added and the for loops put in a tryCatch block # https://github.com/wch/r-source/blob/tags/R-3-3-0/src/library/base/R/namespace.R#L397-L427 # This wraps the inner for loop iterations in a tryCatch wrap_inner_loop <- function(x) { inner <- x[[4]] x[[4]] <- call("tryCatch", error = quote(warning), inner) x } load_namespace_for1 <- function() wrap_inner_loop( extract_lang(body(loadNamespace), comp_lang, y = quote(for(i in nsInfo$imports) NULL), idx = 1:3) ) load_namespace_for2 <- function() wrap_inner_loop( extract_lang(body(loadNamespace), comp_lang, y = quote(for(imp in nsInfo$importClasses) NULL), idx = 1:3) ) load_namespace_for3 <- function() wrap_inner_loop( extract_lang(body(loadNamespace), comp_lang, y = quote(for(imp in nsInfo$importMethods) NULL), idx = 1:3) ) onload_assign("process_imports", { process_imports <- function(path = ".") { path <- pkg_path(path) package <- pkg_name(path) desc_path <- package_file("DESCRIPTION", path = path) vI <- ("tools" %:::% ".split_description")(("tools" %:::% ".read_description")(desc_path))$Imports nsInfo <- parse_ns_file(path) ns <- ns_env(package) lib.loc <- NULL !! load_namespace_for1() !! load_namespace_for2() !! load_namespace_for3() } process_imports <- expr_interp(process_imports) fn_env(process_imports) <- rlang::ns_env("pkgload") process_imports }) pkgload/R/dev-help.R0000644000176200001440000002166414502560210013727 0ustar liggesusers#' In-development help for package loaded with devtools #' #' `dev_help()` searches for source documentation provided in packages #' loaded by devtools. To improve performance, the `.Rd` files are #' parsed to create to index once, then cached. Use #' `dev_topic_index_reset()` to clear that index. You can manually #' retrieve the index for a local package with `dev_topic_index()`. #' #' @param topic name of help to search for. #' @param dev_packages A character vector of package names to search within. #' If `NULL`, defaults to all packages loaded by devtools. #' @param stage at which stage ("build", "install", or "render") should #' `\\Sexpr` macros be executed? This is only important if you're using #' `\\Sexpr` macro's in your Rd files. #' @param type of html to produce: `"html"` or `"text"`. Defaults to #' your default documentation type. #' @export #' @examples #' \dontrun{ #' library("ggplot2") #' help("ggplot") # loads installed documentation for ggplot #' #' load_all("ggplot2") #' dev_help("ggplot") # loads development documentation for ggplot #' } dev_help <- function(topic, dev_packages = NULL, stage = "render", type = getOption("help_type")) { if (length(dev_packages()) == 0) { cli::cli_abort(c( "Can't find development documentation because no in-development packages loaded.", i = "Do you need to run {.run pkgload::load_all()}?" )) } loc <- dev_topic_find(topic, dev_packages) if (!is.null(loc$path) && !fs::file_exists(loc$path)) { # Documentation topic might have moved, so reset topic index and try again dev_topic_index_reset(loc$pkg) loc <- dev_topic_find(topic, dev_packages) } if (is.null(loc$path) || !fs::file_exists(loc$path)) { cli::cli_abort("Can't find development topic {.arg {topic}}.") } structure( list( topic = topic, pkg = loc$pkg, path = loc$path, stage = stage, type = type ), class = "dev_topic" ) } has_rd_macros <- function(dir) { desc <- file.path(dir, "DESCRIPTION") if (!file.exists(desc)) { return(FALSE) } tryCatch( expr = { desc <- read.dcf(desc) "RdMacros" %in% colnames(desc) }, error = function(...) FALSE ) } load_rd_macros <- function(dir) { macros <- tools::loadPkgRdMacros(dir) tools::loadRdMacros( file.path(R.home("share"), "Rd", "macros", "system.Rd"), macros = macros ) } #' @export print.dev_topic <- function(x, ...) { cli::cli_inform(c("i" = "Rendering development documentation for {.val {x$topic}}")) type <- arg_match0(x$type %||% "text", c("text", "html")) # Use rstudio's previewRd() if possible if (type == "html" && is_rstudio() && is_installed("rstudioapi")) { # If the package has Rd macros, this needs a version of rstudio # that loads them, see rstudio/rstudio#12111 version_needed <- if (has_rd_macros(dirname(dirname(x$path)))) "2022.12.0.256" if (rstudioapi::hasFun("previewRd", version_needed = version_needed)) { return(rstudioapi::callFun("previewRd", x$path)) } } # otherwise render and serve file <- fs::path_ext_set(fs::path_file(x$path), type) # This directory structure is necessary for RStudio to open the # .html file in the help pane (see rstudio/rstudio#11336) doc_path <- fs::path("doc", "html", file) path <- fs::path(tempdir(), ".R", doc_path) fs::dir_create(fs::path_dir(path), recurse = TRUE) if (type == "text") { topic_write_text(x, path) title <- paste(x$pkg, basename(x$path), sep = ":") file.show(path, title = title) } else if (type == "html") { topic_write_html(x, path) if (is_rstudio()) { # This localhost URL is also part of getting RStudio to open in # the help pane port <- httpdPort() url <- sprintf("http://localhost:%i/%s", port, doc_path) } else { url <- path } utils::browseURL(url) } } on_load( httpdPort %<~% env_get(rlang::ns_env("tools"), "httpdPort") ) topic_write_text <- function(x, path) { macros <- load_rd_macros(dirname(dirname(x$path))) tools::Rd2txt( x$path, out = path, package = x$pkg, stages = x$stage, macros = macros ) } topic_write_html <- function(x, path) { macros <- load_rd_macros(dirname(dirname(x$path))) tools::Rd2HTML( x$path, out = path, package = x$pkg, stages = x$stage, no_links = TRUE, macros = macros ) css_path <- file.path(tempdir(), "R.css") if (!file.exists(css_path)) { file.copy(file.path(R.home("doc"), "html", "R.css"), css_path) } } topic_lines <- function(x, type = c("text", "html")) { file <- withr::local_tempfile() switch( arg_match(type), text = topic_write_text(x, file), html = topic_write_html(x, file) ) readLines(file) } #' Drop-in replacements for help and ? functions #' #' The `?` and `help` functions are replacements for functions of the #' same name in the utils package. They are made available when a package is #' loaded with [load_all()]. #' #' The `?` function is a replacement for [utils::?()] from the #' utils package. It will search for help in devtools-loaded packages first, #' then in regular packages. #' #' The `help` function is a replacement for [utils::help()] from #' the utils package. If `package` is not specified, it will search for #' help in devtools-loaded packages first, then in regular packages. If #' `package` is specified, then it will search for help in devtools-loaded #' packages or regular packages, as appropriate. #' #' @param topic A name or character string specifying the help topic. #' @param package A name or character string specifying the package in which #' to search for the help topic. If NULL, search all packages. #' @param e1 First argument to pass along to `utils::`?``. #' @param e2 Second argument to pass along to `utils::`?``. #' @param ... Additional arguments to pass to [utils::help()]. #' #' @rdname help #' @name help #' @usage # help(topic, package = NULL, ...) #' #' @examples #' \dontrun{ #' # This would load devtools and look at the help for load_all, if currently #' # in the devtools source directory. #' load_all() #' ?load_all #' help("load_all") #' } #' #' # To see the help pages for utils::help and utils::`?`: #' help("help", "utils") #' help("?", "utils") #' #' \dontrun{ #' # Examples demonstrating the multiple ways of supplying arguments #' # NB: you can't do pkg <- "ggplot2"; help("ggplot2", pkg) #' help(lm) #' help(lm, stats) #' help(lm, 'stats') #' help('lm') #' help('lm', stats) #' help('lm', 'stats') #' help(package = stats) #' help(package = 'stats') #' topic <- "lm" #' help(topic) #' help(topic, stats) #' help(topic, 'stats') #' } shim_help <- function(topic, package = NULL, ...) { # Reproduce help's NSE for topic - try to eval it and see if it's a string topic_name <- substitute(topic) is_string <- tryCatch( error = function(...) FALSE, { force(topic) is_string(topic) } ) if (is_string) { topic_str <- topic topic_name <- sym(topic) } else if (missing(topic_name)) { # Leave the vars missing } else if (is_null(topic_name)) { topic_str <- NULL topic_name <- NULL } else { topic_str <- deparse(substitute(topic)) if (length(topic_str) != 1) { cli::cli_abort("{.arg topic} must be a name.") } } # help's NSE for package is slightly simpler package_name <- substitute(package) if (is_symbol(package_name)) { package_str <- as_string(package_name) } else if (is_null(package_name)) { package_str <- NULL } else { package_str <- package package_name <- sym(package) } use_dev <- (!missing(topic) && is_string(package_str) && package_str %in% dev_packages()) || (!missing(topic_name) && is_null(package_str) && !is_null(dev_topic_find(topic_str))) if (use_dev) { dev_help(topic_str, package_str) } else { inject(utils::help( !!maybe_missing(topic_name), !!maybe_missing(package_name), ... )) } } #' @usage #' # ?e2 #' # e1?e2 #' #' @rdname help #' @name ? shim_question <- function(e1, e2) { # Get string version of e1, for find_topic e1_expr <- substitute(e1) if (is.name(e1_expr)) { # Called with a bare symbol, like ?foo topic <- as.character(e1_expr) pkg <- NULL } else if (is.call(e1_expr)) { if (identical(e1_expr[[1]], quote(`?`))) { # ??foo topic <- NULL pkg <- NULL } else if (identical(e1_expr[[1]], quote(`::`))) { # ?bar::foo topic <- as.character(e1_expr[[3]]) pkg <- as.character(e1_expr[[2]]) } else { # ?foo(12) topic <- deparse(e1_expr[[1]]) pkg <- NULL } } else if (is.character(e1_expr)) { topic <- e1 pkg <- NULL } else { cli::cli_abort("Unknown input.") } # Search for the topic in devtools-loaded packages. # If not found, call utils::`?`. if (!is.null(topic) && !is.null(dev_topic_find(topic, pkg))) { dev_help(topic, pkg) } else { eval(as.call(list(utils::`?`, substitute(e1), substitute(e2)))) } } pkgload/R/dev-example.R0000644000176200001440000000455314502515617014443 0ustar liggesusers#' Run a examples for an in-development function. #' #' `dev_example` is a replacement for `example`. `run_example` #' is a low-level function that takes a path to an Rd file. #' #' @param topic Name or topic (or name of Rd) file to run examples for #' @param quiet If `TRUE`, does not echo code to console. #' @export #' @family example functions #' @examples #' \dontrun{ #' # Runs installed example: #' library("ggplot2") #' example("ggplot") #' #' # Runs development example: #' dev_example("ggplot") #' } dev_example <- function(topic, quiet = FALSE) { topic <- dev_help(topic) run_example(topic$path, quiet = quiet) } #' @rdname dev_example #' @export #' @param path Path to `.Rd` file #' @param run_dontrun if `TRUE`, do run `\dontrun` sections in the Rd files. #' @param run_donttest if `TRUE`, do run `\donttest` sections in the Rd files. #' @param env Environment in which code will be run. #' @param macros Custom macros to use to parse the `.Rd` file. See the #' `macros` argument of [tools::parse_Rd()]. If `NULL`, then the #' [tools::Rd2ex()] (and [tools::parse_Rd()]) default is used. #' @param run,test Deprecated, see `run_dontrun` and `run_donttest` above. run_example <- function(path, run_donttest = FALSE, run_dontrun = FALSE, env = new.env(parent = globalenv()), quiet = FALSE, macros = NULL, run, test) { if (!missing(run)) { cli::cli_warn("{.code run_example(run =)} is deprecated, please use {.code run_example(run_dontrun =)} instead") run_dontrun <- run } if (!missing(test)) { cli::cli_warn("{.code run_example(test =)} is deprecated, please use {.code run_example(run_donttest =)} instead") run_donttest <- test } if (!file.exists(path)) { cli::cli_abort("The path {.path {path}} must exit.") } tmp <- tempfile(fileext = ".R") if (is.null(macros)) { tools::Rd2ex( path, out = tmp, commentDontrun = !run_dontrun, commentDonttest = !run_donttest ) } else { tools::Rd2ex( path, out = tmp, commentDontrun = !run_dontrun, commentDonttest = !run_donttest, macros = macros ) } if (file.exists(tmp)) { source(tmp, echo = !quiet, local = env, max.deparse.length = Inf) } invisible(env) } pkgload/R/file-cache.R0000644000176200001440000000142414247353057014212 0ustar liggesusers# Generate checksums for a vector of file paths. # @keywords internal md5 <- function(paths) { unlist(lapply(paths, tools::md5sum)) } make_cache <- function() { .file_cache <- character() make <- function(paths) { paths <- path.expand(paths) new_hash <- md5(paths) old_hash <- .file_cache[paths] changed <- is.na(old_hash) | new_hash != old_hash .file_cache[paths[changed]] <<- new_hash[changed] paths[changed] } clear <- function() { .file_cache <<- character() } list(make = make, clear = clear) } .cache <- make_cache() # Given vector of paths, return only those paths that have changed since the # last invocation. # @keywords internal changed_files <- .cache$make # Clear file cache. # @keywords internal clear_cache <- .cache$clear pkgload/R/aaa.R0000644000176200001440000000033214247353057012751 0ustar liggesusers#' @import rlang NULL onload_assign <- local({ names <- character() funs <- list() function(name, x) { names[length(names) + 1] <<- name funs[[length(funs) + 1]] <<- substitute(x) } }) pkgload/R/load-dll.R0000644000176200001440000001027314247353057013724 0ustar liggesusers#' Load a compiled DLL #' #' @param path Path to a package, or within a package. #' @keywords programming #' @name load_dll #' @usage load_dll(path = ".") #' @export onload_assign("load_dll", { for_loop <- modify_lang( f = function(x) if (comp_lang(x, quote(library.dynam()), 1)) { quote(library.dynam2(path, lib)) } else { x }, extract_lang(body(loadNamespace), comp_lang, y = quote(for (i in seq_along(dynLibs)) NULL), idx = 1:3)) ## The code below taken directly from base::loadNamespace ## https://github.com/wch/r-source/blob/tags/R-3-3-0/src/library/base/R/namespace.R#L466-L485 ## except for the call to library.dynam2, which is a special version of ## library.dynam load_dll <- function(path = ".") { package <- pkg_name(path) env <- ns_env(package) nsInfo <- parse_ns_file(path) dlls <- list() dynLibs <- nsInfo$dynlibs nativeRoutines <- list() !!for_loop addNamespaceDynLibs(env, nsInfo$dynlibs) # Delete the temporary SO when the namespace gets garbage collected dll_path <- dlls[[package]][["path"]] if (!is_null(dll_path)) { new_weakref(env, finalizer = ns_finalizer(dll_path)) } invisible(dlls) } load_dll <- expr_interp(load_dll) fn_env(load_dll) <- rlang::ns_env("pkgload") load_dll }) ns_finalizer <- function(path) { force(path) function(...) { if (!is_string(path)) { return(NULL) } # Clean up the temporary .so file. unlink(path) # Remove the .so from the cached list of loaded modules loaded <- .dynLibs() loaded <- Filter(function(x) !is_string(x[["path"]], path), loaded) .dynLibs(loaded) } } # Return a list of currently loaded DLLs from the package loaded_dlls <- function(package) { libs <- .dynLibs() matchidx <- vapply(libs, "[[", character(1), "name") == package libs[matchidx] } # This is a replacement for base::library.dynam, with a slightly different # call interface. The original requires that the name of the package is the # same as the directory name, which isn't always the case when loading with # devtools. This version allows them to be different, and also searches in # the src/ directory for the DLLs, instead of the libs/$R_ARCH/ directory. library.dynam2 <- function(path = ".", lib = "") { path <- pkg_path(path) dyn_ext <- .Platform$dynlib.ext dllname <- paste(lib, dyn_ext, sep = "") dllfile <- package_file("src", dllname, path = path) if (!file.exists(dllfile)) { return(invisible()) } # Copy the .so to a temporary directory with a unique name. This way # we may have different versions of the .so loaded, in case # references to the previously loaded .so linger in the session. # The .so should have the package name so that R can find the # `R_init_` function by itself. dll_copy_dir <- tempfile("pkgload") dll_copy_file <- file.path(dll_copy_dir, dllname) dir.create(dll_copy_dir) file.copy(dllfile, dll_copy_file) # # The loading and registering of the dll is similar to how it's done # # in library.dynam. dllinfo <- dyn.load(dll_copy_file) # Register dll info so it can be unloaded with library.dynam.unload .dynLibs(c(.dynLibs(), list(dllinfo))) return(dllinfo) } # This is taken directly from base::loadNamespace() # https://github.com/wch/r-source/blob/tags/R-3-3-0/src/library/base/R/namespace.R#L270-L273 onload_assign("addNamespaceDynLibs", eval(extract_lang(body(loadNamespace), comp_lang, y = quote(addNamespaceDynLibs <- NULL), idx = 1:2)[[3]])) # This is taken directly from base::loadNamespace # https://github.com/wch/r-source/blob/tags/R-3-3-0/src/library/base/R/namespace.R#L287-L308 # The only change is the line used get the package name onload_assign("assignNativeRoutines", { f <- eval( extract_lang(body(loadNamespace), comp_lang, y = quote(assignNativeRoutines <- NULL), idx = 1:2)[[3]]) body(f) <- as.call(append(after = 1, as.list(body(f)), quote(package <- methods::getPackageName(env)))) f }) try_load_dll <- function(path = ".") { try_fetch( load_dll(path = path), error = function(cnd) { cli::cli_warn("Failed to load at least one DLL.", parent = cnd) list() } ) } pkgload/R/dev-meta.R0000644000176200001440000000214314502515617013727 0ustar liggesusers#' Return devtools metadata environment #' #' If the package was not loaded with devtools, returns `NULL`. #' #' @param name The name of a loaded package #' @keywords internal #' @examples #' dev_meta("stats") # NULL #' #' if (has_tests()) { #' # Load the test package in directory "testLoadHooks" #' load_all(pkgtest("testLoadHooks")) #' #' # Get metadata for the package #' x <- dev_meta("testLoadHooks") #' as.list(x) #' #' # Clean up. #' unload("testLoadHooks") #' } #' @export dev_meta <- function(name) { ns <- .getNamespace(name) if (is.null(ns)) { cli::cli_abort(c( "Namespace not found for {.arg {name}}", "i" = "Is it loaded?" )) } if (is.null(ns$.__DEVTOOLS__)) { return(NULL) } ns$.__DEVTOOLS__ } # Create the devtools metadata environment for a package. # This should be run when packages are loaded by devtools. create_dev_meta <- function(name) { ns <- .getNamespace(name) if (!is.null(ns$.__DEVTOOLS__)) { cli::cli_abort("Devtools metadata for package {.pkg {name}} can't already exist.") } ns$.__DEVTOOLS__ <- new.env(parent = ns) ns$.__DEVTOOLS__ } pkgload/R/dev-topic.R0000644000176200001440000000621414502560210014107 0ustar liggesusers# Tools for indexing package documentation by alias, and for finding # the rd file for a given topic (alias). rd_files <- function(path) { path <- pkg_path(path) path_man <- package_file("man", path = path) files <- dir(path_man, pattern = "\\.[Rr]d$", full.names = TRUE) names(files) <- basename(files) sort_ci(files) } #' @rdname dev_help #' @export dev_topic_find <- function(topic, dev_packages = NULL) { topic <- dev_topic_parse(topic, dev_packages) for (pkg_name in topic$pkg_names) { path <- dev_topic_path(topic$topic, path = ns_path(pkg_name)) if (!is.null(path)) { return(list(path = path, pkg = pkg_name)) } } NULL } dev_topic_parse <- function(topic, dev_packages = NULL) { stopifnot(is_string(topic)) pieces <- strsplit(topic, ":::?")[[1]] if (length(pieces) == 1) { if (is.null(dev_packages)) { pkgs <- dev_packages() } else { pkgs <- dev_packages } } else { pkgs <- pieces[1] topic <- pieces[2] } list( topic = topic, pkg_names = pkgs ) } dev_topic_path <- function(topic, path = ".") { # Don't interpret the division operator as a path (#198) if (is_string(topic, "/")) { return(NULL) } path <- pkg_path(path) # First see if a man file of that name exists man <- package_file("man", topic, path = path) if (file.exists(man)) { return(man) } # Next, look in index index <- dev_topic_index(path) if (topic %in% names(index)) { return(package_file("man", last(index[[topic]]), path = path)) } # Finally, try adding .Rd to name man_rd <- package_file("man", paste0(topic, ".Rd"), path = path) if (file.exists(man_rd)) { return(man_rd) } NULL } # Cache ------------------------------------------------------------------- dev_topic_indices <- new.env(parent = emptyenv()) #' @rdname dev_help #' @param path Path to package. #' @export dev_topic_index <- function(path = ".") { path <- pkg_path(path) package <- pkg_name(path) if (!exists(pkg_name(path), dev_topic_indices)) { dev_topic_indices[[package]] <- build_topic_index(path) } dev_topic_indices[[package]] } #' @rdname dev_help #' @param pkg_name Name of package. #' @export dev_topic_index_reset <- function(pkg_name) { if (exists(pkg_name, dev_topic_indices)) { rm(list = pkg_name, envir = dev_topic_indices) } invisible(TRUE) } # Topic index ------------------------------------------------------------- build_topic_index <- function(path = ".") { path <- pkg_path(path) macros <- load_rd_macros(path) rds <- rd_files(path) # Pass `permissive = TRUE` to suppress warnings about unknown # macros (#119). It is unlikely that a macro generates `name` or # `alias` commands, so we shouldn't be missing any topics from # unknown macros. aliases <- function(path) { parsed <- tools::parse_Rd(path, macros = macros, permissive = TRUE) tags <- vapply(parsed, function(x) attr(x, "Rd_tag")[[1]], character(1)) unlist(parsed[tags == "\\alias"]) } invert(lapply(rds, aliases)) } invert <- function(L) { if (length(L) == 0) return(L) t1 <- unlist(L) names(t1) <- rep(names(L), lapply(L, length)) tapply(names(t1), t1, c) } pkgload/R/load-depends.R0000644000176200001440000000130714250570016014557 0ustar liggesusersload_depends <- function(path = ".", quiet = NULL) { path <- pkg_path(path) quiet <- load_all_quiet(quiet, "load_depends") description <- pkg_desc(path) # Get data frame of dependency names and versions deps <- description$get_deps() depends <- deps[deps$type == "Depends" & deps$package != "R", ] if (length(depends) == 0) { return(invisible()) } deps_check_installed(path, depends) # The `quietly` argument of `require()` does not affect attachment # of required packages if (quiet) { maybe_suppress <- suppressMessages } else { maybe_suppress <- identity } maybe_suppress( lapply(depends$package, require, character.only = TRUE) ) invisible(depends) } pkgload/R/package.R0000644000176200001440000000464614451231442013624 0ustar liggesusers#' Find file in a package. #' #' It always starts by finding by walking up the path until it finds the #' root directory, i.e. a directory containing `DESCRIPTION`. If it #' cannot find the root directory, or it can't find the specified path, it #' will throw an error. #' #' @param ... Components of the path. #' @param path Place to start search for package directory. #' @export #' @examples #' \dontrun{ #' package_file("figures", "figure_1") #' } package_file <- function(..., path = ".") { file.path(pkg_path(path), ...) } # Mockable variant of interactive interactive <- function() .Primitive("interactive")() #' Is the package currently under development? #' #' Returns `TRUE` or `FALSE` depending on if the package has been loaded by #' **pkgload**. #' #' @param name the name of a package. #' @export is_dev_package <- function(name) name %in% dev_packages() #' Helper functions for working with development packages. #' #' All functions search recursively up the directory tree from the input path #' until they find a DESCRIPTION file. #' @inheritParams load_all #' @name packages NULL #' @describeIn packages Return the normalized package path. #' @export pkg_path <- function(path = ".") { path <- tryCatch({ rprojroot_find_package_root_file(path = path) }, error = function(e) { msg <- c( "Could not find a root 'DESCRIPTION' file that starts with '^Package' in {.path {normalizePath(path)}}.", "i" = "Are you in your project directory and does your project have a 'DESCRIPTION' file?" ) cli::cli_abort(msg, class = "pkgload_no_desc") }) # Strip trailing slashes, which can cause errors on Windows (#73) sub("[/\\]$", "", path) } #' @describeIn packages Return the package name. #' @export pkg_name <- function(path = ".") { desc_desc_get_field("Package", file = pkg_path(path)) } #' @describeIn packages Return the package DESCRIPTION as a [desc::desc()] object. #' @export pkg_desc <- function(path = ".") { desc_desc(pkg_path(path)) } #' @describeIn packages Return the parsed package version. #' @export pkg_version <- function(path = ".") { desc_desc_get_version(pkg_path(path)) } #' @describeIn packages Return the raw package version (as a string). #' @export pkg_version_raw <- function(path = ".") { desc_desc_get_field("Version", file = pkg_path(path))[[1]] } #' @describeIn packages Return the package namespace. #' @export pkg_ns <- function(path = ".") { ns_env(pkg_name(path)) } pkgload/R/shims.R0000644000176200001440000001475114547266765013400 0ustar liggesusers# Insert shim objects into a package's imports environment # # @param pkg A path or package object insert_imports_shims <- function(package) { imp_env <- imports_env(package) imp_env$system.file <- shim_system.file imp_env$library.dynam.unload <- shim_library.dynam.unload imp_env$library.dynam <- shim_library.dynam } # Create a new environment as the parent of global, with devtools versions of # help, ?, and system.file. insert_global_shims <- function(force = FALSE) { if ("devtools_shims" %in% search()) { if (!force) { # If shims already present, just return return() } base::detach("devtools_shims") } e <- new.env() e$help <- shim_help e$`?` <- shim_question e$system.file <- shim_system.file base::attach(e, name = "devtools_shims", warn.conflicts = FALSE) } #' Replacement version of system.file #' #' This function is meant to intercept calls to [base::system.file()], #' so that it behaves well with packages loaded by devtools. It is made #' available when a package is loaded with [load_all()]. #' #' When `system.file` is called from the R console (the global #' environment), this function detects if the target package was loaded with #' [load_all()], and if so, it uses a customized method of searching #' for the file. This is necessary because the directory structure of a source #' package is different from the directory structure of an installed package. #' #' When a package is loaded with `load_all`, this function is also inserted #' into the package's imports environment, so that calls to `system.file` #' from within the package namespace will use this modified version. If this #' function were not inserted into the imports environment, then the package #' would end up calling `base::system.file` instead. #' @inheritParams base::system.file #' #' @rdname system.file #' @name system.file shim_system.file <- function(..., package = "base", lib.loc = NULL, mustWork = FALSE) { # If package wasn't loaded with devtools, pass through to base::system.file. # If package was loaded with devtools (the package loaded with load_all) # search for files a bit differently. if (!(package %in% dev_packages())) { return(base::system.file( ..., package = package, lib.loc = lib.loc, mustWork = mustWork )) } # Note that the behavior isn't exactly the same as base::system.file with an # installed package; in that case, C and D would not be installed and so # would not be found. Some other files (like DESCRIPTION, data/, etc) would # be installed. To fully duplicate R's package-building and installation # behavior would be complicated, so we'll just use this simple method. if (dots_n(...) && is_string(..1)) { if (is_string("inst", ..1) || grepl("^inst/", ..1)) { cli::cli_abort(c( "Paths can't start with `inst`", i = "Files in `inst` are installed at top-level." )) } } pkg_path <- find.package(package) # First look in inst/ files_inst <- file.path(pkg_path, "inst", ...) present_inst <- file.exists(files_inst) # For any files that weren't present in inst/, look in the base path files_top <- file.path(pkg_path, ...) present_top <- file.exists(files_top) # Merge them together. Here are the different possible conditions, and the # desired result. NULL means to drop that element from the result. # # files_inst: /inst/A /inst/B /inst/C /inst/D # present_inst: T T F F # files_top: /A /B /C /D # present_top: T F T F # result: /inst/A /inst/B /C NULL # files <- files_top files[present_inst] <- files_inst[present_inst] # Drop cases where not present in either location files <- files[present_inst | present_top] if (length(files) > 0) { # Make sure backslahses are replaced with slashes on Windows normalizePath(files, winslash = "/") } else { if (mustWork) { cli::cli_abort("Can't find package file.", call = NULL) } "" } } shim_library.dynam.unload <- function(chname, libpath, verbose = getOption("verbose"), file.ext = .Platform$dynlib.ext) { # If package was loaded by devtools, we need to unload the dll ourselves # because libpath works differently from installed packages. if (!is.null(dev_meta(chname))) { try({ unload_dll(pkg_name(libpath)) }) return() } # Should only reach this in the rare case that the devtools-loaded package is # trying to unload a different package's DLL. base::library.dynam.unload(chname, libpath, verbose, file.ext) } # This shim version of library.dynam addresses the issue raised in: # https://github.com/r-lib/pkgload/issues/48 It helps `load_all()` to # find libraries placed within inst/libs/ This CRAN-incompatible # practice allows for including a custom compiled dll in an R package. # See also https://stackoverflow.com/questions/8977346. # # This shim function first attempts using base::library.dynam() if # that fails it uses `inst_library.dynam()` which is very similar but # inserts "inst/" in the dll/so path. shim_library.dynam <- function(chname, package, lib.loc, verbose = getOption("verbose"), file.ext = .Platform$dynlib.ext, ...) { err <- tryCatch( return(base::library.dynam( chname, package, lib.loc, verbose = getOption("verbose"), file.ext = .Platform$dynlib.ext, ... )), error = identity ) # Call version of library.dynam that adds the inst subdirectory to # the dll paths tryCatch( return(inst_library.dynam( chname, package, lib.loc, verbose = getOption("verbose"), file.ext = .Platform$dynlib.ext, ... )), error = identity ) # Signal original error for debugging cnd_signal(err) } # Version of library.dynam that looks for libraries or objects to load # within the `inst` package subdirectory on_load( inst_library.dynam <- modify_lang(base::library.dynam, file_path_update) ) file_path_update <- function(x) { if (is_file_path(x)) { x[[3]] <- file.path("inst", "libs") } x } is_file_path <- function(x) { if (!is_call(x, "file.path")) { return(FALSE) } args <- as.list(x[2:3]) identical(args, list(quote(pkg), "libs")) } pkgload/R/pkgload-package.R0000644000176200001440000000013514247353057015242 0ustar liggesusers#' @keywords internal "_PACKAGE" ## usethis namespace: start ## usethis namespace: end NULL pkgload/R/enc.R0000644000176200001440000000044414247353057013000 0ustar liggesusersread_lines_enc <- function(path, file_encoding = "UTF-8", n = -1L, ok = TRUE, skipNul = FALSE) { con <- file(path, encoding = file_encoding) on.exit(close(con), add = TRUE) lines <- readLines(con, warn = FALSE, n = n, ok = ok, skipNul = skipNul) Encoding(lines) <- "UTF-8" lines } pkgload/NEWS.md0000644000176200001440000002506514551453262013010 0ustar liggesusers# pkgload 1.3.4 * On load, pkgload now sets `PKGLOAD_PARENT_TEMPDIR` to the temporary directory used in the current process. This provides a convenient place to cache results for functions used in subprocesses (e.g. `devtools::test()`, `devtools::document()`). * Fixes for Debian packaging. # pkgload 1.3.3 * `dev_topic_index()` is now exported (#257). * Fix handling of active bindings inside a package during unloading (#255, @klmr). * The `helpers` argument of `load_all` now defaults to the value provided for the `export_all` arguments. This makes the behaviour safer by default (#244). * pkgload now depends unconditionally on pkgbuild (#249). * `load_all()` no longer standardises version number in namespace metadata (#231). * New `pkg_version_raw()` to get raw package version as a string. # pkgload 1.3.2 * Fixes for CRAN checks. # pkgload 1.3.1 * `dev_topic_find()` is now exported (#215). * `dev_help()` will remind you to run `pkgload::load_all()` if no in-development packages are found (#221). * Shimmed `?` now works even if you've renamed the documentation topic (#220). * `dev_help()` now works with an RStudio daily to deliver a rendered development documentation that includes working images and links (#228). # pkgload 1.3.0 * `load_all()` now calls `rlang::check_installed()` to prompt whether to install missing packages. Outdated and missing dependencies are installed using pak if installed. If not, the remotes package is used if installed. Otherwise `install.packages()` is used as a last resort but this method does not support Remotes fields. * `load_all()` gains an `attach` argument set to `TRUE` by default (#209). If set to `FALSE`, `load_all()` creates a new namespace but doesn't create a package environment on the search path. In this case, it is more similar to `loadNamespace()` than to `library()`. * Improved the way help pages are displayed in RStudio. This makes the behaviour within and outside RStudio consistent and fixes issues with Rd macros (#120). * `unregister()` is now exported. This is a gentler version of `unload()` which removes the package from the search path, unregisters methods, and unregisters the namespace. However it doesn't try to unload the namespace or its DLL so that dangling references keep working. * User `onLoad` hooks are now run after exports have been populated. This allows the hook to use exported functions. * The loaded namespace is now locked just before user `onLoad` hooks are run. This better reproduced the namespace sealing behaviour of regular loading. The package environment environment is now locked as well before both the user and package `onAttach` hooks are run. * Added support for loading a .so or .dll file from the `inst` folder via a new `library.dynam()` shim (@ethanplunkett, #48). * The `system.file()` shim now fails if you supply a path that starts with `inst` to better reproduce the behaviour with installed packages (#104). * `load_all()` now imports its dependencies lazily to avoid parallel installation issues (#89). * Unknown Rd macros no longer trigger a warning when building the package topic index (#119). * `load_all(compile = TRUE)` now forces a full recompilation (#93). * The advice about running `rm()` to remove conflicts with objects in the global environment is now clickable in RStudio (#199). * New `is_loading()` predicate to detect whether `load_all()` is currently running (#134). * `.dynLibs()` is no longer emptied when package with no DLL is unloaded (#176). * The `?` shim no longer interprets `?"/"` as a path (#198). * rstudioapi is no longer a hard dependency of pkgload (#187). * Errors thrown in user hooks are now demoted to a warning condition. Previously they were demoted using `try()`, making it harder to debug them. * `load_all()` correctly re-loads modified translations, avoiding the usual gettext behaviour. # pkgload 1.2.4 * Lionel Henry is now the maintainer. * `load_all()` automatically registers package translations, if found. # pkgload 1.2.3 * pkgload now forces all bindings on unload. This fixes errors and inconsistencies when dangling references force lazy bindings after unload or reload. * `load_all()` now restores S3 methods registered by third party packages (#163). * `load_dll()` will now preserve the DLL name when loading instead of always using the package name. This allows packages to include DLL's with different names (#162, @dfalbel). # pkgload 1.2.2 # pkgload 1.2.1 * `unload()` no longer unregisters methods for generics of the package being unloaded. This way dangling references to generics defined in the stale namespace still work as expected (r-lib/vctrs#1341). * `load_all()` will now work for packages that have testthat tests but do not have testthat installed (#151) * The `pkgbuild` dependency has been moved to `Suggests`, as it is only needed for packages with compiled code. * `load_all()` will now work for packages that have testthat tests but do not have testthat installed (#151) * `load_all(warn_conflicts = TRUE)` becomes more narrow and only warns when a *function* in the global environment masks a *function* in the package, consistent with the docs (#125, #143 @jennybc). * `load_all()` no longer does a comprehensive check on the `DESCRIPTION` file when loading, instead just checking that it exists and starts with Package (#149, @malcolmbarrett) * `unload()` no longer warns when it can't unload a namespace. # pkgload 1.2.0 * Fix test failure in R 4.1 with regards to S4 method registration * `load_all()` now preserves existing namespaces in working order. In particular, it doesn't unload the package's shared library and keeps it loaded instead. When reloading, a copy of the SO for the new namespace is loaded from a temporary location. These temporary SOs are only unloaded on GC and deleted from their temporary location via a weak reference attached to the namespace. This mechanism ensures that lingering references to the namespace keep working as expected. Consequently the namespace propagation routine that was added to pkgload as a workaround has been removed. Note that `.Call()` invocations that pass a string symbol rather than a structured symbol may keep crashing, because R will look into the most recently loaded SO of a given name. Since symbol registration is now the norm, we don't expect this to cause much trouble. * `load_all()` no longer forces all bindings of a namespace to avoid lazy-load errors. Instead, it removes exported S3 methods from the relevant tables. - This improves the loading behaviour with packages that define objects in their namespaces lazily (e.g. with `delayedAssign()`). - This also makes `load_all()` more predictable after a method has been removed from the package. It is now actually removed from the generic table. It would previously linger until R was restarted. * If `load_all()` attaches testthat, it automatically suppresses conflicts. # pkgload 1.1.0 * `dev_example()` now works after removing an inconsistent call to `load_all()` (@riccardoporreca, #122). * `load_all()` now issues a warning if exported objects conflict with objects defined in the global environment (#112) * `run_example()` arguments `run` and `test` are deprecated in favor of the (hopefully) more clear `run_dontrun` and `run_donttest` (#107). * Internal fixes for compatibility with the future 4.1.0 release. # pkgload 1.0.2 * `shim_question()` now works for topics from the R base package that are passed with the double colon operator (e.g. `base::min`) (@mdequeljoe, #99). * `load_all()` now allows using explicitly qualified, exported names in test helpers (@klmr, #95). * `load_all()` gains a `compile` argument which controls more finely whether to compile the code or not. The `recompile` argument is now deprecated and will be removed in a future version of pkgload. # pkgload 1.0.1 * `unload()` now only removes S4 classes which were generated in the package being unloaded (#75) * `help()` will no longer error when trying to load package level help (#67). * Trailing slashes now removed from all paths, which fixes issues on Windows (#73). * `load_dll()` now fixed in R-devel (#77). * The help shim's now work for `:::` inputs (#72). # pkgload 1.0.0 * `load_all()` now updates imports of dependent packages when a package is reloaded (#59). * `load_all()` now assigns `DESCRIPTION/Depends` to `.Depends` object of package environment. (@yiufung pkgload#61) * `load_all()` now attaches `testthat` if the `attach_testthat` option is `TRUE`. This allows `load_all()` to more closely mimic the testing environment. (#56) * `check_dep_version()` and `check_suggested()` are now exported. * `check_dep_version()` now emits a warning and returns `FALSE` rather than aborting. (#47) * Package imports are now exported when using `load_all()`. This behavior can be disabled by using `load_all(export_imports = FALSE)`. * The `as.package()` and `is.package()` functions have been removed. * `load_code()`, `load_data()`, `load_dll()`, `load_all()`, `parse_ns_file()` all now take an explicit path rather than a path or a `package` object. * `imports_env()`, `ns_env()`, `pkg_env()` and `unload()` now take a package name rather than a path or a `package` object. * `run_example()` now works on R 3.1. * `unload()` now unloads S4 classes for packages loaded with `library()` as well as `load_all()` (#46). * `load_all()` gains a `helpers` option to specify whether or not to source testthat helpers. (@pitakakariki devtools #1202) * `load_all()` now sources the testthat helpers in the namespace environment rather than the package environment (#40). * `load_all()` now sets the `NOT_CRAN` environment variable when it sources testthat helpers. It also sets `DEVTOOLS_LOAD` to "true" so that you can check whether they are run during package loading. * `dev_topic_path()` now only returns the last path found, fixing an error when a package has both a package function level help with the same name. (#21) * New function `is_dev_package()` to determine if a given package has been loaded by `pkgload::load_all()` (#2). * `load_all()` no longer updates the collate directive. Instead this functionality has been moved to `devtools::document()`. * `dev_help()` now optionally takes a character vector of packages to search within. This replaces `find_topic()`. * `dev_topic_index_reset()` is now exported, and allows you to reset the topic index associated with a given package. * Added a `NEWS.md` file to track changes to the package. * Initial release from code spun off from devtools pkgload/MD50000644000176200001440000003707614551472164012231 0ustar liggesusers59d7d73665a88748727dbb3119c4bccc *DESCRIPTION 6e6e3c7e91956aee9c18f6e7fc0955d9 *NAMESPACE 200e6d219cabcfa3d142dbb29cad6210 *NEWS.md a9cebe46e41ae836bd6d65f9aa5393b6 *R/aaa.R b711d0c3c4964e4191e2bd766b5ba0a3 *R/dev-example.R 4dee1fdf259c764367f0c185afad8785 *R/dev-help.R 755a2937d012aacc7e77e730933a5dec *R/dev-meta.R 514c450e1c40875082e9df90fdf5671a *R/dev-topic.R ce8cd86bf8ce6af5800835dc5dd519a6 *R/enc.R ec20041c1e398e82c95c105a8ea8b542 *R/file-cache.R a37296942d3237fc411927c2715dd184 *R/has_tests.R 0a48cbbfd58277c193859a40f9404853 *R/imports-env.R 3828ece4f7f3d42bb62e7c5e117ea995 *R/inst.R 8fa669e74e0f4916df7686321d923a31 *R/load-code.R 39dc14e21ff57b1e6e32508f8f2b51b0 *R/load-data.R fd8a7cb567e20b4434550dd10ee6e416 *R/load-depends.R 05a25f08cdd83535a79bcb70f5e64f54 *R/load-dll.R 0d56e3b5ea9817db6c4467002d7be8b8 *R/load.R ac982054388305b5afa5717a2d12e2d2 *R/namespace-env.R f9db8ae5cd99895304507048c9509071 *R/package-deps.R 2232496418fc1708ac4600ab304a0924 *R/package-env.R 5f658a4aed9eec98ecf2f3a2c25b8773 *R/package.R df6cc46bc7fae1a55b713f3d5065b35a *R/pkgload-package.R 4d64aeb23d01abfff5142422d92c9fa1 *R/po.R 125cb55469aaa50ff1ac46646b26136c *R/remove-s4-class.R 0ced33eefbc13142be6566ac8e18fd83 *R/run-loadhooks.R 54e02054014a0b7398ebc6aead1d6df7 *R/shims.R 9925453b25c2f5042abb50ab70e62169 *R/source.R 5d5f2a38777a41ae45e3e67418585497 *R/unload.R 137830b86402ceb34b9019ab1233dd75 *R/utils.R 12ab111490aead6e6fd41fbebd1ab65e *R/zzz.R 640486097e1f539947846012132def05 *README.md 04a4c539154069ec2326a98e04179aa1 *inst/WORDLIST a40bb554c32ce17f55d37d85abebb147 *man/check_dep_version.Rd 4e6de018cc978094a65295459492b9f8 *man/check_suggested.Rd 482d2f6a8126e4852e5449c59d1ce850 *man/dev_example.Rd 9a18c8986cb975889dcf394400224add *man/dev_help.Rd f4cb71a738a19d7faf830356987aeb6a *man/dev_meta.Rd 5f213ad75ab776275a30b7331a2f7517 *man/has_tests.Rd 09b00b0952d9a5c89d4381e18db6b992 *man/help.Rd 0b35e94d0d9c41a063dd1eeeac896ede *man/imports_env.Rd 4d8665b10c04cb52076442c04afd9bf9 *man/inst.Rd 7f8113aa325da659a584cf4e1c271c97 *man/is_dev_package.Rd dc4069c40c91d1976609b0f379938484 *man/load_all.Rd 188e92c4598432b3ff73aa2be058d5f9 *man/load_code.Rd 4db07fb8c690e3cda83646a9f5057a00 *man/load_data.Rd be0f8d58b442e1f1642702e75942a224 *man/load_dll.Rd a9d9c45fbe93753d0d4647e6a069ccd5 *man/load_imports.Rd bac1d2056fa7399271cb1dfebde24389 *man/ns_env.Rd caddfc70119954a1c9ddec396ccab345 *man/package_file.Rd 42a633e8f171837a00fb37c6674a458b *man/packages.Rd c829857ce81cdf2818b4ba80d726166c *man/parse_deps.Rd aac9edd1d3ee4620104f5b164c860ec3 *man/parse_ns_file.Rd eca420f1788e6b04ec0d55ac349fa67f *man/pkg_env.Rd bda761669a83d101cd3f13884e7d77ae *man/pkgload-package.Rd d05d8f1c775815e9c2ad35ae8b4296ca *man/pkgtest.Rd cb508c1dace3c92f094e3359c86eb128 *man/run_pkg_hook.Rd 735c35e9c884b5d4df613bf886beef26 *man/system.file.Rd 219bc146ddd24636de039982b21fe554 *man/unload.Rd 4947f4dca4c99b1f8386b10bdb9a3080 *tests/empty/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/empty/NAMESPACE d41d8cd98f00b204e9800998ecf8427e *tests/empty/R/foo.R aeb5c0b6598ae3ce23b27208e6ceef19 *tests/testthat.R 62443d5aca06ce6386cc8cef96a0bc27 *tests/testthat/_snaps/depend.md 127a51b566a5a2557a673cbbcb5221ff *tests/testthat/_snaps/help.md f67e988186d3f7d6eab6c28b11020c84 *tests/testthat/_snaps/load-hooks.md c10340d9ed31dc4a45e72f623f2db756 *tests/testthat/_snaps/load.md a4db6c98dc5f031a8cc9ae5bce6a1ea1 *tests/testthat/_snaps/namespace.md 533ed49a49a795bb528f4a98869b51c7 *tests/testthat/_snaps/shim.md b00dc7d60a4d115e9981a53d10e8d947 *tests/testthat/_snaps/source.md 49bbe330b2db3b4dc51cc13c1b159369 *tests/testthat/helper-pkgload.R af016f4046099da698799964e6752591 *tests/testthat/test-data.R 58b20635c623a7ab9e3ec2584e07b9e2 *tests/testthat/test-depend.R a85767268aa03d548d58b0d26a186356 *tests/testthat/test-description.R 82c65fb020defb2c3a6441d569ef0a24 *tests/testthat/test-dll.R f2586ce34c024ca249c7c17bb3ac4cdb *tests/testthat/test-examples.R 68b8dab49b36ee11bf2f30de68827d80 *tests/testthat/test-examples.Rd 0c09f6fa25a934bc5f2979f72c6dbdc7 *tests/testthat/test-extraction.R 5f3d6eb6db51c4102ed61a7a2f287ff1 *tests/testthat/test-help.R ac412c1dad59cccc65c56086482b8cb9 *tests/testthat/test-imports.R 132005f7a0c52a1f74f0f3177b1384c6 *tests/testthat/test-load-collate.R f96c8bbdaab2c2935e2139a92034dffa *tests/testthat/test-load-hooks.R 0d25ada93a9cfe36146b856228f83c18 *tests/testthat/test-load.R 08bc307e219448b12c132fb256ad3318 *tests/testthat/test-metadata.R feaa92922478581bc74fd251988fd129 *tests/testthat/test-namespace-env.R 4f6fdcfd1fcc9a3fd920cf3cb2653e7f *tests/testthat/test-namespace.R b07b0f362363449e8d55be5f261cf627 *tests/testthat/test-package.R d903ff32269a01f8271070f1c8efc2b5 *tests/testthat/test-po.R df154e244bbb3d5b9fc2b668bb4d7efd *tests/testthat/test-s4-export.R 0d50cbb94b8411716ea3e1a1cab50746 *tests/testthat/test-s4-sort.R b393488b25f862302b68372af56a40e8 *tests/testthat/test-s4-unload.R 674160a819fcef8ee4aff765970031b6 *tests/testthat/test-shim.R 487b74962ef4b5686b3a50a021b02154 *tests/testthat/test-source.R 979afb1639765c44e170b164759ce085 *tests/testthat/testActiveBindings/DESCRIPTION 9c9114e191dfc8c4face36bca76c5648 *tests/testthat/testActiveBindings/NAMESPACE 5048230b109827ab3131153b97c2a78a *tests/testthat/testActiveBindings/R/bindings.r 190573569db1b89f8a95a78b7a88a7c2 *tests/testthat/testCollateAbsent/DESCRIPTION 870a24794b577e7883169d2d0fa5cbc8 *tests/testthat/testCollateAbsent/R/a.r 0bce505aa6c5dc80635131e13597ae39 *tests/testthat/testCollateAbsent/R/b.r 9428933359013ba999fe5a1b9990022e *tests/testthat/testCollateAbsent/R/c.r a9d0f4eebceb98d9fffa3c14c56af663 *tests/testthat/testCollateExtra/DESCRIPTION 870a24794b577e7883169d2d0fa5cbc8 *tests/testthat/testCollateExtra/R/a.r e08c7a7b525b3028e34c92e8e93b9829 *tests/testthat/testCollateMissing/DESCRIPTION 870a24794b577e7883169d2d0fa5cbc8 *tests/testthat/testCollateMissing/R/a.r d119cb97e3acb0ddacf52c658960de8c *tests/testthat/testCollateMissing/R/b.r d050ad69653ed61d8a36ac8be8ebb59e *tests/testthat/testCollateOrder/DESCRIPTION 012592abf4b40a8d741b299df2ded05a *tests/testthat/testCollateOrder/NAMESPACE c8f75318162ecbd0c54038d1ef899ccb *tests/testthat/testCollateOrder/R/a.r 5dc6a5b47f4272a583e1a76ce68ae884 *tests/testthat/testCollateOrder/R/b.r cec09efd7fb2195e51c58be69e08fc28 *tests/testthat/testData/DESCRIPTION f9ea5333e6efd9c51fc46fe34164c341 *tests/testthat/testData/NAMESPACE d2a5cf8248b95340f49aabf60c1dee3f *tests/testthat/testData/R/sysdata.rda e03377f1cb29a3f1861e89fdb0604ad8 *tests/testthat/testData/data/a.rda aa6661f9ad2794e7d2c6d8a36023e78b *tests/testthat/testData/data/b.r cb7beacf5fecc82dc47093f30438a556 *tests/testthat/testDataLazy/DESCRIPTION f9ea5333e6efd9c51fc46fe34164c341 *tests/testthat/testDataLazy/NAMESPACE d2a5cf8248b95340f49aabf60c1dee3f *tests/testthat/testDataLazy/R/sysdata.rda e03377f1cb29a3f1861e89fdb0604ad8 *tests/testthat/testDataLazy/data/a.rda aa6661f9ad2794e7d2c6d8a36023e78b *tests/testthat/testDataLazy/data/b.r 6b1bc8fb7f2e25d5a8348686ec0344e5 *tests/testthat/testDependMissing/DESCRIPTION 26813d0f7f8e272af05102662163c53b *tests/testthat/testDependMissing/R/a.r 0ad666081152c8e08f6f08a4a3726627 *tests/testthat/testDependsExists/DESCRIPTION dd195332a76b238203e61dc91f7cbe45 *tests/testthat/testDllLoad/DESCRIPTION 44de50ca195021dfec7b25689a9e8249 *tests/testthat/testDllLoad/NAMESPACE 1088899aa7d116bc6360163784e95ada *tests/testthat/testDllLoad/R/a.r 68c4f21a77f2f7cc331e49d03918a326 *tests/testthat/testDllLoad/src/null-test.c 7dad3921f220256ae4f0f1100767257b *tests/testthat/testDllRcpp/DESCRIPTION 029ade657ecf41cfeabeba27c10f35e7 *tests/testthat/testDllRcpp/NAMESPACE 6c1c2c0de9fc0036209d9ae52af0b4c7 *tests/testthat/testDllRcpp/R/RcppExports.R 0c8827bd3100199eada5cf76012f3686 *tests/testthat/testDllRcpp/src/RcppExports.cpp cdae79fe661bbb694dd79074547735b9 *tests/testthat/testDllRcpp/src/rcpp_hello_world.cpp 1ff255921b6b11864580451a5ed503b7 *tests/testthat/testHelp/DESCRIPTION ff09290426402d763c4542e5426dadd3 *tests/testthat/testHelp/NAMESPACE 66236785036c947fd7014e9a02cbf6f9 *tests/testthat/testHelp/R/foofoo.r d72f199234418eb348b7aa2a76d665e3 *tests/testthat/testHelp/man/foofoo.Rd d9194183e8c46d455622f166e4014b06 *tests/testthat/testHelp/man/macros/macros.Rd 7aaf1b4f012efc5b6ff64971488b2b87 *tests/testthat/testHelp/man/testCustomMacro.Rd efec94ac198b7dff257466964248bb43 *tests/testthat/testHelp/man/testHelp-package.Rd 36983a265f6825008e4ca9c2b621f36f *tests/testthat/testHelp/man/testHelp.Rd e04363946cb90d523291b3e468a710b5 *tests/testthat/testHelp/man/testSysMacro.Rd 7bc1ed66c8a6ecfad94558f22d04fa54 *tests/testthat/testHooks/DESCRIPTION 5f10eb4bf9f2ee689fc932f60cc4a002 *tests/testthat/testHooks/R/a.r 69025f60f7052c8cd2774f074165ca02 *tests/testthat/testImportMissing/DESCRIPTION 26813d0f7f8e272af05102662163c53b *tests/testthat/testImportMissing/R/a.r 8e3d98c1d4478afa1d57006019894aef *tests/testthat/testImportVersion/DESCRIPTION 85601cb90b291bb14a88bc9e7349b653 *tests/testthat/testImportVersion/NAMESPACE 26813d0f7f8e272af05102662163c53b *tests/testthat/testImportVersion/R/a.r aa6661f9ad2794e7d2c6d8a36023e78b *tests/testthat/testImportVersion/R/b.r 6118ba079e48a4aab9130fc0ba22b1ba *tests/testthat/testLibDynam/DESCRIPTION 003f019ff93c5b2b9ebd23bdbbcc6de8 *tests/testthat/testLibDynam/NAMESPACE 1ccab88b13ae7fe5ba05b27b7e85767d *tests/testthat/testLibDynam/R/a.r 24e482303f1ce4b035b5d23550158fca *tests/testthat/testLibDynam/R/zzz.R b927143e0c8f0366ec65ab2446b16a47 *tests/testthat/testLoadAttach/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testLoadAttach/NAMESPACE f5aa586562104703d2de8955d6b3b0e6 *tests/testthat/testLoadDir/DESCRIPTION 4ee0e944b871a30086d8ea8a9c227d4e *tests/testthat/testLoadDir/R/a.r e85d608e3478bd981ee081526b97e810 *tests/testthat/testLoadHelpers/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testLoadHelpers/NAMESPACE ab9a8cfc24169f2062b7d3592bf96296 *tests/testthat/testLoadHelpers/R/a.r 214b2dd63d0e3e4d584e273d663616e2 *tests/testthat/testLoadHelpers/data/mtcars2.rda 819590dc157ecfe7cd9f191a1a2dce95 *tests/testthat/testLoadHelpers/tests/testthat.R d0e4413748e1aba1380601aa3e92d6a0 *tests/testthat/testLoadHelpers/tests/testthat/helpers.R 225e3812b897786befc574f805c96dc2 *tests/testthat/testLoadHelpers/tests/testthat/test-foo.R ef5ca0c4a515d28c78e3f3bf187d2bad *tests/testthat/testLoadHooks/DESCRIPTION 2d0c4eeb448049308bea3d76e27e5757 *tests/testthat/testLoadHooks/R/a.r 8a7453c8c288935c62531bd9613c13d0 *tests/testthat/testLoadImportDownstream/DESCRIPTION 2eb25806865e52bf1a02f86590a340f9 *tests/testthat/testLoadImportDownstream/NAMESPACE 06fb52113ad712ce2b07bd41d587bb6c *tests/testthat/testLoadImportDownstream/R/downstream.R 29ef4bb01821f0094e83a8d721a44d0c *tests/testthat/testLoadImportUpstream/DESCRIPTION ac9a51df3508649fb084324d6824388d *tests/testthat/testLoadImportUpstream/NAMESPACE 0dfeeebcc8b603e507e61dd325bb838f *tests/testthat/testLoadImportUpstream/R/upstream.R 36ad9dede2dd9ec2877ed67b694c3e06 *tests/testthat/testLoadImportUpstreamAlt/DESCRIPTION 7df6f709257943ff102b179099e6ce53 *tests/testthat/testLoadImportUpstreamAlt/NAMESPACE a7da6d28660adc8e2f5276fe3036b096 *tests/testthat/testLoadImportUpstreamAlt/R/upstream-alt.R e980cc57e21a5e0e0ddf87705ce9f444 *tests/testthat/testLoadLazy/DESCRIPTION 9c9114e191dfc8c4face36bca76c5648 *tests/testthat/testLoadLazy/NAMESPACE c23239cba08bc8aae2be8627eff1c975 *tests/testthat/testLoadLazy/R/bindings.r 4d536ff3110ad209dbe1cd88214c34c2 *tests/testthat/testMacroDownstream/DESCRIPTION ab74803cf9dce225b0b13185f8f51fbc *tests/testthat/testMacroDownstream/NAMESPACE 2be67a2c211d976c4da2294493ef05f2 *tests/testthat/testMacroDownstream/R/macro.R 8059a03b981e809186f1a404a72ef3dc *tests/testthat/testMacroDownstream/man/macro_downstream.Rd 1494bf61f7e5b6e5a36a6df0faf2c486 *tests/testthat/testMissingNsObject/DESCRIPTION 9fb09fba835e687b843b78452bbeb820 *tests/testthat/testMissingNsObject/NAMESPACE 26813d0f7f8e272af05102662163c53b *tests/testthat/testMissingNsObject/R/a.r a6cc28f2792b0cf78aab540afe43e1f3 *tests/testthat/testNamespace/DESCRIPTION f4cc9c3507eb406de70a6a7c6ca63d8e *tests/testthat/testNamespace/NAMESPACE 26813d0f7f8e272af05102662163c53b *tests/testthat/testNamespace/R/a.r aa6661f9ad2794e7d2c6d8a36023e78b *tests/testthat/testNamespace/R/b.r 3a884f3538f6f69ce26b6f76f6e9f1c1 *tests/testthat/testS3removed/DESCRIPTION b4b8452ca5b830996ac4565d33e29634 *tests/testthat/testS3removed/NAMESPACE 5060a3834cef2931b473b1f2882fcaab *tests/testthat/testS3removed/R/S3.r 52aa7c4531c989b52272125dfb942409 *tests/testthat/testS3removed2/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testS3removed2/NAMESPACE d41d8cd98f00b204e9800998ecf8427e *tests/testthat/testS3removed2/R/S3.r a7e2f077bd7e448a798f153c7c153e94 *tests/testthat/testS4export/DESCRIPTION 2b3de241ad146080f3815429df0666b6 *tests/testthat/testS4export/NAMESPACE 9cdf6a778c52445fa46aae63fe4c7ac2 *tests/testthat/testS4export/R/all.r e4786dbff584b1b4d65b4460c02b0b87 *tests/testthat/testS4import/DESCRIPTION da89f1bf6b87610e418958974b95bb42 *tests/testthat/testS4import/NAMESPACE a0c94dee500c22e01d242a233d5f1039 *tests/testthat/testS4import/R/all.r 42b6d01401e9238fc97d18c2d33cd63b *tests/testthat/testS4sort/DESCRIPTION 77889dc631765bb10f12bdbdfa8542af *tests/testthat/testS4sort/NAMESPACE 43b55f669c6979ed4ed2f6080d9a63ae *tests/testthat/testS4sort/R/classes.r bfc904e6fb6910b903755139720af809 *tests/testthat/testS4union/DESCRIPTION 85f7ace341a0219ec4ae73022413b740 *tests/testthat/testS4union/NAMESPACE 4d30ff3208d42456afc2401585f97b1c *tests/testthat/testS4union/R/classes.r 583f3e7f7449571e9921cefb3ddc39cf *tests/testthat/testShim/A.txt 2aaa7783c966d1455430681fe9f46c7b *tests/testthat/testShim/C.txt d79dbc16cb00ebf4fc5783d3b830c278 *tests/testthat/testShim/DESCRIPTION 14451c613ae2c737269d0062f36eeb26 *tests/testthat/testShim/NAMESPACE 8960211fe22ff697115cc52c5f6616b6 *tests/testthat/testShim/R/a.r 119151c832b23525b2818019573bb463 *tests/testthat/testShim/inst/A.txt 490d1b2eb66ba6d4011ada175d264a41 *tests/testthat/testShim/inst/B.txt 26813d0f7f8e272af05102662163c53b *tests/testthat/testSource/a.R 9b46bb85fb907520ac5b666369873ec5 *tests/testthat/testSource/b.R 1b52fde955450cbefa30dc871752a575 *tests/testthat/testTranslations/DESCRIPTION cea30ae8568f3d1407abd1b23febfbe9 *tests/testthat/testTranslations/R/hello.r d8d02e415297e89aa5661c49dc29a2fe *tests/testthat/testTranslations/inst/po/fr/LC_MESSAGES/R-testTranslations.mo ece193fa5a3d121085507eca8095eb39 *tests/testthat/testTranslations/po/R-fr.po 7b49caa498cd8c376153517e4f3e1c0e *tests/testthat/testTranslations/po/R-testTranslations.pot 395a057924ccb9022a6cc9696eac0617 *tests/testthat/testUnknownMacro/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testUnknownMacro/NAMESPACE 6eccdb680a3f3bbb221ea56f4e8c95cf *tests/testthat/testUnknownMacro/R/testUnknownMacro.R ae1d0e226284d4e2f89ce14584c4b2f4 *tests/testthat/testUnknownMacro/man/macros/macros.Rd a15c83327c5fbcc88b6340fdff03027e *tests/testthat/testUnknownMacro/man/testUnknownMacro.Rd d4e9a09ebd8570a934674caa74b4104f *tests/testthat/testUserLoadHook/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testUserLoadHook/NAMESPACE 40d93eb03206f263f6ff1eeff73e1880 *tests/testthat/testUserLoadHook/R/testUserLoadHook.R aee99c1b0aa729ceddfa6824992ca506 *tests/testthat/testUserLoadHookError/DESCRIPTION dc21c19f0d6968ee25d441b2cf46017d *tests/testthat/testUserLoadHookError/NAMESPACE 153ebb39cd7605a89d4e57cd9a7edd9b *tests/testthat/testUserLoadHookError/R/testUserLoadHookError.R c6f07192d8f2b0d6837c957e430ebc27 *tests/testthat/testUserLoadHookUpstream/DESCRIPTION d1d7e0c2d6c37b2a6e8dc2fd5b9549eb *tests/testthat/testUserLoadHookUpstream/NAMESPACE b25da2702d8a0d840e71d618e3c80817 *tests/testthat/testUserLoadHookUpstream/R/testUserLoadHookUpstream.R 244af9178552fc9224acf33786ac1428 *tests/testthat/testVersionSep/DESCRIPTION 3e303973e12ee0845ee159f0f5f479b9 *tests/wipe.R pkgload/inst/0000755000176200001440000000000014247353057012662 5ustar liggesuserspkgload/inst/WORDLIST0000644000176200001440000000003514247353057014052 0ustar liggesusersdevtools dir dirs recompiles