sessioninfo/0000755000176200001440000000000014153374352012620 5ustar liggesuserssessioninfo/NAMESPACE0000644000176200001440000000145314153370556014044 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.character,external_info) S3method(as.character,packages_info) S3method(as.character,platform_info) S3method(as.character,python_info) S3method(as.character,session_info) S3method(c,platform_info) S3method(format,external_info) S3method(format,packages_info) S3method(format,platform_info) S3method(format,python_info) S3method(format,session_diff) S3method(format,session_info) S3method(print,external_info) S3method(print,packages_info) S3method(print,platform_info) S3method(print,python_info) S3method(print,session_diff) S3method(print,session_info) export(external_info) export(os_name) export(package_info) export(platform_info) export(python_info) export(session_diff) export(session_info) importFrom(cli,symbol) importFrom(utils,packageVersion) sessioninfo/tools/0000755000176200001440000000000014152377737013771 5ustar liggesuserssessioninfo/tools/bad-emoji.R0000644000176200001440000000404714152377737015750 0ustar liggesusers# emoji 0.2.0 bad <- c( 11, 24, 33, 34, 37, 43:45, 50, 67, 71, 76, 86, 101, 144:147, 155, 157, 170, 209:232, 239:250, 264:269, 325:330, 379:384, 403:422, 454:455, 474:479, 487:488, 496, 545:568, 605:610, 617:622, 629:634, 641:670, 695:718, 725:748, 755:778, 785:808, 815:838, 845:898, 905:928, 935:958, 965:1000, 1025:1030, 1043:1048, 1061:1072, seq(1074, 1096, by = 2), 1097:1102, 1115:1120, 1133:1138, 1151:1156, 1169:1174, 1187:1192, 1205:1210, 1223:1228, 1241:1246, 1259:1270, seq(1272, 1294, by = 2), 1295:1300, 1313:1318, 1337, 1360, 1368:1395, 1402:1431, 1438:1467, 1486:1509, 1528:1551, 1558:1581, 1588:1599, 1606:1623, 1642:1647, 1654:1677, 1684:1707, 1714:1737, 1744:1767, 1774:1797, 1804:1827, 1834:1857, 1859:1862, 1864:1868, 1875:1898, 1905:1928, 1935:2072, 2079:2102, 2123:2126, 2133:2156, 2163:2186, 2209:2236, 2243:2521, 2528:2551, 2558:2581, 2588:2611, 2624:2649, 2652:2656, 2658:2662, 2664:2668, 2670:2674, 2678:2682, 2684:2688, 2690:2684, 2696:2700, 2704:2708, 2710:2714, 2716:2720, 2722:2726, 2729:2773, 2775:2825, 2827:2877, 2879:2929, 2931:2975, 2977:3027, 3029:3079, 3081:3131, 3162, 3176, 3179, 3180, 3187, 3197, 3214, 3225, 3229, 3230, 3233:3235, 3253:3255, 3270, 3277, 3283, 3286, 3293, 3294, 3299, 3309, 3322, 3323, 3338, 3341, 3350, 3354, 3355, 3358, 3363, 3367, 3380, 3382, 3387, 3391, 3415, 3433, 3444, 3446:3449, 3456, 3489, 3490, 3516, 3535, 3565, 3574:3576, 3580, 3589, 3596, 3613, 3678, 3778, 3784, 3785, 3788, 3790, 3798:3800, 3819:3821, 3827, 3837:3840, 3849, 3856, 3863, 3892, 3897, 3899, 3908, 3944, 3965, 4041, 4053, 4057, 4059, 4067, 4071, 4074, 4087:4089, 4092, 4093, 4098, 4100, 4103, 4104, 4110, 4112, 4113, 4120, 4124, 4125, 4399, 4436:4441 ) sessioninfo/README.md0000644000176200001440000002234414153370223014075 0ustar liggesusers # sessioninfo > R Session Information [![Lifecycle: stable](https://lifecycle.r-lib.org/articles/figures/lifecycle-stable.svg)](https://lifecycle.r-lib.org/articles/stages.html) [![R build status](https://github.com/r-lib/sessioninfo/workflows/R-CMD-check/badge.svg)](https://github.com/r-lib/sessioninfo/actions) [![](https://www.r-pkg.org/badges/version/sessioninfo)](https://www.r-pkg.org/pkg/sessioninfo) [![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/sessioninfo)](https://www.r-pkg.org/pkg/sessioninfo) [![Coverage Status](https://img.shields.io/codecov/c/github/r-lib/sessioninfo/master.svg)](https://codecov.io/github/r-lib/sessioninfo?branch=master) Query and print information about the current R session. It is similar to `utils::sessionInfo()`, but includes more information about packages, and where they were installed from. ## Differences from `utils::sessionInfo()` * Additional platform details: time zone, pandoc version, RStudio version, etc. * Information about package sources, e.g. GitHub repo and hash for packages installed from GitHub. * Highlight package installation problems, e.g. if the loaded and on-disk versions are different, if the MD5 checksum of the package DLL is wrong, etc. * Highlight packages from unusual sources. * Information about external software via `external_info()`. * Information about the Python configuration is the reticulate package is loaded and configured. * Information about package libraries. * Compare two session info outputs with the `session_diff()` function. * Option to show loaded (default), attached or installed packages, or the recursive dependencies of the specified packages. ## Installation ```r install.packages("sessioninfo") ``` ## Usage Example output: ```r sessioninfo::session_info() ``` ### Copying to the clipboard You can use the [`clipr` package](https://cran.r-project.org/package=clipr) to copy the session info to the clipboard: ```r clipr::write_clip(session_info()) ``` (The current `clipr` version prints a warning, but you can ignore that.) ### Writing to a file You can use the `to_file` argument of `session_info()`: ```r session_info(to_file = "session.log") ``` ### External software ```r sessioninfo::session_info(info = "external") ``` ``` ═ Session info ═══════════════════════════════════════════════════════════════ ─ External software ────────────────────────────────────────────────────────── setting value cairo 1.14.12 cairoFT 2.10.0/2.13.1 pango png 1.6.37 jpeg 9.4 tiff LIBTIFF, Version 4.1.0 tcl 8.6.6 curl 7.54.0 zlib 1.2.11 bzlib 1.0.6, 6-Sept-2010 xz 5.2.4 PCRE 10.34 2019-11-21 ICU 62.1 TRE TRE 0.8.0 R_fixes (BSD) iconv GNU libiconv 1.11 readline 5.2 BLAS /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.0.dylib lapack /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib lapack_version 3.9.0 ────────────────────────────────────────────────────────────────────────────── ``` ### Python configuration ```r sessioninfo::session_info(info = "python") ``` ``` ═ Session info ═══════════════════════════════════════════════════════════════ ─ Python configuration ─────────────────────────────────────────────────────── python: /Users/gaborcsardi/Library/r-miniconda/envs/r-reticulate/bin/python libpython: /Users/gaborcsardi/Library/r-miniconda/envs/r-reticulate/lib/libpython3.6m.dylib pythonhome: /Users/gaborcsardi/Library/r-miniconda/envs/r-reticulate:/Users/gaborcsardi/Library/r-miniconda/envs/r-reticulate version: 3.6.13 | packaged by conda-forge | (default, Sep 23 2021, 07:55:15) [GCC Clang 11.1.0] numpy: /Users/gaborcsardi/Library/r-miniconda/envs/r-reticulate/lib/python3.6/site-packages/numpy numpy_version: 1.19.5 ────────────────────────────────────────────────────────────────────────────── ``` ### Comparing session information `session_diff()` can retrieve the session info from an URL or the clipboard and compare it to the current session information: ```r sessioninfo::session_diff(new = "https://github.com/r-lib/sessioninfo/issues/6") ``` ```diff --- local +++ https://github.com/r-lib/sessioninfo/issues/6 Session info ────────────────────────────────────────────────────────────────── setting value version R version 4.1.1 (2021-08-10) os macOS Mojave 10.14.6 system x86_64, darwin17.0 ui X11 language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz Europe/Madrid pandoc 2.7.3 @ /usr/local/bin/pandoc ─ Packages ───────────────────────────────────────────────────────────────────── package * version date (UTC) lib source - asciicast 1.0.0.9000 2021-10-10 [1] local - cli 3.0.1.9000 2021-10-13 [1] local + cachem 1.0.6 2021-08-19 [1] CRAN (R 4.1.0) + callr 3.7.0.9000 2021-10-01 [1] Github (r-lib/callr@ea5c3df) + cli 3.0.1.9000 2021-10-07 [1] Github (r-lib/cli@e9758aa) + clipr 0.7.1 2020-10-08 [1] CRAN (R 4.1.0) + commonmark 1.7 2018-12-01 [1] CRAN (R 4.1.0) crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) - curl 4.3.2 2021-06-23 [1] CRAN (R 4.1.0) desc 1.4.0.9000 2021-10-04 [1] local + devtools 2.4.2 2021-06-07 [1] CRAN (R 4.1.0) + digest 0.6.28 2021-09-23 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) + fastmap 1.1.0 2021-01-25 [1] CRAN (R 4.1.0) + fs 1.5.0 2020-07-31 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local - jsonlite 1.7.2 2020-12-09 [1] CRAN (R 4.1.0) + knitr 1.34 2021-09-09 [1] CRAN (R 4.1.0) lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) + memoise 2.0.0 2021-01-26 [1] CRAN (R 4.1.0) pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) + pkgbuild 1.2.0 2020-12-15 [1] CRAN (R 4.1.0) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) + prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.1.0) processx 3.5.2.9000 2021-09-15 [1] local prompt 1.0.0 2021-03-02 [1] local ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) + purrr 0.3.4 2020-04-17 [1] CRAN (R 4.1.0) R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) - Rcpp 1.0.7 2021-07-07 [1] CRAN (R 4.1.0) - rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) + remotes 2.4.0 2021-06-02 [1] CRAN (R 4.1.0) + rlang 0.99.0.9000 2021-10-07 [1] Github (r-lib/rlang@3ba19df) + roxygen2 7.1.2 2021-10-04 [1] local rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) - sessioninfo * 1.1.1.9000 2021-10-13 [?] load_all() - testthat * 3.1.0 2021-10-04 [1] CRAN (R 4.1.0) - tibble 3.1.5 2021-09-30 [1] CRAN (R 4.1.0) + rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) + sessioninfo * 1.1.1.9000 2021-10-05 [?] load_all() + stringi 1.7.4 2021-08-25 [1] CRAN (R 4.1.0) + stringr 1.4.0 2019-02-10 [1] CRAN (R 4.1.0) + testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) + tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) + usethis 2.0.1 2021-02-10 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) - uuid 0.1-4 2020-02-26 [1] CRAN (R 4.1.0) - V8 3.4.2 2021-05-01 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) + xfun 0.26 2021-09-14 [1] CRAN (R 4.1.0) + xml2 1.3.2 2020-04-23 [1] CRAN (R 4.1.0) [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library ``` ## License GPL-2 sessioninfo/man/0000755000176200001440000000000014152377737013404 5ustar liggesuserssessioninfo/man/external_info.Rd0000644000176200001440000000336514152377737016537 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/external-info.R \name{external_info} \alias{external_info} \title{Information about related software} \usage{ external_info() } \value{ A list with elements: \itemize{ \item \code{cairo}: The cairo version string. \item \code{libpng}: The png version string. \item \code{jpeg}: The jpeg version string. \item \code{tiff}: The tiff library and version string used. \item \code{tcl}: The tcl version string. \item \code{curl}: The curl version string. \item \code{zlib}: The zlib version string. \item \code{bzlib}: The zlib version string. \item \code{xz}: The zlib version string. \item \code{PCRE}: The Perl Compatible Regular Expressions (PCRE) version string. \item \code{ICU}: The International Components for Unicode (ICU) version string. \item \code{TRE}: The TRE version string. \item \code{iconv}: The iconv version string. \item \code{readline}: The readline version string. \item \code{BLAS}: The path with the implementation of BLAS in use. \item \code{LAPACK}: The path with the implementation of LAPACK in use. } } \description{ Information about related software } \details{ Note that calling this function will attempt to load the tcltk and grDevices packages. } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} external_info() \dontshow{\}) # examplesIf} } \seealso{ Similar functions and objects in the base packages: \code{\link[utils:sessionInfo]{utils::sessionInfo()}}, \link[base:extSoftVersion]{base::extSoftVersion}, \code{\link[tcltk:TclInterface]{tcltk::tclVersion()}} \link[base:La_library]{base::La_library}, \code{\link[base:La_version]{base::La_version()}}, \code{\link[base:libcurlVersion]{base::libcurlVersion()}}. } sessioninfo/man/package_info.Rd0000644000176200001440000000515514152377737016307 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package-info.R \name{package_info} \alias{package_info} \title{Information about the currently loaded packages, or about a chosen set} \usage{ package_info( pkgs = c("loaded", "attached", "installed")[1], include_base = FALSE, dependencies = NA ) } \arguments{ \item{pkgs}{Which packages to show. It may be: \itemize{ \item \code{NULL} or \code{"loaded"}: show all loaded packages, \item \code{"attached"}: show all attached packages, \item \code{"installed"}: show all installed packages, \item a character vector of package names. Their (hard) dependencies are also shown by default, see the \code{dependencies} argument. }} \item{include_base}{Include base packages in summary? By default this is false since base packages should always match the R version.} \item{dependencies}{Whether to include the (recursive) dependencies as well. See the \code{dependencies} argument of \code{\link[utils:install.packages]{utils::install.packages()}}.} } \value{ A data frame with columns: \itemize{ \item \code{package}: package name. \item \code{ondiskversion}: package version (on the disk, which is sometimes not the same as the loaded version). \item \code{loadedversion}: package version. This is the version of the loaded namespace if \code{pkgs} is \code{NULL}, and it is the version of the package on disk otherwise. The two of them are almost always the same, though. \item \code{path}: path to the package on disk. \item \code{loadedpath}: the path the package was originally loaded from. \item \code{attached}: logical, whether the package is attached to the search path. \item \code{is_base}: logical, whether the package is a base package. \item \code{date}: the date the package was installed or built, in UTC. \item \code{source}: where the package was installed from. E.g. \code{CRAN}, \code{GitHub}, \code{local} (from the local machine), etc. \item \code{md5ok}: Whether MD5 hashes for package DLL files match, on Windows. \code{NA} on other platforms. \item \code{library}: factor, which package library the package was loaded from. For loaded packages, this is (the factor representation of) \code{loadedpath}, for others \code{path}. } See \code{\link[=session_info]{session_info()}} for the description of the \emph{printed} columns by \code{package_info} (as opposed to the \emph{returned} columns). } \description{ Information about the currently loaded packages, or about a chosen set } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} package_info() package_info("sessioninfo") \dontshow{\}) # examplesIf} } sessioninfo/man/session_diff.Rd0000644000176200001440000000242014152377737016344 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/compare.R \name{session_diff} \alias{session_diff} \title{Compare session information from two sources} \usage{ session_diff(old = "local", new = "clipboard", ...) } \arguments{ \item{old, new}{A \code{session_info} object (the return value of \code{\link[=session_info]{session_info()}}), or a pointer to \code{\link[=session_info]{session_info()}} output. See details below.} \item{...}{Passed to any new \code{\link[=session_info]{session_info()}} calls.} } \description{ Compare session information from two sources } \details{ Various way to specify \code{old} and \code{new}: \itemize{ \item A \code{session_info} object. \item \code{"local"} runs \code{\link[=session_info]{session_info()}} in the current session, and uses its output. \item \code{"clipboard"} takes the session info from the system clipboard. If the clipboard contains a URL, it is followed to download the session info. \item A URL starting with \verb{http://} or \verb{https://}. \code{session_diff} searches the HTML (or text) page for the session info header to find the session info. } } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} session_diff() \dontshow{\}) # examplesIf} } sessioninfo/man/os_name.Rd0000644000176200001440000000106014152377737015311 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/osname.R \name{os_name} \alias{os_name} \title{Human readable name of the current operating system} \usage{ os_name() } \value{ A character scalar. } \description{ For example Windows 8.1 instead of Windows version 6.3.9600. On macOS it includes the code names, on Linux it includes the distribution names and codenames if appropriate. } \details{ It uses \code{\link[utils:sessionInfo]{utils::sessionInfo()}}, but simplifies its output a bit on Windows, to make it more concise. } sessioninfo/man/platform_info.Rd0000644000176200001440000000310114152377737016525 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/platform-info.R \name{platform_info} \alias{platform_info} \title{Information about the current platform} \usage{ platform_info() } \value{ A list with elements: \itemize{ \item \code{version}: the R version string. \item \code{os}: the OS name in human readable format, see \code{\link[=os_name]{os_name()}}. \item \code{system}: CPU, and machine readable OS name, separated by a comma. \item \code{ui}: the user interface, e.g. \code{Rgui}, \code{RTerm}, etc. see \code{GUI} in \link[base:Platform]{base::.Platform}. \item \code{language}: The current language setting. The \code{LANGUAGE} environment variable, if set, or \code{(EN)} if unset. \item \code{collate}: Collation rule, from the current locale. \item \code{ctype}: Native character encoding, from the current locale. \item \code{tz}: The current time zone. \item \code{date}: The current date. \item \code{rstudio}: RStudio format string, only added in RStudio. \item \code{pandoc}: pandoc version and path } } \description{ Information about the current platform } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} platform_info() \dontshow{\}) # examplesIf} } \seealso{ Similar functions and objects in the base packages: \link[base:Version]{base::R.version.string}, \code{\link[utils:sessionInfo]{utils::sessionInfo()}}, \link[base:Version]{base::version}, \link[base:Platform]{base::.Platform}, \code{\link[base:locales]{base::Sys.getlocale()}}, \code{\link[base:timezones]{base::Sys.timezone()}}. } sessioninfo/man/figures/0000755000176200001440000000000014153367720015040 5ustar liggesuserssessioninfo/man/figures/session-info2.svg0000644000176200001440000004571114153367711020267 0ustar liggesusers > library(usethis) > sessioninfo::session_info() Session info ────────────────────────────────────────────────────────────── setting value version R version 4.1.1 (2021-08-10) os macOS Mojave 10.14.6 system x86_64, darwin17.0 ui X11 language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz Europe/Madrid date 2021-10-13 pandoc 2.7.3 @ /usr/local/bin/pandoc Packages ─────────────────────────────────────────────────────────────────── package * version date (UTC) lib source cli 3.0.1.9000 2021-10-12 [1] Github (r-lib/cli@340100c) fs 1.5.0 2020-07-31 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) purrr 0.3.4 2020-04-17 [1] CRAN (R 4.1.0) rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) sessioninfo 1.1.1.9000 2021-10-13 [1] local usethis * 2.0.1 2021-02-10 [1] CRAN (R 4.1.0) [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library ────────────────────────────────────────────────────────────────────────────── > sessioninfo/man/session_info.Rd0000644000176200001440000000662414152377737016401 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/session-info.R \name{session_info} \alias{session_info} \title{Print session information} \usage{ session_info( pkgs = c("loaded", "attached", "installed")[1], include_base = FALSE, info = c("auto", "all", "platform", "packages", "python", "external"), dependencies = NA, to_file = FALSE ) } \arguments{ \item{pkgs}{Which packages to show. It may be: \itemize{ \item \code{NULL} or \code{"loaded"}: show all loaded packages, \item \code{"attached"}: show all attached packages, \item \code{"installed"}: show all installed packages, \item a character vector of package names. Their (hard) dependencies are also shown by default, see the \code{dependencies} argument. }} \item{include_base}{Include base packages in summary? By default this is false since base packages should always match the R version.} \item{info}{What information to show, it can be \code{"auto"} to choose automatically, \code{"all"} to show everything, or a character vector with elements from: \itemize{ \item \code{"platform"}: show platform information via \code{\link[=platform_info]{platform_info()}}, \item \code{"packages"}: show package information via \code{\link[=package_info]{package_info()}}, \item \code{"python"}: show Python configuration via \code{\link[=python_info]{python_info()}}, \item \code{"external"}: show information about external software, via \code{\link[=external_info]{external_info()}}. }} \item{dependencies}{Whether to include the (recursive) dependencies as well. See the \code{dependencies} argument of \code{\link[utils:install.packages]{utils::install.packages()}}.} \item{to_file}{Whether to print the session information to a file. If \code{TRUE} the name of the file will be \code{session-info.txt}, but \code{to_file} may also be a string to specify the file name.} } \value{ A \code{session_info} object. If \code{to_file} is not \code{FALSE} then it is returned invisibly. (To print it to both a file and to the screen, use \code{(session_info(to_file = TRUE))}.) } \description{ This is \code{\link[utils:sessionInfo]{utils::sessionInfo()}} re-written from scratch to both exclude data that's rarely useful (e.g., the full collate string or base packages loaded) and include stuff you'd like to know (e.g., where a package was installed from). } \details{ Columns in the \emph{printed} package list: \itemize{ \item \code{package}: package name \item \code{*}: whether the package is attached to the search path \item \code{version}: package version. If the version is marked with \verb{(!)} that means that the loaded and the on-disk version of the package are different. \item \code{date}: when the package was built, if this information is available. This is the \code{Date/Publication} or the \code{Built} field from \code{DESCRIPTION}. (These are usually added automatically by R.) Sometimes this data is not available, then it is \code{NA}. \item \code{source}: where the package was built or installed from, if available. Examples: \verb{CRAN (R 3.3.2)}, \verb{Github (r-lib/pkgbuild@8aab60b)}, \code{Bioconductor}, \code{local}. } See \code{\link[=package_info]{package_info()}} for the list of columns in the data frame that is \emph{returned} (as opposed to \emph{printed}). } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} session_info() session_info("sessioninfo") \dontshow{\}) # examplesIf} } sessioninfo/man/python_info.Rd0000644000176200001440000000133114152377737016225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/python-info.R \name{python_info} \alias{python_info} \title{Python configuration} \usage{ python_info() } \value{ Returns a \link[reticulate:py_config]{reticulate::py_config} object, which also has the \code{python_info} class. It is a named list of values. If reticulate is not installed or Python is not configured, then it return a \code{python_info} object that is a character vector, and it does not have a \code{py_config} class. } \description{ Python configuration } \examples{ \dontshow{if (FALSE) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} python_info() session_info(info = "all") \dontshow{\}) # examplesIf} } sessioninfo/DESCRIPTION0000644000176200001440000000324714153374352014334 0ustar liggesusersPackage: sessioninfo Title: R Session Information Version: 1.2.2 Authors@R: c(person(given = "Gábor", family = "Csárdi", role = "cre", email = "csardi.gabor@gmail.com"), person(given = "Hadley", family = "Wickham", role = "aut"), person(given = "Winston", family = "Chang", role = "aut"), person(given = "Robert", family = "Flight", role = "aut"), person(given = "Kirill", family = "Müller", role = "aut"), person(given = "Jim", family = "Hester", role = "aut"), person(given = "R Core team", role = "ctb")) Maintainer: Gábor Csárdi Description: Query and print information about the current R session. It is similar to 'utils::sessionInfo()', but includes more information about packages, and where they were installed from. License: GPL-2 URL: https://github.com/r-lib/sessioninfo#readme, https://r-lib.github.io/sessioninfo/ BugReports: https://github.com/r-lib/sessioninfo/issues Depends: R (>= 2.10) Imports: cli (>= 3.1.0), tools, utils Suggests: callr, covr, mockery, reticulate, rmarkdown, testthat, withr Encoding: UTF-8 RoxygenNote: 7.1.2.9000 Config/testthat/edition: 3 Config/Needs/website: pkgdown Config/testthat/parallel: true NeedsCompilation: no Packaged: 2021-12-06 11:31:46 UTC; gaborcsardi Author: Gábor Csárdi [cre], Hadley Wickham [aut], Winston Chang [aut], Robert Flight [aut], Kirill Müller [aut], Jim Hester [aut], R Core team [ctb] Repository: CRAN Date/Publication: 2021-12-06 11:50:02 UTC sessioninfo/tests/0000755000176200001440000000000014152377737013773 5ustar liggesuserssessioninfo/tests/testthat/0000755000176200001440000000000014153374352015622 5ustar liggesuserssessioninfo/tests/testthat/test-os-name.R0000644000176200001440000000022114152377737020265 0ustar liggesusers test_that("unknown os name", { mockery::stub(os_name, "utils::sessionInfo", list(running = NULL)) expect_equal(os_name(), NA_character_) }) sessioninfo/tests/testthat/fixtures/0000755000176200001440000000000014152770761017476 5ustar liggesuserssessioninfo/tests/testthat/fixtures/devtools-info-unix.rda0000644000176200001440000000216314152770761023741 0ustar liggesusersX[oDΦ-UJZE<ؙoT+[57'8vZl^ޠwC2+)-JQ>[K%Z!i[&ûf4 \pp#jEe΁ݠL#Ȇkpۂa&@f}`eyP\ӻUH{tm[/AXfֆ|4Le`3QB=B$H@Ș{(!bȇLN2؏y~s9SA)e݉R^=_{Ǡ\5V}FP%:X0%aG?et.T6e܍McE>®7Ze9MF<{2*BKMbJxwtbDj!te݄aKZLn j - ʧ7n?~ Z64A΅f>ԝ[~\'Oc'I2t^Oսsessioninfo/tests/testthat/fixtures/installed.rda0000644000176200001440000002222014152377737022151 0ustar liggesusers=MsGvZ ,iek . III)Q,%=Cphf@lKJ[$^6.LO~?o .\py…VXC<Ȋ/ԝ;L< =_%]9 7/ ~thc~|Z?j̊#7%4/#\>AqxC?--@ZOpdk72+rKDQv^dPsKúe[Τ3}O>000000000000000000000a7󳓛2?0܇ͯa2ov\oFy+V[2oeʼy+gnjn47l;j~VR6{} %z۽Ez\v6Mx 7lll6oaXZz[c ol~n~;ilb$$]o9hnl5ߦnP7okҴ/;m-$2ow4]B- \CH2wh-B*ʪ&Mʪu LoUJl{?{l֐{,g7dtц.65(-`7,T|ތaGk ӔKh*o"uZh9+MO+5XP[FkA} ǂrHPR5kk eZ|Jƅv{C}q,XXx]5d#y<MA,.@JT[ $M4|g37[ ˁь~w@MK6[NAž5<0ZU;NZCYU%j=J?H[O:h8cK~qZ8kri2Q"fRtGfY eR@TchV>_hqg(y)HZ"1?6aWV#˱N)K#e|)Lbm`'(fu2ɲ[ղN'8&<|%d=;l ' N풵>];(1ȸ5:VMGxI-eǩq<&NN1sf?r?%U"в=Tnu: L?"MJX#aF&&X'o#)wWT6{[%,zUgUDtA5rS1y2bFRy&G<  !jVGk  0 8 2Vh`Z$c/#28-%y&ɼܟpe.j Ɉoa*&3356;F6pq^5x*4F*! k gyyLQk5s(Ճ'RG㩴{Gcb_ෂ{"WPJy2',lar|dԼ`SI11 n6Iϥ@iCRJ\"Sv[j'eGo٭ 9 YWF*wO%ObKkA2dA0(WEjf`TB7K$jB jiSJ빔 BfN##DI!ݜ˭ۊ˔,zgwe+bW \'Jp)IbV-lI(XGf~w163CV /R`™y3TDŽk2OȟxGYIZ]i@WӪ%Gt`QQ( YđZdcC)*mTaHwz̪E3l4-Ħ Hs˦HgQšy]XH61Cj+Aԭ;smLm\,ҭ1ʫ4T{rG ZL2Im (~ċyaP4V;x#.^كL@NȍʱI KZp%VMufo[6gJ/'?uVD k.kXU!DV;; "2kQ 5BY55PAbeĸ^ 2 YJ'cJijZ%2 -1:YS@-Z#LfyC;Fك!Cm$=|G)>QᇒO~Ϸ ]dasi Khs1_w?/bp4/uyl3G0z]翮2[ 0"铙"]d4ZE )KuG6?rF"!T4ĉfGÈDCOL) d2f`5|FLJG)j?BE.fPHǎ?1Z%ͧNɥI䥵khud?؍>JvH3Je0@FKV514Z r XDye. o( hd G: @EH5~聩QH&82|Lj*Lwus1`tjgdӽ5}V1R80ѽi;k0jdOF`r5$ݖڨ=j#Pi!Eտ3C"aTQ0 1hO|,—y k +2*'Af|NX*߻Z1Tu ό;ĄJ]fpSϖ؊ȍȷqymk&즎޲C'w"ri#@%Xa*$0Dn#u#rAf/qI!ԬL\E=ae S8IxRA ȵbA#'(З{)'ʩ &g\~4Qt* BRXn:tҘ&Aa(Wj è@r!msYfݶܬ%8X#@g谟ߛA: ?q$Aɴ_Ҹ^ j'NZ 5aO>^XKٗ|,YU=u%]VsP7wJ[8D.:);I <d}_nX(#4n89 A ,~NEP:ݞg|"ϙm=DygpΒ~[Y*sEuF'U :L꽦JⲂu%82mےxKwNÒg z7yR|̦!' ^Xp@ kzp1/W/Y;i0 $QSX#))=&;z !ßMp499 Cr}@kI,ro7;KXg &@lrL}ژ>ݘ5Xo#4yK011ݘr5nn0nxJ~dFEnV .:+C%?VlFF:E,>KE^{mxUU2r3jf~Cg}dЩ<8>,Iٖ6Nnﲘ]fJvtc^f.QnwԊJpP?ʔ,,O 7I+4wýIBE}_zs|:ڂhb+k8j?Wa+iSBV"8*gJp^[Si؆P1GD%]y_=Z&$\;4+WjY+fIݦ{ )ZƔի r;hTx4)]bn<=l5KZU2b,44%kC4fGP Kr/ɪ&DaTի'-N[ Wc!KfލRD7!*q%'O<=\Ђղ)#.5]cźb~_XGh=$;flhQ ^lTU/*7 KjܢP[) } ";<0',)ڷI2dn}*uqو([:[3fɓ{qEDŽ01&#9-?f|2՗O6Zʏst/B+u~_OI?D dҞ{C {cs/7?ӽϟ=sDk_"'x]Q )p]ª̝$ů ^~PLYZO/=.u5!S| !'Lef L6aoMj1$ y¬O .3+_otf٘UԈڒ le.߫_u~˞̗u~_u~_UYu~_u~_UƾI闘;W'eR4v!r@vzTv:S&`!GIBPO!l?1Fq\=~ΎL 'o_z<}\.L@FHqO^ @ r}?O u+)sC<&2B.f9H~=ɬSlwi eBS$X,趠A`6BIQ$Bw,dQx_NN^V_ap^3Ou8F(cVj7Wg^Vu^`#yVE;)`-sTˢd,=i 5yTA44EiXg8fSA(4p"0B%(u֡O8k |64gv>4Y-Cp$Tб8LG3Y SmA(q]~,m8)2.P/ ,dn1b]"bgg524԰2aNJ͊-XHbT$(;"2<2o/硧<yfz05(3I a895njAϲ0a^H$<Y``FWφ,RI]Pūuȥp3"z,z$EM|r+G4=! </ &$sessioninfo/tests/testthat/fixtures/fsdfgwetdhsdfhq4yqh_0.0.0.9000.tar.gz0000644000176200001440000000102514152377737025714 0ustar liggesusersT]o0ٿ⊽$RB!!e(IJiɅJlj;MدinRUA9/TH֨<~ƗË|j\u}]# ]k^| \RJ3 )*cSN3ÌF43[J5a+@s0a[P`H6W ׁ_2XTHutho$9}̤vX%ˊ9)h5l2ؑDJKʲEٵ>pCyN$vPE庚 j_$M$ӦC&,BɞހiX)Td#3e~'QMCrdX,OrA!t\oNBg~_ skdaP:Wƃne\_+>3)ǶMg`8~[=[|4C5pWhmyǜ%^(גi2fCp gTka^^_;7&fV5j'f sessioninfo/tests/testthat/fixtures/biobase.rda0000644000176200001440000000142214152377737021577 0ustar liggesusersmUmo0 XAh?p6m2(c]I톺䖚vd;l_?!.mfJI|s{Z[Ѳ^ųmx[}|՘t܅zu&#˕4p4.R2"{;6F>|AiNl}qրC< p{ @D10Ԑ%hNx;ѤOc*X0ZZi--{AF$Jd#C{;{AMc5o;~HrRONT{EP0d\ZzP?M㊭Ow=iˍQ3t{?c5IBk%T*~DkzO2FR\6yB8i&Y:p !_6K ]q)E&*wwT!<<{ưYGŦ'bǚMBsۣTɏ"N ^sZ !m aPZ +c?қĴ-k}=`sessioninfo/tests/testthat/fixtures/lines1.txt0000644000176200001440000000505014152377737021440 0ustar liggesusers- Session info ------------------------------------------ hash: squid, supervillain: medium skin tone, ewe setting value version R version 4.1.1 (2021-08-10) os macOS Mojave 10.14.6 system x86_64, darwin17.0 ui X11 language (EN) collate C ctype en_US.UTF-8 tz Europe/Madrid date 2021-10-12 pandoc 2.7.3 @ /usr/local/bin/pandoc - Packages ----------------------------------------------- ! package * version date (UTC) lib source cli 3.0.1.9000 2021-10-11 [1] local covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) desc 1.4.0.9000 2021-10-04 [1] local diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) mockery 0.4.2 2019-09-03 [1] CRAN (R 4.1.0) pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) prompt 1.0.0 2021-03-02 [1] local ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0) rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) P sessioninfo * 1.1.1.9000 2021-10-12 [?] local testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) testthatlabs 0.0.0.9000 2021-09-15 [1] local tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library P -- Loaded and on-disk path mismatch. ---------------------------------------------------------- sessioninfo/tests/testthat/fixtures/lines3.txt0000644000176200001440000000344214152377737021445 0ustar liggesusers ! package * version date (UTC) lib source cli 3.0.1.9000 2021-10-11 [1] local covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) desc 1.4.0.9000 2021-10-04 [1] local diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) prompt 1.0.0 2021-03-02 [1] local ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0) rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) P sessioninfo * 1.1.1.9000 2021-10-07 [?] local testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) testthatlabs 0.0.0.9000 2021-09-15 [1] local tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) sessioninfo/tests/testthat/fixtures/devtools-deps.rda0000644000176200001440000000131614152377737022765 0ustar liggesusersWK06MAy$MpE8UB$ަud;-{C(8rBj$'x<3;r\i>[ChNGB.edOQ2+RtTBI^򜫮[vRzb2-9Q]zaLS"^JeR&ʴdILFEN;'sF&ʌzuYAB{,4Ǫ!\wsܚUxn8c* YbPAUzB^Qy+*3X:/ R0ךpz:4QWtv4D[ivfu 5?Pb߇%QuQ3="Z`x;Bb?WeP)21 W"mbv:Z|iBV&[ife% ,U]N9GdL a^6)LBH*K$fYޮ$DKUZ1IԒb^-.M⵹4)a˚-۷IT!7ǯ~$8aN;,KaH,[rQ gX=VϰϰqE՚װmu-Q[`Hq iAw] !)Q܌!ɁBH4ZOx N̩3sessioninfo/tests/testthat/fixtures/devtools.rda0000644000176200001440000000203514152377737022033 0ustar liggesusersUn6V `[ b7uKd(PEgIHMcg ;$f6lدő-\?d[eu:k9<_ڶӈ.4^WB8 N钦`yDgX2* OuͭG_௠B=QJ}""C!U1>$ R ^2!v;Kj$y|o `XS"E@ pA8[WTaCh*g8"Gh*EA-* Kn_#D\o{'Qumި; sessioninfo/tests/testthat/fixtures/memoise.rda0000644000176200001440000000157714152377737021644 0ustar liggesusersTn7XNc;(xt#7~rؑĭ%-38UrLJ!}hx+ 6MhO=Vux9y>Ji*9,`ȐBoMFl_?ONY#N~ 12Kp ]$|(6S hugfTX$~,`%raqngyM:<P*E2q?%2yQZIa(rH*oj%ynb9Z]:Iy۩z).ݿM*2C nZ$u;Oki&Q2L$Jo|R6ô4_췫kPNwtVuմ.+K;acGV^MS;kmG^lp\S:[;"lz]v%x߲ Y=:StƮ8Z_˞=u88t`XCB^uwжB`܌MyZ]ǬA{9͌x6pʪX`9ڀƼ}{8 6U J3\Ŷ.L_tPle;Cy4P"I;7Zgz'W#O,Pw|<\13ѩZ ]oap,s#[rD>a%_V M kqg֭~$Oc 'J2z^v9oWsessioninfo/tests/testthat/fixtures/no-remote-repo.rda0000644000176200001440000000155014152377737023045 0ustar liggesusersU[o0.`#@BBBȪ֊\Z`\6@v@YBRԎlg<?c&^v7A4~ޫj3z^+~]TU.lrdȠĠՍo7`dX8^'I>Ծk FÃό7|h$"*݋t I"6VVe<ـ^F埈peZ;8erlZN] PU]s?eH8r"TUP!M超e} JLUF.L< X0&Gxj:]nl[%/#=2KQ9*>G}18&RpǺA!0, I2{CCN=s3&õోEIoo$"0^Pl!Gʀi D,h*$h[B Nr1E,!4-_RрdY٫iUĘJ()KL])xV]%3؂8 AG|f@off`kwA<\Z\\j?2((w.t9{9St .κ?;sT~ν536C"3̽3؋/ ^TFr7ō AƜ߀&=(a׷ nHc3.\]9*RuLq ORL7G@ɜȞ} %Zb\1myMF^N_:hvޟղIY}:^Q0 4X¨D'1lsessioninfo/tests/testthat/fixtures/descs.rda0000644000176200001440000002622214152377737021301 0ustar liggesusers}w#ǹI#J%aْJ# mċ  3 s3]zII=YrNVwM 'YwE6oHVYd{(TgF#ږFuUu=wՕW.\||-+K?_b"oqvs/~فeY}VP+Z\+J2ꅏU0 w,EvK>XCxJFqA0= <~Vc;׋S~Qzo`I9*nwLh0!g1ٌqo;3hdٜYÎݾC63~s`ȺVY:մ Koĵς`jMgY+wyǣwAA㼑.FQoڟaNU򼰸 Rn'EU: pa0F U 8TḰ\(ȕ(c?ύyq5*7UQ j9Iɢ;PqC{hCn`߅ŶH}ZtcӁ N#ߍq`?qϓU `UHq0.ܔď-/1bX*r= jڂZ?V*J0$цokwnހyn[MV{ƙu[ώ]Hb5js_iˢzЊfu[MٱyznU{g[oX-]} $qeXd@7I%dIo ĸltXb|7xd(}O-IGAG|}'yw}{@ a[\j뛿7% ٤jpӈH7'r Z[E uY9Q j3J3 ?4ҔHm-TFG1#O<(O VN^-4ɤ؜͞>W +%RHmݳVn4FcWyo˪95gl4yYm}^\hJ J>-jU`zEWYR#3ӘC3pe9#G^cU:n3@k:E KHOzkixCCy,?C4 !vB9ql ?XA(7 79՛VTn0ʎȾڿ0wmz|l% O\Z/7nBA!ӴDsD{ ')Í{n7ƭ!;mHoy$!+,Ewo2-?rmZ2ɗ V|ֆ.q9KJYr/|9a^g@ Y P#/޾8W,wg.\2'ڻo zl_|ZfS27҃vJ|H4vT]%Bin%CD>lOb3XԆׅ\LR!67Wj>ŒZ:A/>?}]PƑV2%%](\aQ Ъ_/_M7ٽM!=ݽokjRnfXĿnoml2"=:ߧdKo)JZ+i"_œL]pGNTuBnm㐞uʆI4\̣5Rc@ZV.&MYDIưVM'nW$n*PU7[ZozL$g)F A =3Q">M3"$ '?uªӿ<:4{J.eBКN}nx p7Aýʹ j!T[r4r׏ev/-Ѝ?}&7c?:r x{ĮsG +Y0Z>?fV]ǖjONqo Y4d? du{POEe ?EO] Y"ÁpP.VLh AK](~ԪNVS-t_Wߊ{!8\}C7h"? mO}PS^ Bq4|yg+1[K"S:"ҁUfZC^S@Z&!#>jajЍ)֨D'ګ)H4h9W`hE{QįZ2#%Rh)cpPL 4iXh}yca@p<FItBږ`6D,=l Fep:L( Ա(bƒ;{ s{}i$t`ŕyf^n-S2n:dQpʍrU#y~sC |6|Zom",o6m rIQVZVEii̶Zmՠe48\g8w0o!q.c|뼴:' S,9M}YOho>X=л6&"Twؚ̹̏ q{1 1( $1[ҶHXܸ@K'{il-`aj0]lxsk/7乖Lϫ ~yр9d+:¬sYC r._?g7t[uNus)'^sVؿ,D&JO<~l6j%:vI4"gŻִ[Jt -ˬ$}eUi\fՆ͙ k˷M7-f\RAv:ZRkn@[*!G$*2, Cϳ9 !ȚR '-@ap]gJSE mT+t21% =6蕬R2%L*qK͚HSz2ۧ>!׺<A|Ltj0M{bF)S Hi}n+'-҇=w@ DQy$Z{$1UP/bN' Bnu0jIA~ٞO]`ĂT"]9AqRzACK<+3 NDbY: GP.<@q8Jp0P Mv5HktT[Л"$ z6VZ0Nu;wc|ơtg9u4wKفPYtv僞EbB44J`sglT>ɕYfiYMJUyn[pMa(8PLNJ#dx/۞3T7áKn߽}C"q+! TV EN{|:$ͫ.~`/vy6wMEYn0#*ZW<>=̜6r5hT ,>&*̤:r5} ӹSckHJ郢냴 F2r#ڈwN㑌,VzStJW w<أpr!wЙ`yq{=z 4Rܷ0؆^_@ǖ{h}[L^(yF)çĖ<=TQ%[XC71-eXAZe{\'9!*jfIVsLZMz9'>s2|xR7$~z]+l`SK%Vۉ2Kx] KSN@PT(.DZ/P(p5)zc=hRgRSAZ˥]%m]S89ӇlX5}1H]Ȗ$sRRPVHK%d\h-"HAG":.M>]F)K;C6Ld.0׹lDw.d7WږwGe &b\Kc <}dŃH@ NA`x"X* Y'Rafo<hOs#*_ 3PsPT5vҳyޤEl*N92-N[kF_I?By!}> L"!/f/NzfoDĹL'@8ɘiVeI?:Hфl# :7"=t2޶= )C% ,; `t-zQJy;GtN󱂀DFq5DS_DcWj<C`$mLHM:V0s4eE׆]۶nҭԻNZޮfӬ8goz#Q=getPC9g4' 㼾ah:+fڵ;LPH $"R`7Ɠ(+Ce PS0bh¶' `7G@ 3\pADx\Si[ PyD9i-/)x" ZOf6tޕMn9Ls\]*E>^ʁOSn'Ћ#qbY𜈽WL=̵` ͚"IqEqhU ލE׌az&GS7Jvb3D9"Q0sC 1}Bn",ΤuWؑy2N ,VI "5 & 1 !BUqi"'{H~Ҁ jpXjT#-̺҄׀?_@K{x j(l*q{|BJU'-&sx Pյuq}USP')Hvl.D4OL#{"@C^QЅب8BV7EzWA違0bG>RDžc I}ښ-v&0ȼ\W T(>/O@+Eb_& uLKCi,%"q0t#O꜑hlbpnɛjUw:bQ%LxS=`l)Y Ium3 4<#R!?Є9n'dj=~WeF0@1U01-Q5& 6D1 Rl3ɛ.@]|ۊ<r0_/A Hc~${ ;wՉ(LtN]roв# A7;ByT&@[bC d}=%.!tIL>aƔ}~,l 0]]AV_7ʏFn(.3!VrU?%g;P!! pzD'R82!QՂ=ρ=:4"dA{ttq!sؒEIU-,u9*3YQ_1fO3 - ۔&(F=-/p&q!:X٪oYtDTc3wֹLcg]SXf39@|j"mZ[709?L;+qgm<$O @ȐK!X؀߂VT&GGص]P7i `8k90aeL]`E= ,N)ur|">pwH`^s|9NoimmyN U{ݬ4j[Lsl@p+@Aʥ.OϿs.3(N޿><@ю%nz5,-nC+LVG @G)C"[?m-l-u2-2-N xu8K1~3 }SQiF7! K9>ib|ΜKB%g썧$R-h}1̠z yZ--ֈQۧ/ݿɐ\T)W k!b%s'}:]kwWBП.62e¬CAmt^}%&-PKNR 4ANX6xlo\"2=U+fbMjT(OnąOR 9$B xE-Ҡs+Dvz#3uhJAʿ "'zQ~|BbAyL4y9 m%W$ ZL^G`{7S,I6y2F]p]FJx>}W;5+jay@5X~aXt&L&*{DN%/D-anwsfL0bې,,V,vFfbGLbFm/1O6%#}4z#JcQ̗>)bDxQ`5 o{huUF5sܢЕ fc 6Hp@VT;t dݑq׾{px}%W͇AsbDϏ1]G (`oS@; /Eɳ; uFD. _͐2'%DU& yEq]Ê0fFz:E~<{~wXC>uW@]Q~l"4odA,ZR:G)#a?0)zH32~`Sz£AP()纄iDUGsfEc K踽x|U|RA ΍4=jhDh%%}A=Х 0R0'[ݭJӶ ^=f7榽mmUmםݧ\̣:~7)vi:Zu7qZ; DHkUGO R-d2D8]3x7ŅLT'yxţàħ|rbS/w8:V9V)_pzvlH84_ǂOYu3Nf,OGh5D]Bu3/,EHɋ6xwryW/fJ`-w,\lʷ 2͍ $(~y+ Tl_π g5o􋦤-}\uOGXl'+>UWTF=N>&vˑm8aejKjix;@gB-ġܑO}N<|NvyVm̹P4ݐKVOwDQRC]<$6SګI]w{t (:x=}Ztg :Kw<,nI_p ґ$Ԏ:2) EG1B#UjKIhF6^g-WZ'*B+.<8ibp`Kk"Ŧ+k'فu'AşVdpU[)P:607֩ r?eC<%# )죔po6"-* x)>Vmg>C|ѪYKlE[ݐZ/UA]'42wb F@Y^2,'Cl@\SubOFX>^n@rBc7 ?Fwln0g<:U[J˓Kyn* KZz-\,f\s]k)?-Oٕ# ;8"-ء Am )=$4V#&yki"g6(H:8SgxWPb55SSުtτ( vfGHz|s\unosڣK^C\w),{˯*iZPJT-`?JY:){rE֜CF1jK&)b#_V9(:G޸sessioninfo/tests/testthat/fixtures/gh.html.gz0000644000176200001440000011430514152377737021413 0ustar liggesuserseagh.htmlv80{nQTW풵ﲿ{ (RH>whG'$jqZNUY}2, ` ( N0Åa+p] Rsm')Q&ɶ55C24䅮]:}~ *f*~/wQhRǶ9sBͼ#L˝^[6;B3R/%@{]A# Nbf~Bٺz7FZ(S VSh|-@Arx)ln [ L;‚en sgL;[˧c8-46/`Rpu8|76C-d其TÂm_8,`mA&J˗eAA`p-lߢ(tFX]&4겤y^ ` _o@T[zv2av000Lre͌Ia,#PnL3EZY/qxV֌`n)*qR(Qym"o4iV2cFJ<;S\)sq1b`?ڳfT8vYQS}x|U M"䖧"}0&R>)SQt4UUM5V&g4|%dy[7^DIIkkr/+?7j:7 Gٛ|UuKt6ezRݴ匕Bhl/w쨙$%@"j@VG4(*J&u)*ݜeѕsk7DAbY_fôKf en%g訦 h++Z/͗|18㫀ojhKCIQiAɠhC58` r xfX}Ѹ@T$P>n!3Z:;g/͆U{)Ի ߴ{^VX<#^,v9~ `رJmūE(Z3drѐNCQB' ,[^*!thPP塬>5v+OHFaTݮCg˒敎jW󶬷CP=zRo̧mly.g[ZA6F|jgi/): ςgcpX<5teԱ^VLj",J[kplT{8*fX_%e&~ș)iŠ`0 X?ReaDz`;Λ0Uc!Phϕv^VtkYB`J XUV5.QvZTm{ZѲo?<JA~.|u0s۾c<^YWպӮŦ]Jpӣ]z2_vA1r;PNsyuEG:Ө[)giK55Js$˲p'ЫV3ΝtڮĎi* Sr#PZ áUN\bW.Z8\ӵl>zKsu|o Pl;o|\߈t&tֵm?Z ,i;ԖƶZu^MZrlUi:2-hr4;\Bݼpp`HȀϠ>odʠzF4piDMJZ @~nU<eRwkˠN:̞W h}43MXDĐē 7R"HR8gh5F@k/ºw^6VݛH %W5]2gDc5aU= VRGFEB5wl7}oTW<ͦ՝dLfTԂQ΀0)F" _I j}U* \ҹYNaeU [F}2@5ieP)܉J1U-"ˬ‹ @FU4M#q5d^XK;rٓb ֵвLuV4ѫf}ԢEίZN-P4y0 :z U<#I<0(:>DFWV` =;V{5c]9jevSSkʸuX✯EeԳƸԌ t-KcH$#R?eNHlFxeRP{&=6z"5]>MµTM^ߖ~N?DC7/:K:EBZ gsR`H@COEOt( Ru eBqŊJ8}:OS,B1-l+dTʫKt`{Sj^+{4$,ZxdB)ќ!Hg1TZ\ үV!2Zm-hS +c%۪]ۤ*%OѲaAýaFu_'C-n~(IIgx\‘yۛza,@yj֔1EOz5 vK<q_[[Me7SG]7PV"G3G( H(H!hUW^sϼܶhBm+g' KIpXU3>z['urlRͷ_̏ɔC} jPrg*mDC!eUE vk<<qڲZqSi#'ںK5붹ao6j/$S=A%F77SUYTĊ8j=6RLaجք!5iX=JZ=փLv\;]+-{-/uE$HE35ʓRhVhUٞwumN*:]hӗh%Lzm1Fs8n4uk сfGYFӋ I)HHRɬ%ݖVd,#L;2̠-Jdkuj myrlf[|XŞxh-݇^u2αI uy7GH$N1/n[9z4[7葦rRPJ٥715]cuE#(E7>2^Hׂ^>QC,l*mP)j,QgHJuHLR`d!eK]eӛN:֖UEfy7f[VEiΚ킦:޲Ŷn@Ul-(>@},) 3uj[ Br(>)Lorՙy>_u۶:P6u[F _ 1z!O[jP׎7'95>H]ga>RU[6#pwT&#Y] SV 쐭:+kb37ng(~c&tkn| 6Õ#,וIGW,ju^U6iVgk^2s6:@Csh$<+ҟ>*ai<J%,iWTG-GkN츝ڃǺĶ@KO򶏍(| Bm 8zȷ2Hvm֔uN5bHh!n%ͩʢ]dT&EE`Z~񃕔)T ͧ^/nDeW'!qvhQIr+7P޾g4i3f3SsU(;AzeieK%  MۇlkO[2-ahP/n"^ i($R+rS(Wu`V i6l7@r՜Z`/E^Eu1:Ϻi7,N:#H;uiUm QoLmicjKN>[߂ΰ?EꭍɤZT3@ZlZ)Æ .BW nKAr-4# +Z'CIݕ M^ˇ;z\XFItIˎV]A3tVVytš[qoi Wխhq`HIeYS>cקG+;b;2i~ϜHҦ:.KgÔ_8۷vKXMĵ^F9򦕡n^,ua)CcԜ43+nxyYQWƟFUҘ!WxQW}ˮ*0rfQգ/Sz̗[Ί@yШ "uqshċ, >.l/O#PYk>*90ӡG.ˬ1t{ 7vU.E6Cr,:ɕߤ$PHd^p6Qi}:r#eƴ:V+\&xX?"=km5KP#7/+/!~1};ט&!HQiFE:7psE K|_F#gjAfkON|ezx=uȯTec/mbV|yyhnZhCNV^ rԭf2jÙ>JS-f}1 Ӷ1YϢ~KW;|JZt[ՖU+]:AG:蠓 h0>.b: ӆ%wDyCHpekwX)"taхZ"O 0|wA+6A?D FM@}ҶlR+FٸTD[̀%RUuNw30M@~%GcJZD%(V;ޥš⣨zߦPϬ.fV*=N-r4,aG` 5b-8s9Ӌ1E=V#67 ϖ)Q4'Ir3R`PB+x^,|BBR• ǥ z ®U8AsDYbT]iV 4EqTV OdIYXYNt^8>{ 8L+)$rkRhPͳSZIc4^d,s`Vw[B[ΑM?b Ԁg(Lޗ^-3bTD\.g*pyqT{8/%}(?pCn#k=‰ $CHDq_ \7D&@ G oWŠ .OHhiiQd((3*ep"/I t !@hQLT8MF)49I®n'ুdRLh"*h:ӓ&o mJ*X@Q{` !L#,R`b =+Upܓ#:-2fM6(͜}~w4tUA -- M786dCZ"5=/>x$t e3U,˚wAyZbgU]ưax?WggPO|yE8VW S \3FpS(/#~#o.5yDq" v DE_xO"@jK5Hc2h:FdZkPSƠl+ orx &)qLw\;GE+!ЉH."6_A? h5Tˆ|p: &c/!0hr*cQRᱧ*)쯑9+ei3ˎgrJ(Z 'BhEa,i0ÿTMx-@<ן*Cٳwth ͟gvS?[oC)fBx ܷ1l='0,ŚX@/-U7,x{a(vP4͍'7Lf..jsvi4ǽ@sf[^W{!P42f躶ꮟP9{1hC[*1P;\ ρ5u#vl8^Vz˞t8=TX3tχ%yAz q3&9 r3>yy:?[ Qv2m "L0(6ڽ y^>4U])0V{~^r!rrg ȇT܂L+po醘F:.gBx{Z8\da-}vAob^࠱-0o.>J.E4f Ԩ~mQY^Po۱a@o歾9!n3q9Tُ ?s{qΐdN`!m.iaA}mEGy>Eg *6P,ͽWލ{6 |%̿"IGO8^bɔ+Gl2Ψ›.e\)}U˶)ӛCdy^zuKzpq2dWΦE3"z uC!]x}<-K_ c[d8xiߜ.Ke8ꃕ韛q࡚e)M=8 h@u(M?t&}8,E˒Nb QA K uѵÆ"MQWXC|+ϡo)gqĂͳ#_iSz!Pn% P1,s5qFg?Nzs> -'pD ڛ"G *  _5#=ZLN.;E#N"nFwOdBn4M#GJ8ޏD 4 AvOMY^4>L)5}gxU1" X}@ ujg@dž$/9>9q#@D:vz\޿OX !͉7BBܢts}cXYD~sW[u?"Fh"tshg4zg'Z1dvLxAe͹1?h5(1a/B}.@^DZm+Gr;ˋ•^t99Iti.tRk:JiJdo`V$o;JB+S늡ܺtF tdhH"sR ўUv_iyHmx.tm|j4P]'Z{>+e8ݤ|vovd?+Sⅎc fJ3Ywasr@#2[VmoHDon8شQ::d-XߕN}"w ʋ7?#ysvWz2"iSi x)݁,@348)3&h3'F)fw-DhQp=E*|]E_(W._p憚U_wIud 9HJڃZ#< S f$1p n 4KPvn}OǡX@* PD 1J7\:v I~A!31|R.ȶZ͒d3zcځ\ 1wzA0[Ͻa<.vfW/ :\)VrFZN+>~ik]*R= r{$8R0ޠ]xu(ŠxCSdYWP(]yY(hkJ2g HF*˅P'f XKtAb5gΪ o "t,dI]ypN,=((ItW !x?UWH{%($$gg&FȕxhtNQbF Ł M% ` \@PeO$aA%iHC5ȄB$CxyTE8To88HRf9reB& P2֏/GsCAwaB'Uı5EhuRyN!XcGUIUNSŰ]I:;W8zA?eWi0è\a͐e 5>%y=ոw]['NqGe {D1N!ΙPg3w"Ra=E{N&7ϒq(ϰL`` a~=%!iXK"¼ {&0$̣̂,a0 a:Iu/:`հ H#XO |DߕfڗXfbycɌ/-}[S>8't'C7(bA= ׿艣Fu:e0(<$4u ahVJE` `h<wxӱq:( J+ 64hO5XCI5.e$rA :􋐤wױ! 2_={1|vFRZs1MOi$*}.(x5 hBN} 8CQ̹ggcz"OyZZ8qI{?t="|[ua #X @F'jʼn{UPJBGO$2#xpH H6mc`{Pc}P['@As(!>AB ՀMAՆCGfO#N󑩌 krRqN2Ή 1j =™bgVd;,lJ z8**Gw{Į5s˶RFa&/Gx$O0~C4H6\QNkv$q.4?LnFUhlm>yɥIޤJ!kщB6!n6ź bln{,w&>V![)ܽP}4F;/ᱬ` twy8=tA( ;Y믴-3+}IK9G/b_|ō@Zl7vvwOhTI~ TýZMf6M4g tzgd&L&O䣅$e#p)P%`ڐxXآr\؉0"B'=Ͽ#mK< N`2H@| ^ܸ@M\Rm6Î^OH.CI¾a s&Y:IEhg'T! B$@VODD\_6t'!B<Q-U@˦ʫ R)'+t=f&}EUBZOxj ׷ޡ& ~_OSCR~R$94.ԐwX\Xw4:Sgǰ: ?C__ڃ:Mu}\!4z}Ӷ͊1h B Hj$[ՒF^iMk&h$׶5? ZN{4vOƮ]+x?{kvBtDB{ v|ic+VX!AYʟ%EQl6v?,>A6D"0Vp͂8P('&U-j6:_\(J%tb]IWM) wé5kq9z.#]-B0>& R8OUҿgDG{@يOw6SUM=O.-~Ip̓PɄvЕ+KdG_3c]n!m7ت<<ӳ_z& Ƹ}t?,z- hnŸ|cgp@kGӧFp7LEE !c>aONK@rT6)Mx m@A+D dL- g]\z!v3[86\LWn\(B=؞S u@E3rL2Yҹ̾eIn- ܝE jubeY,C;ˤNRC'g2oMhOs9Do(zsy\5^DNP.iVCgQu1k0( L$%2Tʦ1g {AI.L1T+6M]_@'- wlm_පM3^DGoc!@uVN@A*=Wwtpa(6Ν`Y&=GRPQ-(_Hz_G}Elc U mh$L"8kTCC\*ٝPOջK-PG,#Y?>6nh}bz8ŵ.ЋG!W.5NSvl>w9mJ">\@ѣo -b(L&;q7@R諸,!Xk*:ɟhEBQt(8L n`+]*t*d?~u0K$ktek~L:\q/¸8 TɣƧ 6r`7ˁ ~CTLv? d/Ē2&/y?;ʥr]v2>\n@Eܤ#1a0t:?ƟOa0tsh¶7{=tO~'?ݓO{-cm柴~EA.J+VIܤnO[-tK~%?ݒnU.$8:C{w$ʎ_^xLt~5C=uhQ5lwj90C)3COW, Jqc`8I%QT Us&124VfL+A-jNso`"_ ] y]h`cGi<\QH_5Nd{"?D~ZQWwbo`8݆)$1qh#,]:q cvmq~{ y\3֖GEw#x}&NI$Rǝ-.{/~4hM MTђp"A)Nf2(aTE5Nc$8{~mxfI3*h=}%]u\Q [mߊ͔5(D? th=;dS3~Nˑ;'d,3kΒd`p,; 4#BߝW‰8rX(&#߽V&’`Vw !ђJ%U(srMQ`QtWyb94D|?z~䥞Yy(;,=v8/drKoL3.v^6AStto PKڡyO2 Ad86݈XDAH{H2Th|<9'Aªkν?{?F4R.> +}]y~4MEj:TF5  A?_(UEQ *L)Y0{6h/8}#>`- TB,! =E=J^J=M5|!ȗ]0/,ZBZ_2U5g9VH1jJPm)"E DXB(>Q% ,q.%XQI`YH>?:NP+Gj0r$.n%xN9Zq#I1]0MHXÏ(B2{о0bJ$htU)!Pd;m.YBD^J{=UMQ{| ]Dy(xEl_) @7.2_P]bthr "&hy]@ hh`)%%͐$V>YCHc; ۈ}t+#,O,G3-*Ih FyZ}439F2Phy&n$4 'B yVȐ׀HY&VN1@E~Эx2 H]84nvA! ީS !-׊vR P $Kd9F11іEq4KX%qS$$Q8 Ss,a"#%o1Blu~_W@,ND'z~=-M-,uZy+0x.SKb7\xkr_.QjpK`X ~ <]yJUQ),K:P*D `u5ЯdwtWd,1iQ\ĶZmi:LIMuk 9UeyDk;&EeGU8׾-.e |}M6]4 qroL xM!h>kw,hӦ9Eœ_,P(ΏF ⅎ^_]҅RgQ5"P`uSL_8Km5WCq7 |'WM bJ";~% qh^‚[C(>Jd 'vؾxsH{Q;ZLtb?8[ k/43 xٗ٭"-G"s"RC0rxpCB>f 3vS[҇CeP)+=/wxU+<.h!,o H;1^t$ͺoˢ;ItB) 5 4z%yr\AX+ Ґ;z {CKxc: >̇=1gd]4 HhJI 7pa!M{JoJ ]ҁT>xxoI `.x]V` THWr ;B2ۡ? R}xO""{/bjK< L[\(6/z#v'O,tbIN,4KZ8uvCo9vб{t`3@W]/T c)3:F*i<ͼw£ ߔ棋ԧJd22u.%٣7aNK)?9*#EfZ ( qH19[ ^+)$iF {E‰w_U'+d;1oOI>t qv׶ڡp@X>J!'!'^vC_bZYs KCPuI\s)zC ?;$C[,kX(H 42\l8}&KqP 7W?˪꜒yxHJ$%qxs@&P&@v ]~/K_ڬz1sb dAxnbAm-_[,,iJ6>moMo\OFɷZ~_K.Na`MdVz?ZqQyfRʋL-p!`s^u?Ћ'˾-`|7:t̹^s4 {`f؇=8ridC6>sDz.秝VC(c&q^)M/ e "1ʥR8Q GPJ:N8"F 8!:H"pRt:7o?@~"c7;q7(哜LY${YvpD7\:.ABDI62K<$5E< -\\rxS xLMZ}t#^`8M)>3Zw @;:(*]3gH%?;Y w.҅8^qոIlnS9g J3nG- [U, djR#"A^d':ͤ9'5O*C,2W=ɋOtnpꇖ-;u.zy@t.b=S&Y%6!r#z6LH!}+ZhmرOݫ rr~x|~wڷ.cJ ;jOvO,y[4LAK|5Yru[\,_UIw\Alx; fJfrHAd!{PHxkAi e |Lϟo?\HM_Txוd_mU}KuY6%KP%GzףǭObtV{}=.ܭׯ׹&pxƜ4ݐGMDA!ȷ(nNMxNnba#p@gb;+<I2&:|C2$66&` An2U,QA"G1QlT>w=kzElKұpylwQ|Lس#=un -q8sKNhRӗ}σ/]y׹"qp?a<(c,~!]](nL7_[[w'Ax+hrldTFpVN!usPsTY43 F=Ө^K X ?`.M0jzC$ TS mި(Ho>VR`j o.S Y8t 9^*#9-gUܱP L9BK5: ^#  .I _LY7T C.{] 7hqoMHh+kd 9c_X_tc}ܔ 4[ @f5Jf3{IMw9-嚐הyxfJ)/XD@%p@7/{^jӄ~ز`y915]͘J1ъI:`gZL+e²^RXK _),+k(,EEVX"}UEF HD T|SXDN'+,W_Yar ˏNRv9-KRpvLGȥx1JAi- 4Sr#W3([4jT217Uu;(So`Ֆ4s(Stjx B@#CDqVPX>*=;+pƂȔc`R>4:DbA}]]+J+#G$j k뵶fN + zCP3V9(@8c^HzbY 4}TxSy-=Is^)ꀓff{>OhC4ߒ_ T_+/)o٫`C!!TWqۼ9.h1Z+yӖ*+;lG n.8CW6p?wIgɳk)1E"M5µڒ .l=a5! hxk)eח\2|q [40LLW=Sd#$~ϧ969fW8g ,~dW}ɐ ̠m ͆²s=ڏPYFIH7!AMhy$3p Cދ0U)cSGVK#X@gZ@7ۄr޷ ]@8#qB"%‹.Ecz[,a 3ߌ*n |)C;%DR?anÄs9"%@r0Æ+wK&0"qbn66܍ARBabTY&arl_\<1fƘ'šH|GHi89stqEG1$ٷ Ж<@hK%ޓ[ju+¯I%9<Sڒe`SuCSVHWZ+ÏKձdiۃr'>]l_b[;} ʑ/ܝHI~"ދ~u<[myxh#!b $֤5bIĎQ8}H/kbIDw%?2ݮ3 zjD۶b/M2i]aRָcT6SA$ZJ`}|X|y=V 75&Z1 4^\d}?BX֨4– 7 &AŴ$`#P62[놷8H,i虚$HG'8mq^xR4s %uT`:v1Q@{jyqwԸIl{DEn~^boS"*~iP AhuFzm j2Lns}ywۮup?^j_CIaǝsӱ'=^(-{a ˇlNsL$VE4H54Uw(v_KCKa(?ɗcG2{>lmmmoQo[PL]I~'X'nFbt^7iU||́}u9tw?[Ƿœ_CL>i;dNqX_>W2y5m΃fbL~4eՑБ<NJQ$ِ%EUaMEpLMpY=(/㪒 {"j΄َm$GCؾ?/lޛ##vޝٟwv<ﶩ[Aáuww6 Ni:^ pNbҋ5kg=`vk[Z[^W)BW=6x%\7$iCkβϼ>'0Xf!,p:qݡ<+]#L a>n?΋4qb@EnAF( WYtz-̓;>su4,եmb;9r/nnq-goա:k;^aGo9طz泡:rjW>nTvzN0؏%:Bz$v(dc))=! 󋋍lFوq1&͙;E.AN|kdr㢵F}^<$'Z*$~j^OTG&7[*R&3:ݕގɍSQSrV^?b)&Oo!BS^D@{`1 iQa4x_V7A'AY-G) r2UFnt$D߄( ;&3Í]{R (p$648K\ #5d(G(+_M; M5$+P$}qB_'6d(EN=hXŷ< 4K UW4nHPcKlDو.jEp½(C;,Kkq@lYG(qu^5LljH 8 ]-vT(cuqҷ:NAuIDől7Uͳ5]42 S4SS00Z1ED2;"BđjF_G$c𓙕gX?̔ͿlK )F(K4 |2xYQ 1!6\Y< Uݐ 6\Yuf@ fq՘hU^ ټ :? qp)(ԅl QJ.L9N-'ٔs0=bh[q;J8u=e$bN)1 `#)w0yBpJdK~(+5**V„2#V%n>*J3@T)ǑR(9a7@7%tJ2`7aJ/+/k^y[Օr]>\ +p%~#0HZђaVBYVMIL0ޏז4T2$ lʆTa|l9"Is]NEry 1f# ?"mP4(k2F9P+U:o謍iVv ) gd, ׆H` v꧰:]~]}7Z_ܗVi.0׬T0!&7~KLeh<.$h;\7TiC'AQWTh;^\=~M쑺jFjE{Z!|#dSuT" {&Ym(I&tòmY`F|KTEWlх +k*0?t.c+wx|λ׮iV"+d7DIY Yd,Bkg`ԸBQ"`sy\~E <.'Ż$R#2F[NX$y2qk=+"H68-ML4ɓ*9&[Iy =>Yec֝4KJ1*'$/vwxe.zO]wN=Lwsا3 S2E2ju"~0A#^ Ŗ*BPy팬[~z,.~M8uv8p_?]GB0НdCҀ͕5_׸0fеgqxkBC JǨs܃hKh鉰׸a5.Mwh\N``zp^AZ)JD?c= P?&Ad1 |4P6cjEART$ ;q;XL6c\+#Z(bƻ=ģ\Q*,"~ #~65Q4IҤepYRb3έJiP#6uC e,Lj<&DzǦyJ~l[ KK@+xALd'ةQIze8ͨ%]dDY$TL=dl[I(|##f,6 AJt un'^1!,c}GP*+oP'Xp7 =,?d>&pO1J3*# aE/d.֨O5R+9:=rNNlpV9>i;([Z6_\ҼR!ҼRWJJi^)+y4ҼRWJ?T&Qvj¥x:|:&SRW"dRT|/WJKekA?nq ai$ ebc:F0:'`z9STD9#o5IK] z$(['œX>Q`/04a WS F'YjQ^O+v>i) Qtdx3c:)bnL3QprM<1TӚ\s+JD? 7?5XnɦKK]jjDK}_O+sL%d%a[|KJ{CTn  cv:5ck9XF cnUcILӌNKCAO g8r8V9,Lv;0* aaL$l#19f-LrMT_0s);9_-Ig@ԧaAs-rG9u ΋.ji^[#w@\a0* s0:y8=a}Z&50.(BaQg؜Q‹ZøT,s9qy ؼ }`2X֠ )-< e&\dΕ d~yI?μ\Gp%M P7%pp@63 cvN ȣ?xI6U.܉JE1 R<$E /yt;{=.5FBvѱ( QyMF{yCI4i Qw~&!i2'bu~rPٛ89n9W:UuA ~&Ŵ);n#/Ixx>Aߟ+-11 ;L* ?_~_\?>Xyw/>zr=Ӄw۟7}w{9E,pTw,мVŋ=֪ש-pŒcpԀs?$Ɲ~s7tYyV?'%KWPs]`#7KJ*peҊ`.Mj Ҿy4e*K[4e*K\y4e*Kk]4c2LiKBs R5.dUX,K-腬Kոc,UBej\LYpq!25.f)ZƅKKոEjb-%:.dZŬeKոm)9g!R5.d[ƅKոp2.Sbj\ĚT Y@q!R5.di]ʌuv9"ݥj\ |O/eXڼ\X2.d^,Ը|ԓ,;]]<_z`av_C$_]z[mpr"a/ N~\Ǘ|u| }T;Wo~7xRa|'2]άPgV3+ԙL=[LS҂m%W., /pFsU[<G^ ٔ%l,} IY%VmرOݫ rr~x|~xz9Ԏ?=n 'cYxoj+J/ڶ*%,%#hhyۚ牎mۊ滆"+e0*vF4>m'Ƿǯ~7=4$ݫB[ۖfI0i{ip8U\m+~B{J6Gmr m|ZYÔ01R")\%j8349໡;7/9_ԉ%pOnMƄ ./2)7귿cx}q,|w6$7VS鉢(SuC%)C:}`i|_7wA}wпN8z9]ƃ''V@’Q|r2X,)-r=mڔLeKrK:K1Q)S"w:UEKY( 0%jR܇?Y'?C p*VO"uF/p reޠRJ! y蛗O.204ր3;^lH3 XF0uIėYM=;?P(,:NB?) M@&/qS+A[uhvH1dɐ4YG5Mų,Q|EmQtO<]1\M[uMTsǐE>쒽ߩ7`Da\#cS4Aan 5Jdz~gp04m uq6+<}ÓFUȞk颭+"ڂmiɶzX&i躐RUBW~0V?Jo࿬zh_,L X1 rͣ|e8 5j< ?]ffjZ˪96vo[Qκ0\9blۋO_y}p^|]ӅŽ;2L@&ԟ=V[ȮUĻAӇK':ZIȡ<9(^&L"t[|B(]h󴛄xc͡Q|2O ӼM55ts&#cO@2DF?0>@j2RcIIffihC4ߒ_ T_+(HxC^<&C 2d\&+vBu#^LTĉ$4#j8oe{42?$QBַKʾf۰zFm۹p{[-{}[~tq//v~ anwڹu{wMov /?-,,/)1AqN7XܮgEN < z(7O'$y3::My{2dNZz[ GgiI`Bɨ(lO"eY,J&2\ ~yr."vP~A[McfI3WI1TU%msBHgg{?!_U\~:~ƙ}5F~x2]Ǘ 8|+nK N?1x &(}"7Jͳ! {#:jaqV!'׵/<*9SZ+ruBdE#`Jɓ_N姯 uɲ% q"kZf0V?Ecj`60ϼ_Nӵ>*eẖj`| V>̈q-U韂}(u΄Zfa(-CM) B Xk` Ҩd4E-|Qof?.椒$I`y=8ǂ[|w7bargo6Y P@8hR _eN2i(7z&H/Þ0<57t5Ac&LzGMR|.k f8JW1WџM}vj&Ǿi UԆszC5UHȐ~|C!bC1y 5d=e> @+Clux JJ˂ t~DtH5 y:zȢg[?DsQVIJ~=2q55i@7d '<'n\C:j-El %h ~B/p!?t8|!`c-Ď'ahXAD,U2WKkþ;4t208(d M:P/C*avaU-^$.48͏y~?9jůpy~`.3|4NSdq|H\QRTAt ז W C%M UT47whR%\WARw`T~@: %}4 ۊ'Yɖ i,8 j"Jbfoɪy#X"?c_XMwrg0ߒ*ꛆo hH / m+扂bz18UY`ɻ"Zpf槟m͹k>7mX ;oxbȮ뢤ڶhx|UUP2˲кnJ>XϾ`y&L9+ HZ娾/dKٮ/[ kYHy0{Ы4KZSL.2X[^6FU7'G>IuxhZ$߅9"jmr|Uy/C7{{04r1sHo6sdv.ps.}QHa.шY` NkJ #GDIoIŕSY2Ä_NVIF>@L&GS8Ea8A4x1~JjbH3V|_zb8&]vA#Ad,G9boz(tFf#htQ4;-k n}OJnB "QiTI1o޵;.h#5 P}$v)pcPU:Lo%78|PȈyH9*Vc~u՗^EDܶiUnȚmFl +wы|Ji6sݲ*VR\ ]/;Im=n8B#wa*`C `W|sm uS^l@:ǼGI&}g|S&tuG`d )j[,H"RmRE@#J_w:'1[Nqg"Ǫm8\zQdfۛp$e7Qq)Јk{$. 60wxGsessioninfo/tests/testthat/fixtures/MD50000644000176200001440000000262014152377737020014 0ustar liggesusersa429f780423be984b698e4c36d285b33 *DESCRIPTION bff899621c77de080a3ef27cfb70b33b *INDEX 22cd8a05255133c305564b516e7a3746 *Meta/Rd.rds 429724b30f0322e2d56778dd130867d3 *Meta/features.rds 01a94e36648a1f8302fc451ef692c986 *Meta/hsearch.rds 9bd30c296e0e705b742b51f44f99b61e *Meta/links.rds 06019c01d899dd9ac5bcbc1ab93c316c *Meta/nsInfo.rds 55be8b99dcf16cc28f441c279ea55bc6 *Meta/package.rds 5156c45818e1683a3d9e3ec41e3843df *Meta/vignette.rds 96ec3b945479563c93da75299c577a76 *NAMESPACE 049fdaedb9fff0f07342ca6a6c75e3bc *NEWS.md ebf0fc819595d631b8bf280c4b049940 *R/fansi 97dca9d3f744065714257d1d0de6bb63 *R/fansi.rdb 880e55930e831680e23992e6f03c83f2 *R/fansi.rdx 5079e586ae2ba970be4944ad0dd123aa *doc/index.html 7642f25e75f84d5811fefb105694ff48 *doc/sgr-in-rmd.R 34fe1d9bbffdb860fd7a2fa35a24c327 *doc/sgr-in-rmd.Rmd 9653f9785b8daba190d1b04e9acd080c *doc/sgr-in-rmd.html c2d517b6a0191bc228b782c576f3cdb0 *help/AnIndex c5d03d5e1c296bf829dd6edad6a4e103 *help/aliases.rds 6ecf56a6d11f78f93e28b849908942ed *help/fansi.rdb 37b6d5ce67db287a9a8a4b507e9f1dc3 *help/fansi.rdx 062471f7f5e674f589302364ed41ee13 *help/paths.rds 0d5b55bbd16d41e19ff10a8ab36aee54 *html/00Index.html b6763e6916890c631fdc3f2643803b1a *html/R.css 7b96ab4bf019b0cfed86425634d640e8 *libs/i386/fansi.dll 24b4d526fc30094c13969216ceb1dd56 *libs/i386/symbols.rds 6503170d698e5a7916bf2457edc5de8d *libs/x64/fansi.dll 598b845e7cfc22b2d72fbae5de46a21f *libs/x64/symbols.rds sessioninfo/tests/testthat/fixtures/lines2.txt0000644000176200001440000000410514152377737021441 0ustar liggesusers- Session info ------------------------------------------ hash: squid, supervillain: medium skin tone, ewe setting value version R version 4.1.1 (2021-08-10) os macOS Mojave 10.14.6 system x86_64, darwin17.0 ui X11 language (EN) collate C ctype en_US.UTF-8 tz Europe/Madrid date 2021-10-12 pandoc 2.7.3 @ /usr/local/bin/pandoc - Packages ----------------------------------------------- package * version date (UTC) lib source diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) mockery 0.4.2 2019-09-03 [1] CRAN (R 4.1.0) pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) prompt 1.0.0 2021-03-02 [1] local ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0) rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) sessioninfo * 1.1.1 2021-10-12 [?] local testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library ---------------------------------------------------------- sessioninfo/tests/testthat/fixtures/no-sha.rda0000644000176200001440000000155714152377737021371 0ustar liggesusersUn9MA h"h'@KKZhj%*NL'+.wϴ+MRS&?|3h4 fXh*yGS-\i,6{1y*`{g^ R`wnQkBO`zyVZ}qg* 8J,@RĈMg[[ qt 1'?8v:SU';# $,98*ߐf`ryێuDB%*XECi%  cRg?c+~KY$ɉWG ʓ\$ ['DhR~htb< $R< ޏV)g [JBA)aKqƤEBl"f`$"8]Ql%njʈTh D4Ri4.!'X"׌v>)hXKRvhLNm6;KLB!MYbJ%<;DcN%tj$s2Uy A zovf`Fը zkk`%gU.OzaO7gp]5($?Fܳk͈10hR!TzT*#=Ò K\څPB7]yd\ 绍Ku 9vi2S&K;MsLG߬9;MK|QJnɁOl8gw_w4WܿeJۢ=$IER!0c~޳ڷsessioninfo/tests/testthat/test-dependent-packages.R0000644000176200001440000000646314152761134022452 0ustar liggesusers test_that("dependent_packages", { ins <- readRDS("fixtures/installed.rda") dep <- readRDS("fixtures/devtools-deps.rda") alldsc <- readRDS("fixtures/descs.rda") mockery::stub(dependent_packages, 'utils::installed.packages', ins) mockery::stub( dependent_packages, 'pkg_desc', function(x) alldsc[[x]] ) mockery::stub( dependent_packages, 'loadedNamespaces', function() ins ) mockery::stub( dependent_packages, 'getNamespaceVersion', function(x) alldsc[[x]]$Version ) mockery::stub( dependent_packages, 'search', function() paste0("package:", dep$package[dep$attached]) ) mockery::stub( dependent_packages, 'getNamespaceInfo', function(x, ...) alldsc[[x]]$Version ) exp <- dep[, setdiff(colnames(dep), c("path", "loadedpath"))] tec <- dependent_packages("devtools", NA) tec <- tec[, setdiff(colnames(tec), c("path", "loadedpath"))] expect_equal(exp, tec) }) test_that("pkg_path_disk", { p1 <- pkg_path_disk(utils::packageDescription("stats")) expect_equal( read.dcf(file.path(p1, "DESCRIPTION"))[, "Package"], c(Package = "stats") ) }) test_that("find_deps", { ins <- readRDS("fixtures/installed.rda") expect_equal( sort_ci(find_deps("devtools", ins)), sort_ci( c("devtools", "callr", "httr", "utils", "tools", "methods", "memoise", "whisker", "digest", "rstudioapi", "jsonlite", "stats", "git2r", "withr", "pkgbuild", "pkgload", "curl", "crayon", "testthat", "BiocInstaller", "Rcpp", "MASS", "rmarkdown", "knitr", "hunspell", "lintr", "bitops", "roxygen2", "evaluate", "rversions", "covr", "gmailr", "processx", "R6", "assertthat", "debugme", "grDevices", "graphics", "mime", "openssl", "desc", "rprojroot", "backports", "praise", "magrittr", "xml2", "BH", "yaml", "htmltools", "caTools", "base64enc", "stringr", "highr", "markdown", "stringi", "rex", "codetools", "stringdist", "xmlparsedata", "lazyeval", "parallel", "brew", "commonmark") ) ) ## An edge case expect_equal( find_deps("foobar", top_dep = character(), rec_dep = character()), "foobar" ) }) test_that("find_deps", { ins <- readRDS("fixtures/installed.rda") expect_equal( find_deps("devtools", ins, top_dep = FALSE), character() ) }) test_that("dep_types", { skip_on_cran() withr::local_options(repos = c(CRAN = "https://cloud.r-project.org")) expect_silent( tools::package_dependencies("sessioninfo", which = dep_types()) ) }) test_that("interpret_dependencies", { skip_on_cran() withr::local_options(repos = c(CRAN = "https://cloud.r-project.org")) expect_silent( tools::package_dependencies( "sessioninfo", which = interpret_dependencies(TRUE)[[1]] ) ) expect_silent( tools::package_dependencies( "sessioninfo", which = interpret_dependencies(TRUE)[[2]] ) ) expect_equal( interpret_dependencies(FALSE), list(character(), character()) ) expect_silent( tools::package_dependencies( "sessioninfo", which = interpret_dependencies(NA)[[1]] ) ) expect_silent( tools::package_dependencies( "sessioninfo", which = interpret_dependencies(NA)[[2]] ) ) expect_equal( interpret_dependencies("Depends"), list("Depends", "Depends") ) }) sessioninfo/tests/testthat/test-diff.R0000644000176200001440000002577614152377737017664 0ustar liggesusers test_that("session_diff", { lines1 <- readLines(test_path("fixtures", "lines1.txt")) lines2 <- readLines(test_path("fixtures", "lines2.txt")) sd <- session_diff(lines1, lines2) expect_equal(sd$old$si, lines1) expect_equal(sd$old$arg, lines1) expect_equal(sd$old$text, lines1) expect_equal(sd$new$si, lines2) expect_equal(sd$new$arg, lines2) expect_equal(sd$new$text, lines2) sd$old$si <- sd$old$arg <- sd$old$text <- NULL sd$new$si <- sd$new$arg <- sd$new$text <- NULL expect_snapshot(class(sd)) expect_snapshot(unclass(sd)) }) test_that("format.session_diff", { # tested via print expect_true(TRUE) }) test_that("print.session_diff", { lines1 <- readLines(test_path("fixtures", "lines1.txt")) lines2 <- readLines(test_path("fixtures", "lines2.txt")) expect_snapshot(print(session_diff(lines1, lines2))) }) test_that("get_session_info 1", { arg <- NULL abort <- function(...) stop("test failure") mockery::stub(get_session_info, "get_session_info_local", abort) mockery::stub(get_session_info, "get_session_info_clipboard", abort) mockery::stub(get_session_info, "get_session_info_url", abort) mockery::stub(get_session_info, "get_session_info_literal", abort) mockery::stub( get_session_info, "get_session_info_local", function(...) arg <<- list(...) ) get_session_info("local", pkgs = "foo") expect_equal(arg, list(pkgs = "foo")) arg <- NULL mockery::stub(get_session_info, "get_session_info_local", abort) mockery::stub( get_session_info, "get_session_info_clipboard", function(...) arg <<- list(...) ) get_session_info("clipboard", pkgs = "foo") expect_equal(arg, list()) arg <- NULL mockery::stub(get_session_info, "get_session_info_clipboard", abort) mockery::stub( get_session_info, "get_session_info_url", function(...) arg <<- list(...) ) get_session_info("https://acme.com", pkgs = "foo") expect_equal(arg, list("https://acme.com")) arg <- NULL mockery::stub(get_session_info, "get_session_info_url", abort) mockery::stub( get_session_info, "get_session_info_literal", function(...) arg <<- list(...) ) get_session_info(c("foo", "bar"), pkgs = "foo") expect_equal(arg, list(c("foo", "bar"))) }) test_that("get_session_info_local", { expect_equal( get_session_info_local()$text, format(session_info()) ) }) test_that("get_session_info_clipboard", { lines <- readLines(test_path("fixtures", "lines1.txt")) mockery::stub(get_session_info_clipboard, "clipboard_read", lines) clp <- get_session_info_clipboard() expect_equal(clp$arg, "") expect_equal( clp$text, get_session_info_literal(lines)$text ) mockery::stub(get_session_info_clipboard, "clipboard_read", "clipboard") expect_equal(get_session_info_clipboard()$text, "clipboard") }) test_that("get_session_info_url", { html <- readLines( gz <- gzfile(test_path("fixtures", "gh.html.gz")), encoding = "UTF-8" ) close(gz) mockery::stub( get_session_info_url, "utils::download.file", function(url, destfile, ...) { writeLines(html, destfile) } ) url <- "https://github.com/r-lib/sessioninfo/issues/6" expect_equal( get_session_info_url(url), find_session_info_in_html(url, html) ) }) test_that("find_session_info_in_html", { # We skip this on old R, because it does not calculate the width # of the emojis properly, and that messes up the output of the # character vector of lines. We also cannot compare the UTF-8 text # on Windows. if (getRversion() < "4.0") skip("Needs R 4.0 at least") skip_on_os("windows") html <- readLines( gz <- gzfile(test_path("fixtures", "gh.html.gz")), encoding = "UTF-8" ) close(gz) url <- "https://github.com/r-lib/sessioninfo/issues/6" expect_snapshot( find_session_info_in_html(url, html)$text ) url2 <- paste0(url, "#issuecomment-937782988") expect_snapshot( find_session_info_in_html(url2, html)$text ) url3 <- paste0(url, "#dfgdfgdfgdfgdfgdfg") expect_equal( find_session_info_in_html(url, html)$text, find_session_info_in_html(url3, html)$text ) html <- html[ !grepl("^(#>)?[ ]*\\[[0-9]\\] ", html) & !grepl("^(#>)?[ ]*[-\u2500]+$", html) ] expect_error( find_session_info_in_html(url, html), "Cannot parse session info" ) re_start <- "[-=\u2500\u2550][ ]Session info[ ]" html <- html[!grepl(re_start, html)] expect_error( find_session_info_in_html(url, html), "Cannot find session info" ) }) test_that("parse_url", { expect_snapshot(parse_url( "https://github.com/r-lib/sessioninfo/issues/6" )) expect_snapshot(parse_url( "https://github.com/r-lib/sessioninfo/issues/6#issuecomment-937772467" )) }) test_that("get_session_info_literal", { si <- session_info() expect_equal( get_session_info_literal(si), list(arg = si, si = si, text = format(si)) ) lines <- format(si) expect_equal( get_session_info_literal(lines), list(arg = lines, si = lines, text = lines) ) col <- paste0("\033[31m", lines, "\033[39m") expect_equal( get_session_info_literal(col), list(arg = col, si = col, text = lines) ) str <- paste0(lines, collapse = "\n") expect_equal( get_session_info_literal(str), list(arg = str, si = str, text = lines) ) ktr <- paste0("#> ", lines) expect_equal( get_session_info_literal(ktr), list(arg = ktr, si = ktr, text = lines) ) ktr2 <- paste0("#> ", lines) expect_equal( get_session_info_literal(ktr2), list(arg = ktr2, si = ktr2, text = lines) ) expect_error( get_session_info_literal(structure(1, class = "foo")), "Could not interpret" ) }) test_that("strsplitx", { expect_equal(strsplitx("", "\n"), list("")) }) test_that("check_session_info", { expect_warning( check_session_info("foo"), "This does not look like" ) expect_silent(check_session_info("- Session info")) expect_silent(check_session_info("= Session info")) expect_silent(check_session_info("\u2500 Session info")) expect_silent(check_session_info("\u2550 Session info")) }) test_that("beginning", { expect_snapshot(beginning("foo\nbar\nfoobar\nnotthis")) expect_snapshot(beginning(c("foo", "bar", "foobar", "notthis"))) expect_snapshot(beginning(strrep("123456789 ", 20))) }) test_that("session_diff_text", { x <- c("", " ", " date 2020-01-01", "foo", "bar", " ", "") y <- c(" date 2010-01-01", "foo", "baz", "") expect_snapshot(print(session_diff_text(x, y))) # if matching packages fails, we still have meaningful output mockery::stub(session_diff_text, "expand_diff_text", function(...) stop()) expect_snapshot(print(session_diff_text(x, y))) }) test_that("diff_drop_empty", { cases <- list( list(character(), character()), list("foo", "foo"), list(c("", "foo"), "foo"), list(c(" ", "", "foo"), "foo"), list(c("", "foo", ""), "foo"), list(c(" ", "", "foo", "", " "), "foo"), list(c("foo", "", " "), "foo") ) for (c in cases) { expect_equal(diff_drop_empty(c[[1]]), c[[2]], info = c[[1]]) } }) test_that("diff_no_date", { x <- c("foo", "date 2000-01-01", "date 2000-01-01") expect_equal(diff_no_date(x), x[-2]) x2 <- c("foo", " date 2000-01-01", "date 2000-01-01") expect_equal(diff_no_date(x2), x2[-2]) x3 <- c("foo", "bar") expect_equal(diff_no_date(x3), x3) }) test_that("diff_min_line", { x <- c("= 3456 ============", "- 345678 -----------", strrep("x", 1000)) x2 <- gsub("=", "\u2550", gsub("-", "\u2500", x)) expect_equal(diff_min_line(x), 19) expect_equal(diff_min_line(x2), 19) expect_equal(diff_min_line(strrep("-", 100)), 80) }) test_that("diff_fix_lines", { x <- c("= 3456 ============", "foo", "- 345678 ----------", "bar") x2 <- gsub("=", "\u2550", gsub("-", "\u2500", x)) exp <- c("= 3456 ===", "foo", "- 345678 -", "bar") exp2 <- gsub("=", "\u2550", gsub("-", "\u2500", exp)) expect_equal(diff_fix_lines(x, 10), exp) expect_equal(diff_fix_lines(x2, 10), exp) withr::local_options(cli.unicode = TRUE) expect_equal(diff_fix_lines(x, 10), exp2) expect_equal(diff_fix_lines(x2, 10), exp2) }) test_that("expand_diff_text", { lines1 <- readLines(test_path("fixtures", "lines1.txt")) lines2 <- readLines(test_path("fixtures", "lines2.txt")) xp1 <- expand_diff_text(lines1, lines2) expect_snapshot(xp1) xp2 <- expand_diff_text(lines2, lines1) expect_equal(xp1$old, xp2$new) expect_equal(xp1$new, xp2$old) expect_equal( expand_diff_text(lines1, "foobar"), list(old = lines1, new = "foobar") ) }) test_that("insert_instead", { cases <- list( list(1:10, 1, 1, 11:15, c(11:15, 2:10)), list(1:10, 1, 3, 11:15, c(11:15, 4:10)), list(1:10, 2, 2, 11:15, c(1, 11:15, 3:10)), list(1:10, 2, 5, 11:15, c(1, 11:15, 6:10)), list(1:10, 5, 10, 11:15, c(1:4, 11:15)), list(1:10, 10, 10, 11:15, c(1:9, 11:15)), list(1:10, 1, 10, 11:15, c(11:15)), list(1, 1, 1, 11:15, c(11:15)), list(1:10, 0, 0, 11:15, c(11:15, 1:10)), list(1:10, 11, 11, 11:15, c(1:10, 11:15)), list(1:10, 2, 1, 11:15, c(1, 11:15, 2:10)) ) for (i in seq_along(cases)) { c <- cases[[i]] expect_equal( insert_instead(c[[1]], c[[2]], c[[3]], c[[4]]), c[[5]], info = i ) } }) test_that("parse_pkgs", { lines <- readLines(test_path("fixtures", "lines4.txt")) pkgs <- parse_pkgs(lines) expect_equal(pkgs$begin, 17) expect_equal(pkgs$end, 40) expect_snapshot(names(pkgs$pkgs)) expect_snapshot(pkgs$pkgs[["!"]]) expect_snapshot(pkgs$pkgs$package) expect_snapshot(pkgs$pkgs) pkgs2 <- parse_pkgs(lines[1:40]) expect_equal(pkgs, pkgs2) expect_null(parse_pkgs("foobar")) }) test_that("parse_pkgs_section", { lines <- readLines(test_path("fixtures", "lines3.txt")) pkgs <- parse_pkgs_section(lines) expect_snapshot(names(pkgs)) expect_snapshot(pkgs[["!"]]) expect_snapshot(pkgs$package) expect_snapshot(pkgs) lines2 <- c( " package * version date (UTC) lib source", " cli 3.0.1.9000 2021-10-11 [1] local", " crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0)", " prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0)", " prompt 1.0.0 2021-03-02 [1] local", " ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0)", " sessioninfo 1.1.1.9000 2021-10-12 [1] local", " withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0)" ) pkgs2 <- parse_pkgs_section(lines2) expect_snapshot(names(pkgs2)) expect_snapshot(pkgs2[["!"]]) expect_snapshot(pkgs2$package) expect_snapshot(pkgs2) }) test_that("find_word_lengths", { cases <- list( list("", numeric()), list(" ", numeric()), list(" ", numeric()), list("x", 2), list(" x", 3), list(" x ", 4), list("foo bar", c(4, 4)), list("foo bar", c(7, 4)), list(" foo", 5), list(" foo bar", c(8, 4)) ) for (c in cases) { expect_equal(find_word_lengths(c[[1]]), c[[2]], info = c[[1]]) } }) test_that("get_symbol_name", { expect_equal(get_symbol_name(as.symbol("x")), "x") expect_equal(get_symbol_name("x"), "x") expect_null(get_symbol_name(call("foo", "bar"))) }) sessioninfo/tests/testthat/test-warnings.R0000644000176200001440000001010514152761134020544 0ustar liggesusers test_that("broken dll", { if (.Platform$OS.type != "windows") { expect_true(TRUE); return() } skip_on_cran() ## To check this, we need a package with a dll. ## We need to install it into some temporary library, and then mess ## up the MD5 sum. We can use testhat itself to do this, as long as it ## has compiled code. We also run package_info() in another process, ## to avoid changing the current one. dir.create(lib <- tempfile()) on.exit(unlink(lib, recursive = TRUE), add = TRUE) file.copy(system.file(package = "testthat"), lib, recursive = TRUE) md5file <- file.path(lib, "testthat", "MD5") if (!file.exists(md5file)) skip("Cannot test broken DLLs") l <- readLines(md5file) dllline <- grep("testthat.dll", l)[1] substr(l[dllline], 2, 5) <- "xxxx" writeLines(l, md5file) pi <- callr::r( function(lib) { library(testthat, lib.loc = lib) sessioninfo::package_info() }, args = list(lib = lib), libpath = c(lib, .libPaths()), timeout = 10) expect_false(pi$md5ok[pi$package == "testthat"]) expect_output(print(pi), "DLL MD5 mismatch, broken installation") }) test_that("loaded & on-disk path mismatch", { skip_on_cran() ## Copy testthat to another library, load it from there, and then ## remove that lib from the library path. dir.create(lib <- tempfile()) on.exit(unlink(lib, recursive = TRUE), add = TRUE) file.copy(system.file(package = "testthat"), lib, recursive = TRUE) pi <- callr::r( function(lib) { library(testthat, lib.loc = lib) .libPaths(.libPaths()[-1]) sessioninfo::package_info() }, args = list(lib = lib), libpath = c(lib, .libPaths()), timeout = 10 ) wh <- which(pi$package == "testthat") expect_false(pi$path[wh] == pi$loadedpath[wh]) expect_output(print(pi), "Loaded and on-disk path mismatch") }) test_that("loaded & on-disk version mismatch", { skip_on_cran() ## Copy testthat to another library and change the version, after ## loading it. dir.create(lib <- tempfile()) on.exit(unlink(lib, recursive = TRUE), add = TRUE) file.copy(system.file(package = "testthat"), lib, recursive = TRUE) pi <- callr::r( function(lib) { library(testthat, lib.loc = lib) desc_file <- file.path(lib, "testthat", "DESCRIPTION") desc <- readLines(desc_file) desc <- sub("^Version:.*$", "Version: 0.0.1", desc) writeLines(desc, desc_file) binary_desc <- file.path(lib, "testthat", "Meta", "package.rds") if (file.exists(binary_desc)) { pkg_desc <- readRDS(binary_desc) desc <- as.list(pkg_desc$DESCRIPTION) desc$Version <- "0.0.1" pkg_desc$DESCRIPTION <- stats::setNames(as.character(desc), names(desc)) saveRDS(pkg_desc, binary_desc) } sessioninfo::package_info() }, args = list(lib = lib), libpath = c(lib, .libPaths()), timeout = 10 ) wh <- which(pi$package == "testthat") expect_false(pi$ondiskversion[wh] == pi$loadedversion[wh]) expect_output(print(pi), "Loaded and on-disk version mismatch") }) test_that("deleted package", { skip_on_cran() foo <- "fsdfgwetdhsdfhq4yqh" dir.create(lib <- tempfile()) on.exit(unlink(lib, recursive = TRUE), add = TRUE) pkgfile <- normalizePath(paste0("fixtures/", foo, "_0.0.0.9000.tar.gz")) install.packages(pkgfile, lib = lib, repos = NULL, type = "source", quiet = TRUE) pis <- callr::r( function(lib, foo) { library(foo, character.only = TRUE, lib.loc = lib) unlink(file.path(lib, foo), recursive = TRUE) list( sessioninfo::session_info(), sessioninfo::session_info(pkgs = foo) ) }, args = list(lib = lib, foo = foo), libpath = c(lib, .libPaths()), timeout = 10, error = "stack" ) expect_true(is.list(pis)) expect_equal(length(pis), 2) for (i in seq_along(pis)) { pi <- pis[[i]]$packages wh <- which(pi$package == foo) expect_equal(pi$ondiskversion[wh], NA_character_) expect_equal(pi$path[wh], NA_character_) expect_equal(pi$date[wh], NA_character_) expect_equal(pi$source[wh], NA_character_) } }) sessioninfo/tests/testthat/test-platform-info.R0000644000176200001440000000170014152377737021506 0ustar liggesusers test_that("platform_info", { pi <- platform_info() expect_equal( names(pi), c("version", "os", "system", "ui", "language", "collate", "ctype", "tz", "date", "pandoc") ) ## This can be a variety of strings, e.g. "R Under development" expect_match(pi$version, "R ") expect_true(is_string(pi$os)) expect_true(is_string(pi$system) && grepl(",", pi$system)) expect_true(is_string(pi$ui)) expect_true(is_string(pi$language)) expect_true(is_string(pi$tz) || identical(pi$tz, NA_character_)) expect_true(is_string(pi$date)) expect_equal(pi$date, as.character(as.Date(pi$date))) }) test_that("print.platform_info", { expect_output(print(platform_info()), "setting[ ]+value") }) test_that("print.platform_info ignores max.print", { pi <- platform_info() withr::local_options(list(max.print = 1)) out <- capture_output(print(pi)) out <- tail(strsplit(out, split = "\r?\n")[[1]], -1) expect_length(out, length(pi)) }) sessioninfo/tests/testthat/test-session-info.R0000644000176200001440000000071514152761134021336 0ustar liggesusers test_that("session_info", { info <- readRDS(paste0("fixtures/devtools-info-", .Platform$OS.type, ".rda")) mockery::stub(session_info, "package_info", pi) si <- session_info() expect_equal(si$platform, platform_info()) expect_equal(si$packages, pi) }) test_that("print.session_info", { si <- session_info() expect_output(print(si), "setting[ ]+value") expect_output(print(si), "package[ ]+\\* version[ ]+date[ ][(]UTC[)][ ]+lib[ ]+source") }) sessioninfo/tests/testthat/_snaps/0000755000176200001440000000000014152377737017116 5ustar liggesuserssessioninfo/tests/testthat/_snaps/diff.md0000644000176200001440000010345314153361644020345 0ustar liggesusers# session_diff Code class(sd) Output [1] "session_diff" "list" --- Code unclass(sd) Output $old $old$name [1] "lines1" $new $new$name [1] "lines2" $diff @@ -14,10 +14,6 @@ - Packages ----------------------------------------------- ! package * version date (UTC) lib source - cli 3.0.1.9000 2021-10-11 [1] local - covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) - crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) - desc 1.4.0.9000 2021-10-04 [1] local diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) @@ -39,9 +35,8 @@ rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) - P sessioninfo * 1.1.1.9000 2021-10-12 [?] local + sessioninfo * 1.1.1 2021-10-12 [?] local testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) - testthatlabs 0.0.0.9000 2021-09-15 [1] local tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) @@ -50,7 +45,5 @@ [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library - - P -- Loaded and on-disk path mismatch. ---------------------------------------------------------- # print.session_diff Code print(session_diff(lines1, lines2)) Output --- lines1 +++ lines2 - Session info ------------------------------------------ hash: squid, supervillain: medium skin tone, ewe setting value version R version 4.1.1 (2021-08-10) os macOS Mojave 10.14.6 system x86_64, darwin17.0 ui X11 language (EN) collate C ctype en_US.UTF-8 tz Europe/Madrid pandoc 2.7.3 @ /usr/local/bin/pandoc - Packages ----------------------------------------------- ! package * version date (UTC) lib source - cli 3.0.1.9000 2021-10-11 [1] local - covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) - crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) - desc 1.4.0.9000 2021-10-04 [1] local diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) glue 1.4.2 2021-10-04 [1] local lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) mockery 0.4.2 2019-09-03 [1] CRAN (R 4.1.0) pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) prompt 1.0.0 2021-03-02 [1] local ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0) rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) - P sessioninfo * 1.1.1.9000 2021-10-12 [?] local + sessioninfo * 1.1.1 2021-10-12 [?] local testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) - testthatlabs 0.0.0.9000 2021-09-15 [1] local tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library - - P -- Loaded and on-disk path mismatch. ---------------------------------------------------------- # find_session_info_in_html Code find_session_info_in_html(url, html)$text Output [1] "─ Session info 🤳🏾 😻 ⚒️ ────────────────────────────────────────────────────────────────────────────" [2] " setting value" [3] " version R version 4.1.1 (2021-08-10)" [4] " os macOS Mojave 10.14.6" [5] " system x86_64, darwin17.0" [6] " ui X11" [7] " language (EN)" [8] " collate en_US.UTF-8" [9] " ctype en_US.UTF-8" [10] " tz Europe/Madrid" [11] " date 2021-10-07" [12] " pandoc 2.7.3 @ /usr/local/bin/pandoc" [13] "" [14] "─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────" [15] " package * version date (UTC) lib source" [16] " cachem 1.0.6 2021-08-19 [1] CRAN (R 4.1.0)" [17] " callr 3.7.0.9000 2021-10-01 [1] Github (r-lib/callr@ea5c3df)" [18] " cli 3.0.1.9000 2021-10-07 [1] Github (r-lib/cli@e9758aa)" [19] " clipr 0.7.1 2020-10-08 [1] CRAN (R 4.1.0)" [20] " commonmark 1.7 2018-12-01 [1] CRAN (R 4.1.0)" [21] " crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0)" [22] " desc 1.4.0.9000 2021-10-04 [1] local" [23] " devtools 2.4.2 2021-06-07 [1] CRAN (R 4.1.0)" [24] " digest 0.6.28 2021-09-23 [1] CRAN (R 4.1.0)" [25] " ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0)" [26] " fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0)" [27] " fastmap 1.1.0 2021-01-25 [1] CRAN (R 4.1.0)" [28] " fs 1.5.0 2020-07-31 [1] CRAN (R 4.1.0)" [29] " glue 1.4.2 2021-10-04 [1] local" [30] " knitr 1.34 2021-09-09 [1] CRAN (R 4.1.0)" [31] " lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0)" [32] " magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0)" [33] " memoise 2.0.0 2021-01-26 [1] CRAN (R 4.1.0)" [34] " pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1)" [35] " pkgbuild 1.2.0 2020-12-15 [1] CRAN (R 4.1.0)" [36] " pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0)" [37] " pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0)" [38] " prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0)" [39] " prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.1.0)" [40] " processx 3.5.2.9000 2021-09-15 [1] local" [41] " prompt 1.0.0 2021-03-02 [1] local" [42] " ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0)" [43] " purrr 0.3.4 2020-04-17 [1] CRAN (R 4.1.0)" [44] " R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0)" [45] " remotes 2.4.0 2021-06-02 [1] CRAN (R 4.1.0)" [46] " rlang 0.99.0.9000 2021-10-07 [1] Github (r-lib/rlang@3ba19df)" [47] " roxygen2 7.1.2 2021-10-04 [1] local" [48] " rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0)" [49] " rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0)" [50] " sessioninfo * 1.1.1.9000 2021-10-05 [?] load_all()" [51] " stringi 1.7.4 2021-08-25 [1] CRAN (R 4.1.0)" [52] " stringr 1.4.0 2019-02-10 [1] CRAN (R 4.1.0)" [53] " testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0)" [54] " tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0)" [55] " usethis 2.0.1 2021-02-10 [1] CRAN (R 4.1.0)" [56] " utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0)" [57] " vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0)" [58] " withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0)" [59] " xfun 0.26 2021-09-14 [1] CRAN (R 4.1.0)" [60] " xml2 1.3.2 2020-04-23 [1] CRAN (R 4.1.0)" [61] "" [62] " [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library" [63] " [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library" --- Code find_session_info_in_html(url2, html)$text Output [1] "- Session info ---------------------------------------------------------------" [2] " setting value " [3] " version R version 4.0.4 (2021-02-15)" [4] " os Windows 10 x64 " [5] " system x86_64, mingw32 " [6] " ui RTerm " [7] " language (EN) " [8] " collate English_United States.1252 " [9] " ctype English_United States.1252 " [10] " tz America/Denver " [11] " date 2021-03-06 " [12] "" [13] "- Packages -------------------------------------------------------------------" [14] " package * version date lib source " [15] " assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.3) " [16] " cli 2.3.0 2021-01-31 [1] CRAN (R 4.0.3) " [17] " colorspace 2.0-0 2020-11-11 [1] CRAN (R 4.0.3) " [18] " crayon 1.4.1 2021-02-08 [1] CRAN (R 4.0.4) " [19] " DBI 1.1.1 2021-01-15 [1] CRAN (R 4.0.3) " [20] " digest 0.6.27 2020-10-24 [1] CRAN (R 4.0.3) " [21] " dplyr * 1.0.5 2021-03-05 [1] standard (@1.0.5)" [22] " ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.3) " [23] " evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.3) " [24] " fs 1.5.0 2020-07-31 [1] CRAN (R 4.0.3) " [25] " generics 0.1.0 2020-10-31 [1] CRAN (R 4.0.3) " [26] " glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.3) " [27] " highr 0.8 2019-03-20 [1] CRAN (R 4.0.3) " [28] " hms 1.0.0 2021-01-13 [1] CRAN (R 4.0.3) " [29] " htmltools 0.5.1.1 2021-01-22 [1] CRAN (R 4.0.3) " [30] " knitr 1.31 2021-01-27 [1] CRAN (R 4.0.3) " [31] " lifecycle 1.0.0 2021-02-15 [1] CRAN (R 4.0.4) " [32] " magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.0.3) " [33] " munsell 0.5.0 2018-06-12 [1] CRAN (R 4.0.3) " [34] " pillar 1.4.7 2020-11-20 [1] CRAN (R 4.0.3) " [35] " pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.3) " [36] " ps 1.5.0 2020-12-05 [1] CRAN (R 4.0.3) " [37] " purrr 0.3.4 2020-04-17 [1] CRAN (R 4.0.3) " [38] " R6 2.5.0 2020-10-28 [1] CRAN (R 4.0.3) " [39] " readr * 1.4.0 2020-10-05 [1] CRAN (R 4.0.3) " [40] " reprex 1.0.0 2021-01-27 [1] CRAN (R 4.0.3) " [41] " rlang 0.4.10 2020-12-30 [1] CRAN (R 4.0.3) " [42] " rmarkdown 2.6 2020-12-14 [1] CRAN (R 4.0.3) " [43] " rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.0.3) " [44] " scales * 1.1.1 2020-05-11 [1] CRAN (R 4.0.3) " [45] " sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.3) " [46] " stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.3) " [47] " stringr 1.4.0 2019-02-10 [1] CRAN (R 4.0.3) " [48] " tibble * 3.0.6 2021-01-29 [1] CRAN (R 4.0.3) " [49] " tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.3) " [50] " vctrs 0.3.6 2020-12-17 [1] CRAN (R 4.0.3) " [51] " withr 2.4.1 2021-01-26 [1] CRAN (R 4.0.3) " [52] " xfun 0.20 2021-01-06 [1] CRAN (R 4.0.3) " [53] " yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.3) " [54] "" [55] "[1] C:/Users/ayip/Documents/R/R-4.0.4/library" # parse_url Code parse_url("https://github.com/r-lib/sessioninfo/issues/6") Output protocol username password host path anchor 1 https github.com /r-lib/sessioninfo/issues/6 --- Code parse_url( "https://github.com/r-lib/sessioninfo/issues/6#issuecomment-937772467") Output protocol username password host path 1 https github.com /r-lib/sessioninfo/issues/6 anchor 1 issuecomment-937772467 # beginning Code beginning("foo\nbar\nfoobar\nnotthis") Output [1] "foo" "bar" "foobar" --- Code beginning(c("foo", "bar", "foobar", "notthis")) Output [1] "foo" "bar" "foobar" --- Code beginning(strrep("123456789 ", 20)) Output [1] "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789" # session_diff_text Code print(session_diff_text(x, y)) Output @@ -1,2 +1,2 @@ foo -bar +baz --- Code print(session_diff_text(x, y)) Output @@ -1,2 +1,2 @@ foo -bar +baz # expand_diff_text Code xp1 Output $old [1] "- Session info ------------------------------------------" [2] " hash: squid, supervillain: medium skin tone, ewe" [3] "" [4] " setting value" [5] " version R version 4.1.1 (2021-08-10)" [6] " os macOS Mojave 10.14.6" [7] " system x86_64, darwin17.0" [8] " ui X11" [9] " language (EN)" [10] " collate C" [11] " ctype en_US.UTF-8" [12] " tz Europe/Madrid" [13] " date 2021-10-12" [14] " pandoc 2.7.3 @ /usr/local/bin/pandoc" [15] "" [16] "- Packages -----------------------------------------------" [17] " ! package * version date (UTC) lib source" [18] " cli 3.0.1.9000 2021-10-11 [1] local" [19] " covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0)" [20] " crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0)" [21] " desc 1.4.0.9000 2021-10-04 [1] local" [22] " diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0)" [23] " ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0)" [24] " evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0)" [25] " fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0)" [26] " glue 1.4.2 2021-10-04 [1] local" [27] " lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0)" [28] " lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0)" [29] " magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0)" [30] " mockery 0.4.2 2019-09-03 [1] CRAN (R 4.1.0)" [31] " pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1)" [32] " pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0)" [33] " pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0)" [34] " prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0)" [35] " prompt 1.0.0 2021-03-02 [1] local" [36] " ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0)" [37] " R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0)" [38] " rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0)" [39] " rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0)" [40] " rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0)" [41] " rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0)" [42] " rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0)" [43] " P sessioninfo * 1.1.1.9000 2021-10-12 [?] local" [44] " testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0)" [45] " testthatlabs 0.0.0.9000 2021-09-15 [1] local" [46] " tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0)" [47] " utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0)" [48] " vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0)" [49] " waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0)" [50] " withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0)" [51] "" [52] " [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library" [53] " [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library" [54] "" [55] " P -- Loaded and on-disk path mismatch." [56] "" [57] "----------------------------------------------------------" $new [1] "- Session info ------------------------------------------" [2] " hash: squid, supervillain: medium skin tone, ewe" [3] "" [4] " setting value" [5] " version R version 4.1.1 (2021-08-10)" [6] " os macOS Mojave 10.14.6" [7] " system x86_64, darwin17.0" [8] " ui X11" [9] " language (EN)" [10] " collate C" [11] " ctype en_US.UTF-8" [12] " tz Europe/Madrid" [13] " date 2021-10-12" [14] " pandoc 2.7.3 @ /usr/local/bin/pandoc" [15] "" [16] "- Packages -----------------------------------------------" [17] " ! package * version date (UTC) lib source" [18] " diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0)" [19] " ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0)" [20] " evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0)" [21] " fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0)" [22] " glue 1.4.2 2021-10-04 [1] local" [23] " lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0)" [24] " lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0)" [25] " magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0)" [26] " mockery 0.4.2 2019-09-03 [1] CRAN (R 4.1.0)" [27] " pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1)" [28] " pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0)" [29] " pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0)" [30] " prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0)" [31] " prompt 1.0.0 2021-03-02 [1] local" [32] " ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0)" [33] " R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0)" [34] " rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0)" [35] " rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0)" [36] " rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0)" [37] " rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0)" [38] " rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0)" [39] " sessioninfo * 1.1.1 2021-10-12 [?] local" [40] " testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0)" [41] " tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0)" [42] " utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0)" [43] " vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0)" [44] " waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0)" [45] " withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0)" [46] "" [47] " [1] /Users/gaborcsardi/Library/R/x86_64/4.1/library" [48] " [2] /Library/Frameworks/R.framework/Versions/4.1/Resources/library" [49] "" [50] "----------------------------------------------------------" # parse_pkgs Code names(pkgs$pkgs) Output [1] "!" "package" "*" "version" "date (UTC)" [6] "lib" "source" --- Code pkgs$pkgs[["!"]] Output [1] "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "P" [20] "" "" "" "" --- Code pkgs$pkgs$package Output [1] "cli" "covr" "crayon" "desc" "evaluate" [6] "glue" "lazyeval" "lifecycle" "magrittr" "pkgload" [11] "prettycode" "prompt" "ps" "R6" "rex" [16] "rlang" "rprojroot" "rstudioapi" "sessioninfo" "testthat" [21] "testthatlabs" "waldo" "withr" --- Code pkgs$pkgs Output ! package * version date (UTC) lib source 1 cli 3.0.1.9000 2021-10-11 [1] local 2 covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) 3 crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) 4 desc 1.4.0.9000 2021-10-04 [1] local 5 evaluate 0.14 2019-05-28 [1] CRAN (R 4.1.0) 6 glue 1.4.2 2021-10-04 [1] local 7 lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) 8 lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) 9 magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) 10 pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) 11 prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) 12 prompt 1.0.0 2021-03-02 [1] local 13 ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) 14 R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) 15 rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) 16 rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) 17 rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) 18 rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) 19 P sessioninfo * 1.1.1.9000 2021-10-12 [?] local 20 testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) 21 testthatlabs 0.0.0.9000 2021-09-15 [1] local 22 waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) 23 withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) # parse_pkgs_section Code names(pkgs) Output [1] "!" "package" "*" "version" "date (UTC)" [6] "lib" "source" --- Code pkgs[["!"]] Output [1] "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" [20] "" "" "" "" "P" "" "" "" "" "" "" "" --- Code pkgs$package Output [1] "cli" "covr" "crayon" "desc" "diffobj" [6] "ellipsis" "fansi" "glue" "lazyeval" "lifecycle" [11] "magrittr" "pillar" "pkgconfig" "pkgload" "prettycode" [16] "prompt" "ps" "R6" "rematch2" "rex" [21] "rlang" "rprojroot" "rstudioapi" "sessioninfo" "testthat" [26] "testthatlabs" "tibble" "utf8" "vctrs" "waldo" [31] "withr" --- Code pkgs Output ! package * version date (UTC) lib source 1 cli 3.0.1.9000 2021-10-11 [1] local 2 covr 3.5.1 2020-09-16 [1] CRAN (R 4.1.0) 3 crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) 4 desc 1.4.0.9000 2021-10-04 [1] local 5 diffobj 0.3.4 2021-03-22 [1] CRAN (R 4.1.0) 6 ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.1.0) 7 fansi 0.5.0 2021-05-25 [1] CRAN (R 4.1.0) 8 glue 1.4.2 2021-10-04 [1] local 9 lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.1.0) 10 lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.1.0) 11 magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.1.0) 12 pillar 1.6.3 2021-09-26 [1] CRAN (R 4.1.1) 13 pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.1.0) 14 pkgload 1.2.2 2021-09-11 [1] CRAN (R 4.1.0) 15 prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) 16 prompt 1.0.0 2021-03-02 [1] local 17 ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) 18 R6 2.5.1 2021-08-19 [1] CRAN (R 4.1.0) 19 rematch2 2.1.2 2020-05-01 [1] CRAN (R 4.1.0) 20 rex 1.2.0 2020-04-21 [1] CRAN (R 4.1.0) 21 rlang 0.4.11 2021-04-30 [1] CRAN (R 4.1.0) 22 rprojroot 2.0.2 2020-11-15 [1] CRAN (R 4.1.0) 23 rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.1.0) 24 P sessioninfo * 1.1.1.9000 2021-10-07 [?] local 25 testthat * 3.0.4 2021-07-01 [1] CRAN (R 4.1.0) 26 testthatlabs 0.0.0.9000 2021-09-15 [1] local 27 tibble 3.1.4 2021-08-25 [1] CRAN (R 4.1.0) 28 utf8 1.2.2 2021-07-24 [1] CRAN (R 4.1.0) 29 vctrs 0.3.8 2021-04-29 [1] CRAN (R 4.1.0) 30 waldo 0.3.1 2021-09-14 [1] CRAN (R 4.1.0) 31 withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) --- Code names(pkgs2) Output [1] "package" "*" "version" "date (UTC)" "lib" [6] "source" --- Code pkgs2[["!"]] Output NULL --- Code pkgs2$package Output [1] "cli" "crayon" "prettycode" "prompt" "ps" [6] "sessioninfo" "withr" --- Code pkgs2 Output package * version date (UTC) lib source 1 cli 3.0.1.9000 2021-10-11 [1] local 2 crayon 1.4.1 2021-02-08 [1] CRAN (R 4.1.0) 3 prettycode 1.1.0 2019-12-16 [1] CRAN (R 4.1.0) 4 prompt 1.0.0 2021-03-02 [1] local 5 ps 1.6.0 2021-02-28 [1] CRAN (R 4.1.0) 6 sessioninfo 1.1.1.9000 2021-10-12 [1] local 7 withr 2.4.2 2021-04-18 [1] CRAN (R 4.1.0) sessioninfo/tests/testthat/test-loaded-packages.R0000644000176200001440000000060714152377737021742 0ustar liggesusers test_that("loaded_packages", { lp <- loaded_packages() expect_equal(sort_ci(lp$package), sort_ci(loadedNamespaces())) expect_identical( gsub("-", ".", lp$loadedversion), unlist(lapply(lp$package, function(x) as.character(packageVersion(x)))) ) expect_true(all(file.exists(lp$path))) expect_equal( paste0("package:", lp$package) %in% search(), lp$attached ) }) sessioninfo/tests/testthat/test-utils.R0000644000176200001440000000041214152377737020070 0ustar liggesusers test_that("sort_ci", { expect_equal( sort_ci(c("ant", "\u00a0nt", "bottom")), c("ant", "bottom", "\u00a0nt") ) }) test_that("order_by_name", { expect_equal(order_by_name(list()), list()) expect_error(order_by_name(c("foo", "bar")), "no names") }) sessioninfo/tests/testthat/test-printing.R0000644000176200001440000000023314152377737020563 0ustar liggesusers test_that("rule", { expect_match( withr::with_options(list(width = 20), rule("test", pad = "-")), "- test -----------", fixed = TRUE ) }) sessioninfo/tests/testthat/test-package-info.R0000644000176200001440000000655114152770761021260 0ustar liggesusers test_that("package_info, loaded", { descs <- readRDS("fixtures/devtools-deps.rda") alldsc <- readRDS("fixtures/descs.rda") exp <- readRDS(paste0("fixtures/devtools-info-", .Platform$OS.type, ".rda")) mockery::stub(package_info, "loaded_packages", descs) mockery::stub( package_info, "pkg_desc", function(x, ...) alldsc[[x]] ) mockery::stub(package_info, "pkg_lib_paths", levels(exp$library)) pi <- package_info() expect_identical(pi, exp) }) test_that("package_info, dependent", { descs <- readRDS("fixtures/devtools-deps.rda") alldsc <- readRDS("fixtures/descs.rda") exp <- readRDS(paste0("fixtures/devtools-info-", .Platform$OS.type, ".rda")) mockery::stub(package_info, "dependent_packages", descs) mockery::stub( package_info, "pkg_desc", function(x, ...) alldsc[[x]] ) mockery::stub(package_info, "pkg_lib_paths", levels(exp$library)) pi <- package_info("devtools") expect_identical(pi, exp) }) test_that("pkg_date", { crayon <- readRDS("fixtures/descs.rda")$crayon expect_equal(pkg_date(crayon), "2016-06-28") crayon$`Date/Publication` <- NULL expect_equal(pkg_date(crayon), "2016-06-29") crayon$`Built` <- NULL expect_identical(pkg_date(crayon), NA_character_) }) test_that("pkg_source", { descs <- readRDS("fixtures/descs.rda") expect_identical( pkg_source(descs$debugme), "Github (gaborcsardi/debugme@df8295a75f8e26bec90386beb1c82b529427029f)" ) expect_identical(pkg_source(descs$curl), "CRAN (R 3.3.3)") biobase <- readRDS("fixtures/biobase.rda") expect_identical(pkg_source(biobase), "Bioconductor") memoise <- readRDS("fixtures/memoise.rda") expect_identical(pkg_source(memoise), "CRAN (R 3.3.3)") }) test_that("pkg_source edge case, remote repo, but no RemoteSha", { desc <- readRDS("fixtures/no-sha.rda") expect_identical(pkg_source(desc), "github (r-pkgs/desc)") }) test_that("pkg_source edge case, remote repo, no RemoteRepo", { desc <- readRDS("fixtures/no-remote-repo.rda") expect_identical(pkg_source(desc), "github") }) test_that("pkg_md5_stored", { md5 <- pkg_md5_stored("fixtures") exp <- c(`libs/i386/fansi.dll` = "7b96ab4bf019b0cfed86425634d640e8", `libs/x64/fansi.dll` = "6503170d698e5a7916bf2457edc5de8d") expect_identical(md5, exp) }) test_that("pkg_md5_disk", { dir.create(tmp <- tempfile()) on.exit(unlink(tmp, recursive = TRUE), add = TRUE) dir.create(file.path(tmp, "libs")) dir.create(file.path(tmp, "libs", "i386")) dir.create(file.path(tmp, "libs", "x64")) writeBin(charToRaw("foo\n"), con = file.path(tmp, "libs", "i386", "foo.dll")) writeBin(charToRaw("bar\n"), con = file.path(tmp, "libs", "x64", "foo.dll")) md5 <- pkg_md5_disk(tmp) exp <- c(`libs/i386/foo.dll` = "d3b07384d113edec49eaa6238ad5ff00", `libs/x64/foo.dll` = "c157a79031e1c40f85931829bc5fc552") expect_identical(md5,exp) }) test_that("print.packages_info", { info <- readRDS(paste0("fixtures/devtools-info-", .Platform$OS.type, ".rda")) expect_output( print(info), "package * version date (UTC) lib source", fixed = TRUE ) }) test_that("print.packages_info ignores max.print", { info <- readRDS(paste0("fixtures/devtools-info-", .Platform$OS.type, ".rda")) withr::local_options(list(max.print = 1)) out <- capture_output(print(info)) out <- tail(strsplit(out, split = "\r?\n")[[1]], -1) expect_length(out, nrow(info) + 3) }) sessioninfo/tests/testthat.R0000644000176200001440000000010214152377737015747 0ustar liggesuserslibrary(testthat) library(sessioninfo) test_check("sessioninfo") sessioninfo/R/0000755000176200001440000000000014153361604013015 5ustar liggesuserssessioninfo/R/sysdata.rda0000644000176200001440000016302214152377737015176 0ustar liggesusersBZh91AY&SY\e (>a}@2x:.p05@ t:|Ah_h7`T ^JRsڡ0Sui 4CJ}>"U(pouwwog (oӓﳣzNjO톛KJ0:vR3s**u}}oJ" ^ Ű@3i(u*f|Ժ)O0׽x ޳ݛ^9>[@,xBpkfP-2 &HBЯ isTu݈Ԏwm/wvm@ EFAuZ{=UC%H{Zb.ѽ}6h{Kc[ۜg6Xo}}M=Q}P]>(G3l*>{ot`}kxݬM=vB=3'O@@4d#FATb M42iMOLe6hCRx&Q&Ghz LQLS=)&&D M=MI)mMH 2=#@=@I$ JO*~=Ȓ~꧴LMSC@4ѦS@44@CMz Pi4 (M$D!0c"MSbM5?jޔzI♤cSz $"Si4ha'OB'=OQF L A@ 4h44i4i"iOFCSLS=S5m|{&ܞw}/7K+vίuЏ]ZTg;.ϴ}k'=7s{? ~Ǽ>>G?x~׋G\';7- }Dz彧COMm?|'ߟ~v_{7]O}l>?g?}Wv9]Ϗ<]j?~;/O;COFsSuc>[{xw{r\/sSt|~_ϩq"z7OGO-ϱ/ //?g>s|_V!G{x?}_>o~ߓ|>w|_߳x u?oOί_?|n;Oo-_#}v{gM~C}5U?^[?pu|n~<#>+_#~^>|Oc|?WxrվzOWzeW뿳GuwyϘw\ >sov7?_`~tn]BzD$Lz#,]z_”=vAxì21-4wZFǭ9Wx^z%u]טaaapi-񿯻='#7bŮ˳ahhʒI$i#88hEh3V*SmBjni֩q4MKU[mU]m3E/2QM,UucI*LK,qYS*(`zGye}^RHYK,O$ Gq8cuM$qqEQE0ʔqeڛGbjj|@oꔫ߃]+8r.Ix1~ּ?r|=>}`|?Z`8@{@b?=΀}@_o{8γ3?\޾޾5/^?=|ѯ־oWWWW|0?|<@>> >h= J_'>{?>y_e-ՃPآ(׫qG 0 0)JR)JR)JR)JR)JR)JR)JR)JR)Jb(aaaaR)JR)JR)JR)JR)JR)JR)JR)JRw{UH܁Qs?؀U}gzM*Lv@o3=Xsri-]1|f8{Bh]m|饧ahcfiՓHTP E4ÞFi=:8Hh 詏뙞z21c{nLG0ůI{n;?=0D797Tt}15dV=]%cR4hfPV4x<4/nf(VgDt)tmu n6~J_w曾nIH~d a 3qI)K,i{gxn*0Dj$zr63}AJ!L$GuIQ@H2S峃`Mvg=YƑ:2Q%okr +C+W*nέؚi;LfK]9.VslnNEǢtӝ{_eTxNʦBDt b1eF c'D57@6,8d7ByӆF6ߛ5}2sYVTz'?%FrZLA8oeo /Kʲpެ09aC0I yDYV,%|x4qgd02;f_@ᘑdUBN(uIQT0LHv`Q(^TH;AMct uތf%z@Y] ;UR\.E]$G?gP$ Z!l; @z"eN/p!_^crƩGsW .O䀘c|X q7x]!cfm䉻Xu?8Iﶹޕo`ёL==ǣCvYSf3Ӈg|ܐZ$쳮YpSɊ!H!scLK"wڸc3©SEZIƷ0]"L- 㜼2e|s>.Κv:iHψLb\ҧH%38fA&=%}krpo B}J<*(ьh)3&qÊY02ˍQG0I h c4ֻ/Oic dBvw4 &X1;7eu? M֮}{U2DeP+u^ڌ11"f AڢJeSѮakC1]xP; /zllk΀E4LSm!6rnU"mڑgC%B`y5LSI7ɨC!!JÅiѠPe6ҡ\Nj=!.k8ގj) RhV+?8fCSC5l1t4! o躏xs NV&&aZfqk!O/_K$P>m+v8AkU+a`j^Qyzm>4t*kg )xX^sxTn KJp:+׆=ك^3w[F݄ X><~,unolw^ׁVI07ߋ#?]_+^l4~~߶ϻ(b + JRB@XB "O )BPDI,@0 H Id@ψǪoVqW_*ўQzF'q60BٮV ,Vpf[no]źk f񭿼 I@~=" 꼫q@{}/{$nŒII0b$ Y$$1d`,LŒIgګjUSuIEPWa*^ZָY$$1d` Y$b I0I&a1e{se5Sʥ (P$"$,0%1cJ# UQ25RZ,dIJ$$ 0d"F}9?uTq5ym|v?e,qW jM<bWz1norK>Cv![V^X]_c=Rݏg#}>^ƯʁOee]&FFFF69 Oeu%h`گ՝=:fO * lŪVׯ^αyV!qXyƍ[ H7wmmk𹙽c*&䦪T4`Q3Ѐۦ롦 Z՟Zyy:s9s|9s9os9s|9s9os9s|9s9os9s|9s9os9sTT$R""f{&flG6a/M3~^f1UUUUAWH ۢ|/~}&_szr]/[s}~so{3gdrz_'c'\?Gkh{|ϳ׻7O7_1>'>ϵGk.S?O?ݺ=~O;ZOS|t}7oa~O}+sa?Wsgfemmm5$cSx#_u{>@TcOƜ5W*k!ԲVuylfa_@scU]<מD8(EԴQAD@UK[!P,H(r6Ò:߬]iyfD󋊕g.+ѽ:7 $h`h~O__>}_dGdQ0nXFُHpQ@dr4ˤӃpy.k(;S* )o y3p(;;~.3qBt~RQ0<0$qt_]qἵևvu_X1kZ;2]˱&0U(9Ҥ;Fʚj1 WL݌|"ZK>iw:9c!$vc}D˜"/_ 13$S8RDaNn=OYu*v 2`)OxSKR?ohHEX+D|N兽CЄ p~i~[>{g<1׽0u׋ ӣh}}Tܙ{sGo~eɁ?} V'k$hW6 "7n{{l%۽`aP>ΧT͎(Y ;fY#ysA9Ek{z妞-gΎmlw",ݴc ޲'F06 /^e 4sy!UGrz{R 6wX[K~h~lag[J}qsa:5Z5m>sy.s4|Ox8?"x-ssN cbMWO޵wnR*gV-*ۼ:OuH0,.44`m36uHdJa}@}> VÄ y \E7N$7uqGns75}ZIJgZ[>6wcXKw0ѦRno;"""#7̗;r,z%9LyiJ6xV[`VPW\mZֵ_{=c:j7\ 1}.d@寪2ZMiп94$B(񱔌nw۳p3X䃍WPquZa0| ]o(sDщ2 ZZqo{yw~H߃߆|R?~>,͖aHsv36J66=mu s kU__%{twKz+cɵZ :U:'AB 8d=# ~۲[>{ƽzΰgۿF2-Q׺=oH&c ?f~Z-k{N% H#wۖ2 U ǡE/~ƒHx{Ȁ "q|%Eu૲~e7K_G9^#{"{x>R=KR7>mȐ_x1=J$4+RSniL LW3CfPU=c*-o+g-S6 8Zɟ\{DA!)vͦYsNFOoLMԲgs`CzEB%"+R3#YUP96XRl cvh6RB>sdǔ[[ϸߖpznF=2I¦5ΓzW2*+ vpOj-L`j3|}=&H2 XS {y9COUƏӵX':Ƭ.=Ҿ+C6}Š'c|jB-A0o[;\jicȾ ֿ{|_7 1hDt4ׁ9ȯv;`E v|Oa=xlXeDzSTOTvD=[`po}Ms87abNZX~樾605un7^3>%}=@*6˛( )݅w&lyg¢D|&,g+):K<y۪egAfN3&O/1,yM۹}"8N-߶WǦA3";TzRt"&{R뭸ާ^|m+7V];_=8|#g+zT诉Iy6'aʏyc{V es-W~oL_[||D̞*%{>ѧ?lFxh^k'{VuyNu|N-13<I`i.K-x.20˿CK螽];_'nfԐ+{ʛi:؍^p_>|OR= V6m떝oUşg̶~k~shGo}j؋[jٖ]6~~r7ٙ@&C=" l ;p9vo8*@o VڅՇAwM"M^^@ :VmR}G: 2fEYYLȀczV>oyğ~쩎޾. RO)"k ; h'}7psTX#ޒny τE5ơϯsi\"ѵQobkmyT?T È򚉻Xlbm>??H6&{Ylh~4XĘ(T4XhU>~1W08=*: BaAӭ^p~wuԑ9d4;O~MŘ{a>-d? fx:HQn>eX>zWDPW/i'̉ Rg"/?P+o3'.=gGkeKﴇYqa,?oIMl3`)܄xCGElNؾ8}hw.wD2?A)gՠyKxNO''7x:~3׎yc/]gzXʴF5t*MXNSC32Uvf]u]xȁ--Π4l2;$BhC]}#AgӬ08uw/?Z1gk/TvH]r`dc=/tk }V֬`"Ԣ75 zq)ݬr"Ό: J m|*o1eϽܯF<ĝy"nvٌ= D1fC-u'Ƕٵunje |att6Kmx;Oї_=zߞf#39suZֿW|1;&qu&k ű[kg9/cq}&"7Z֘ZEmWYKj޵k[Zfcyf'-琎oZֵx7ֵje-l>|Nώ}t`vuu4۷Mvm0ۦiM0`p  6tݴ{ tXh@vnm@9vvvvvsM vl@vnuh:Ybz\K. b`t9yH hGG0doMٸ-+l p0B^~^0j?J쟆/+as2Qq|-KW<j.wtGT=Uk6m1w~cuZV~lk*`d9O_Ot|{ ?΃~? {Ve-l xC2SeCvbD@o-1zܬ;fʠ( 'F_U?\r`(1l+2Ú l;)ܤw?⧥)7˶maRQ- #G9[ߨ|/̕^?1ۖ" YǤ<CeoD؊6_oa597O !9ш=m,vyfr"mGCFòacIgb+]j)+c0!-{mmr*دY9$yFDDDH@`ٱ|қih:[ꑍi=.J]MG 5ڨ*뇔qKk}[/Jf6%pjx"XhB;~O3_tc ;"^_f Oo}>}{vYrM *I"GpҐ~=fNyz]2f- ̣BQd= [SBr(ejc"@CXׇ-o]=ptPðO\a_P0L ~f`CH'4 aӮpfFC9 )rn14C s:4q=FXb@n˘`{Q-\{{8[Yxz l=EܢK.-.38jcx0kw`܈q ^( &t)W7-UvdڠDCғ*lw3)`xRnhp#m{۫~o?7~cW1{ήwU^ss\z;\W:ގW1{ήwU^ss\z;\W:ގW1{ήwW~!#! ~^~FMmߒb.)nfdF`tniO7ӡPB&N&8yYcD `jY6'$UcO2;Qz3d'Zhq]d X̟_~x[Rϡsb!6kߍΚ} CZT3yЪ!r ZMњC|UIU]8hf\>+_;]^Dy/[N'WSJүAYrVs@|]zqM^N^'o%cN3ǂUykxc֞-xjӠ+޿?ǶK_Qtf.__k~n]U^ SpeXb%GLҊwoaK6#Pu =!f oiUቼ! ),Jx=T ZҨ|Oq(PZM ,(ΜEH`UM$TG=BAD`tÝҢɔ*~+eCBJC̲j9G7vo=uׯT=-%jx'gb+蔜(5 eLUUQUZ5W'Y&$1d`,LŒII0I&u[WTꪛY+[EPW2J9:oI&b$ Y$$ Y$b I0I&b$ ,LŒIec^ 2莹喵>,Et4k֠ uI$H{7|sV ._WL_?;CGOMkO) ˻[;jg{N1Vl疼sn|s;M{nm"7%6Fyu\N1.vϞr۝5[mmm\9,as [Cɂ1)DtO<2UkvϢTs{=jkGt4#ϝe cHHfŚh %6ײCrj򀻄M~MKMW$kHj&&0=osC:oRA)O"N cji{'a;9Ӻm2WyL|A{ F N8TUm1RGq &mʕoT}' oN 5塏-,u_!Qu)#S}I|[cvOwUX1OU/?F?8Jd/..)܉3{$&gkdv:3)-.u=o&XbwdLVCuuiBaUW ꞅK/a'N B 3L&VMӕup+\T59H.jfpr:DžV*"jn Wi߯-[3][N %UQN;xNY:<\{u .BlDp7b`<ˁe$BPJ1L ܞEa׉= G$Т(UvWL̶s3-nfZu\+???'<1QKeǼsYlCc+ፒ ?3 XD9V@`oWr!UʏCgy?D[T[ADD}*;Zֱޡ^UZ߰  33333:kX"*;v{'bzM""{AJm DH$E"`B!  E"T`2 $B0$2$hf !P i($, `2X!QUm'ƬDIH, `X$ +!Pə `\OkU~?۷hila?LɖgY8^Ru0yw;`EQMX, `A 0X,$`"@ C0B0 `@1 $PX,`X,0dIH@`, Al   `X,BDX# `X1$ID$HYQyz\-oVmg5/Ŭ36J%D/<5{A&|1_# ?s9z\O_EUUUU_ߗ{Y^wIDd d VݔQ}|0<,KB׬Z(0H2aYD9#p?vO,0%T# UQ:qL ӎB7`n 4K*xӯ=MkZ"sҨ2N5O&ZZ!dQ#/+'++..,Bq %%⹍r2g*:`yŜ{泋bi4V,> ƍ-mmm`q}{Y߇*% uy` :\@(M[Jsr !c3 s2 dNZmh ջ(j3!GV Z&E2 f@""LI2"w}m4r Yz8=N/|6m}( UT*TSC71@hEl9!-/khnz"k kz5\UQBfUG{ mɨ. Ejrݗ뮞m.[-N7D\C330fU<{yxs;UE ׯ^z!II!*I kJI$I(u1kl)zVyt(2_".dAr]]{ɄŮMZIKٷ|okIckW$ٳKԣf5`P4zIi]uy]^7/#{`=Oz.8yYLu ^!GTԕ ˢ&? uv>V/4x?99y:heI;&Bn"'kKedžnɅag )4:1HV'(<3N Z%dvoKZ;UB!L3(DNBe;} ؉xӬ YZW3N ۶D][֩`+fRì>BandW:%y}:nSݴJ&:ޖWi K4U(DNBedžn t$h )4:1HV'(<3N ۶D][TqfCPBAvo_k\8,Mwm\>zٖ1vrx59_+O?*|-ݱEs2D⢣TQxۿQN:t$I$I$KΙyU+}iAu]vݵw|[;}}lBw_n2*[߇Ӿg<>ZKA8UWBJY8d"ׯ2Pyq:N.jͷbYYۗwF۷yp١UTUa8Hy $g<(YTyƛek]Z-ko_^m-%%(KNɲ洪kNfa2Վd"&fTޚ/ʪB-B^>>>>aۼU\+O_4W:ơiLf9*I1'RI>B'h){߿ ̷̷̷6\8ZZG>]kn8؞5#XL0U{f8\pL|>QUQ!nUc(?Ũ$Eb&fFffg]3֢1VfUunZms{Ы tk_N A`ȉSDژFD҈[){^ZusM\@pIKNό뾢WSv;ƴMhvvڙ̤Ki-f332W<֬f =ѿXW^)N+M3&7*)l鱋$ 33 y$_j= sL=i]+ovR6VêT>Vufuz0<^c ||H H1 vF!RLB)*R (p($@ `'duy;c$\GBА@* x^3F "ޕŁ/T@7,6 1`W] 1%^2(DE7#x^* $`yϹEW@`f|bUsʯGBq|{mDUUBI?릚L#8ة;^|J Yp7ñGUUGu@tf 6,0NX@#dJhBKTtϫ;cmuO@R]{ HH*>gӓOWyX0W:q8ETQ<&oWW.UUS8'0̒6wbUUSo5mb~OcUUrAg(HbNS604A XNgV 3$7ʇWM\s7\[:x.oqQ 7481 ѭ^M9y q{K1s<4<6CT6p #D)`c-2lЊ<W.!A t,P&G*Xfql####=bFZrx:ʹI#P,hd hCk09|][jmmڍ^)oo[u/)ec#$r^KS|[A6{}$]l0g I0z"b̂%J@ Tf$ѣ,*S(d1V{&|Qr^*$Q'fZv#1''\̞tKR&L;s\l*~7S r̡̞̂,;8S8)4lE%TdJ;/ VMZPffb""x˯Oaz'흷T:Z>عj!2[nni; [ϫ'uj-.bVcp1,5ڛow~6"m^4lVW'eDlkUv`ijE\]„Dp,:6Dan/{b&N6ei^lfN['/n%dvoKZyPC1fiPYțL- =3HP ҬA"YX 8D'/n%dvoKZh zS;-NR|y555M%F27w4y*U;:<#偘AhxB#iJ @%n'A;.h-j%8qaÐ &-Zx`:+ (d0K`(J SdV2sNfEuW0"1Y ٥C@]$CnNιI;u# TU`}`֥VDmثKlQX,UQYJ[JJՕFVV)m-TJZTYDYijڃjZ`P 5[ZQ[hF`- ZȱDV-EDڊ65AY#FZR*1R$Z֫UBVjçNxz.مQUV߱d3W=2\X[U݊J Aɶ3QbmP޳9MgKc3 tAIFM/ s&BAn)8߯}44QE7D|pH!mD2͔.l`̈˓+91"i9Tyq^I'ֵXkRy_.8Mf`+UJjg9mks3-mmm{*?'wJ֞CH~T& LZ+VaEncQ@یSTb>|qI ҷXw7-ڮS+6C1vyW`ڠE :utauyY'ӆb QY0f]Q0-KgbxB"I fiu(0F#[)r*idk%Nlh ̉S?hm 8CFaѭlB,c-dUI}_)gE: Heu]22/I hz!$;!+j XB,W #ǹZfJ(yOх 3 s@kP$ 3Jl)~< ȸy{kB;˕{*!x[|S:~וGf'ޗiz6:un&wU NG)$$B#'!PEa!QqQ1^3y[ +,2:t0װ'C:UUչj,(5,C-.N6@$.4vL0&?մ3g ekRZԺI< ;N9pDWTY1Rl=yRH @H X\)T('Cmފ-kD$*T Kވ$Ŭ;l䶃?1ṟ?a,$4!/7Fb&X=g0nb*kX.T̀ H9vL[FeZbr;&d3WYs)ӛ.oXqOT//sojBN]wH2UV$= =HzwNҠBdP6h@tm A@Y\,38ԓteb p 0Zu~/Na?5}&_ ~ťW<3&˧ޡ;Aq n֦~YyN& h+%ր=~Io1I?MOB r#|4'oGw@mƛ DBqx2Ij2 eKAFV"(s$"MaPynOk`qwJ| na`pze) oBX(DT A>$"H`@40BX YRV3I! f=-dX *8.)"gCd 7#I\o/iކPfIash{ɴmW|U9`k:x<ѧ|Ձm@ CNγ]i#y!vBR|D@(+.W3? Rֵd <)tJNG?@@$C+tBCtCL/yNT81&ȇ˔ARyC4>yl~s|TX5(hV25zc{)Mg9ݽx7XÎ-y,eCy!bFkSI"i`?l/tl2!]=M=n΀qũN'&fjjbq ܔHpZ6D!N%yN" zr>ktv["Y-GB`@ B;g~0gʣԯW7<}$8dBYB龒*HI$C`|~*v:[ deǙ*TGS]^e>GܔPBVF2@_H/d9?úГGB a+0axP!EIW}~Y»_ņ]asNYD”:{m[|е-*LxZQ!eh$y=>3g6vOFji ޵sBU6sWjS,TCwL9XJxX3;'u#l8ʭsb'ILxq@wUKw.~ëbX!wQoXb͚dK04ay4T4쟌{MN'`4g偲}'{=1ێNO09O%Є!Cw$Y9zk>Uއ!x:d K5<>9>/M>Z'-u>nC p݇ 50/ 9sb0jHb5Km :=|zjFlJh_ _ gG__/yǙw5}_jt[d*Iy?ְa2='N4̺˻Yw)}U&cK6X쟤=9p#sƆh~ΡfTsˮ^NU;42>}qe^umw.[x1ЯRfki 顲hO5L_4&vwa 996tƟbJRfMcs[9T4剰`3jđ(=\5fv;Og2pN;yN[4ҋBZTqi60qh'SBwqȎ쏬Y7N{m&؞llj792"c+VI^2B_;0gL5ddpHw_JpЩlzr^&~nTw4|a[cNC (.GW%aHPl@fQ&^]2=&lyϊBQ 6lX<8ՖXѐ350\Qӿ<,s:z!FځCY}wceϝCItX9}>`tCɭV9IU a'|m̩ vk{ߍǜdR5EcT E $Mo| Qa$|E*}Wzh2#( ,|Qm{( @;=*/;US+^iiWY|>Ll[y_Wp˯fw\cb9cs~, !epaN-oΦ%UZRAPOy?t7Өˉm10kUV7?cm> N+i?y]NR_d FҾT<2yw[)3@D>~, )@AXk U@R,XAhkDV "IUҕ!\Lpϓ&i)XJQ%B$dcl \D_^cr顰U0`^9b5TKXqqMYSK6&Ph)F-4z*E07ig ni0]O3}8=KJ󐟟~X_Z/ur`v6<;iEAMNgHap\k14o%B Gw{N_+8~cF-׮v{!>ǝ`8x=vj+G#Gv8N;qulCabsnay+хC`&^EQrj8wc&?g+¯E^oc];! %[5uի6i.,Z m A(ĵ|Hbe03+'c㕽/Ă بN5kBN ӥ.d7unc$:;[>NVI~0%!BGv$ U,Y}O{|$$:^xHw=ő>m_Qvt;ŌKeS8P2Չ'__翦|/cVlx2Js@ӐƺUNwuoN<"-UCݑ^ۦ:U2qQZ6.1-Y5\773{ K`X&N9xxz*6,J2YH֪g.8,7S{7qaӝI88]jL7Mc%N9a2+5fNc$2k3.@78C,9$2@[Kӌцڢ f:L4Jo7F8jk 1 K@0`" pzm )DP4D0D3P L(pL$B$ 43)1fa1f1=n X8--i*A&0"+Behe&1 l3 s0[j,yuMlmS oy{Q$XwɩSa!?E $QEAeͅ/R먆o>sא]q6' _a~B$!dپYC]HԴIbGo:WQ9ѦYƵ)QpߔEcgd@&|;Wj߂v\%UUˍ CCs"544-t5T%[WhE(-; * ]*YsPĀj0)A(ΈiMz 2NXE;! F mTZ{,%\eNw k5 L]ԯ/3Ďsb(h0a` Un@zY6a|ᘘc.Q1GT2ivoreITve.$悺lY3ɣ4w{(3thTGAo4f{[-gj/;]I(2V@6bS( FàRӬZ5S:+`DƈW)] c*IiU/p, ƅpEO1DBrR2lzR{ŀlT t>T9tb1SU)z{J:: rj |YcL 00An0veܺMk瑽<*1UnJ uC! `jVzҒ*QX-R%`JdB5c)e! r᮳5{kQo;&S'Mbkʋd]p!F.k8Z32V#w3͑Sim&55С,ә9/3kt)EѡMBb:f".l" [JAECCB?'~D4 d20%LLA3-3Y8Cy̶- g,4j}M7mc6Dz/vk8AqfZ "MyWwG6@'::&^oxd20%kYhdICL1;("P-Q6#K|MքUj0 !,5>AT̩<j&*Q O< "43;W$db3ĥu= 6V3'6x*~}s).yU_-{9LrZ~lFTA/s|G}I!iMЬ|1D›p+ r kskm؁nCz&aYy4<63Crxfg|G{ξ"| Gt$R#0o[ +>r[Z>m7iPwcl)I?7k:ofœI!e6;7?uݧ'XCc֬9GS B%Ka{C!'A9BVYHV(~ 5:+*h `" 05|TxK C`i0^  THAի1i M DZ7r3pkeC;*>"_T mƬ썑c3ɌѢZ*Ҳ&I:PfR /P:TNr1<$`@SZUڡjɬ"~ـGpHPǬX&p*@YRȔ^B9W>9Jb 2nL45!>kK35lpYf &5 (by<7g˧XsnY+/1%RLm31;ITLNU$3Sj֗=Yf3")ӣYpi ݺJ31NU$3 wfqSԚ-K I7KgO76$~c7;yc#-:QF3p'ǃ^*ϻɜd i T9xghYfn˴ѡBUʳ쮼1UMmu3(z7pC! c A=8j.m*R(SёpgvJ)dȵΑU6(ZZI׺,r{a=L6"HeJu #iLB 2&wkz7_xԹ qy Zߐ8_ YkBv:`a)|QUgb|ddaTy2bU!>"pJhDpD(Su.Ʈr~ 0=Uvt)!<;W3ˈ4- #!F%|-'>}=uG7%ꤒByN~#scrO[=ߍ)\zgbfFa<磹7]';[6RK꤀>ϻE@Y׹ef_f{x>؊n= @P<6Y$q!4'ʼ3ITlM v6x23q`؞9p/’,X hF95U D?}|%?7߱oόWޚk ?2dÎ[o]'wݝMhqaiӉTIPd{an{+22뺻hf1n9m祷WMxGנ:)](mguW0pao58W[b{L=t0V]'u5ݖG?(4.h.PO{G NMJJ=`x|zaof=bkljvٸ/.ɧ ֣e=u;.ݓ>J=}jibOBYunL[f el2 g[0LK|5:>CN}:aemm"(yD A|wyO^r|r}!ҝa1fb1`g;z5=\`ilI XMmnhR\}MOg%#!-<ݥ qT?oƦ4KDHT#]-(dPҿ"f~BJYHW8锑DfPF%j :n*kY;M$Z3$Y+w!LbJ@a:3YEQAH6%aEPYH*BG0 ((X,H)H$RXICI Ov|}G{$RFKgZk48?k}N<8'!ZR1TJ2K)e%0BJ,ir8+DDDG1/A˩ ˓Ȫ~OޝoZ>*֩{0 d$}6xu`x$De tqp FHc V !]Z$a559\x9@v:&"d]B@O&?{ :x;p:OtĪ(Ryl{wX?pvQZַ =CH?L#TjZ 496[1À]K_nVcGi}ffOA~kRiL!e d+ /F$hP6 ,%sw*ES (f!u^;o2I +U,?tdؒ|,y~_;MT! Dkkg;Sd!,$&nQB+c.+{B'[OD; ;w.lBk{W8df {߲IXl>D}bZ?|QEU^7M*mL7Q޻8;Kj ӎ}Ng63'CX6!*I 2QQE?SHOcAYmrܟ!i +!09c;_.yͨTqaT=$S؄cL`{ Dwqo``{S+'j]:F{2dDRĔzZs::r.v\s00̧i79Os~\6[D+g 뮴) sPP u}(n5CD_[`hm2J5A#LquQf !c?,mFk)6-M heY>L'۴HBVlNs&$*9cts5kUtAd4!z*v8ܨI.%"aL*3g[̢QN9cph`l֔  X iwWgW` C㴈?Nr]]磮:e[da9yEieN`K/}&\ђ#L M )߸䶕k2 [z޺ٿv pi[!q,k@Go[uLtc098> ߧ.9t9Gj8Qc6љS| |g?HQԻԵk01qToR@*B]xI gf/v8xgnтPLU@rh$0=,Δt^ A؟nB@0]T ^Ѡ6B28ٔʟE y+mil*eŒc$@SH @Y .#aD^1ѡ͇4 oў?r0°X5UbizK#Z4g^ l1A3[́w0yEkD(aHekPWnZr@7mf#$/r CGjw:^w@$,s||e{!ۯ;g6yצMl/ҽ{:h`JrE*E7H,ṲXNd$i㏌*QT`ҿX) I<9'sx|4t$Z_42\=drk˿نz<'ߘH׶qtĠO-`Li.xYrI=_ޯ^#; Äېtm|mRYeR+Zfc[9d M?:k Vu[ + %@49@}7FŞLmmSpX"A.Z l3 \_ 4+)Φ]έmD\ŢxRC  &]w*(cˎɝgI;,m33333338%-Zh @l=sb"۝hCh;DvzJگ4.wY/u4.wY/u4.wY/u7&%k3 q.Y\s3CM\؋\Dn!YH"d*(>z^of\Â[J-hsO:_hXm3sREB{[B{[B{[}t2݋fnt⺲E9z"EQEQE ;뭋A4w7̇耕RQ^(FPxMoF :xv}5E-+W@r&}p7"kNW*Fa+@!xN!,L;rV0~n2Q7JBAFT,.P6d`" Y'َ$PƓ:b>VV _yϏ $gf]H_CU0a8I;;w.0X'OG/mCi](kn 1Eř&Ć;Hr/'SmeG(V3p0&2TL p]dkMޮit:Q:-A-mSRHFnMEeua.'g-Ekitbrh$f @be5<;p8ua}G3e;HBd R | g N=Op*"y֝%^^Ӯ\Zi07Md]eM`j%I&̡xȚ 0Ө29 o]|L.>wkޕFO$sGqu]U h0>ѐ% N 8=˽evF *uWtآ%!MZSnnF֥];m]QKʯH\aef74A,^[w13"h.,Grm,jz{TޠeaYa<lwvtj8sa]Bu̚?_(==:×˧oL_ f殻IMrThZ{Kp*?G~|tkbhfw>;m ̯L'@\B!g$1~@c2 .[y¦9g"X;-E@xzn+0QQH1X1"dQb*"X*R"",* @R,QHDX*$! &_+r; >'?1\U78 x*g,]yG^Y}Y=ym^([^?#GVuBSL5.hKu Ԋ-* $Rfj%(1Yh5+$&l!Tvk c0HʼnK-BH",t }}  0HB"OiH{^xƀf^ /&ߩn&'E L s& /HX.~l2#3yƴBZ4ֳz8CH P^juu+R= 3%Ul9Nfh'<FXa$6mkb5XAR2A:N?z[pc$0&%N85^}\+ *-:c4qV$B[?ǫ}V}Z7<0VB7isDMk5ƷgK8xbԵ:ՄD)2G- Z5vm)Ο>P?|<=k}w7HTjccŪ=F578WGX &w 1_qEEA1a(P#X +_FGɔT4e/b>b6S菦 )ሒNb: T3ν3:Nq]IwΓO$mk9Ns$<nuli )*Y>|{|-|]{5ӱocLc5i2u8uWɎ>QBAkN!ԒI$j^br4>qmW~c 2F}'L`PEkH7}Y#wwTHAX~nsE=y玏 a+)WL5-BY՛Ra IaR֞j%p>h%2'u)%GϖÈ\S@ۂ**8|xvo;׌&\1<|'>9Le4N/ûz%\D 89Je!KH`áOߚP 754]{@BWI%bm=<Gx|/8zDWwOqԈ }UOUxU R4){'|>nP4@-EۃpaޜtD7HNmrŶ{zߧgb#瀞=|,zfe!kɎ 1VD) MnCbQ!cL Acs#ʣ0L ! WY3)R b9%+ ERB,&82 0 \Ҕ@5B@'Ǵal[{KdEaHRJEP%BRDBBV# i QF EiYXcP"ĕ ,1=f(C1"2sCR i|sw@*)y,ڶ/B[9;m֝ש9l'3j}Yj6g> n1v%!*"x $ "/̕HHM Q&6ВH  2""H"G*lݟ}gx Pm,X[$ RIhP)(~*&a}ZR'hMPc&֠Z5MD;88ak&TyvMi?]@xkxgz=JS'E4v8Tb!RUU\eURUD?0pdʭޟmk"(I 8P0j3VM*2 F&L^,-$z|? 4x V6lه@@d\3fwLdiL}wcHmH>)/UTr?q2҈ҥ>ѥ#jK l5 &@RQaX-AQ6ƲIВ ]eX TcQv-.P4jf@(&픈aY/ nVajQGeɴr~yHl3uGf$0Xw{g%c-٬(aBËUвz4"_yZuZBAyHWtbQO3n=ܺ]:vAFǤHH >A rpG!B6 EAFPॱ11A«qEX# E9*i=3{Po *my$lS+ZN{mN JK%sx9X(VT]F5S{=ѓ`jq$;qb[gw jtsB05u) NgiM6GB9v[TQTIMSs,J 8:{h1DElOk7 viGAUM#DzJ9{UCP/a '0ɳ=׿I+3MPKAnjNXS 2]ikVc ML>ž*,1!a 0LKq ~Ğfٶ`med+ , O?a %efG,h5DY$&n/8^B\ѥit턯T:U/HoشrRjPtݻwZL0уDKv5:nteqaPbRg9 PQbŊws *J+ @mY5=gp~eFXx2| tkw,:ϙa`}㇞Xabm, 0dJ_rQ+,!Cj]l}[x*)gdUkҽhZu]-D =:ݴ5F!QǑ>"GpPQ:v4v;y>Nů{kZvWQzJ9+bjR8 0wz 0 &thj˪ƎuoK6:6de,^5uׯ&2nÖۊQܨ'i]Yg?nݽo{O;s̋֗Z*>1=ꗋGדylCu<8~oO̸ٙPy)ҧΏtF:YaK1-Wȁ<:q=,)O6qS|gKmjAlJDZF"Mջ#p>d1oRfr${C5G|IdټQik{6 r:?-6ߡMMm35rnx4 Pg6ۤVJ˿g{>H|<9H|Ô۰i< WpCGsu;&1 &6ZJ+(h0p|IjIUxܹM H+gY>kGU $I bZJy% N=ΟWr> ^xRhKƾ)mQ5)aٷ t fxwr=Q$=` KF %_l~֎ӽq53[wp$?p_L5AShv$~IGPT @#jx~>R04GUÙY#mG˓]׃=t%EVFb(X1QEDU`rq+҅AF4r(BVVuw ͦ-ŌbRLpIQs3 ,*@U1E*ZX-Afb*!  ֤So8Bk$H%`RlAF;(61T*,QBPpbDd [MX&  h , Z%k[hfr $XAI SaGNE?lwikz5n8*߰=={3z1%Fd=q,[S"~$:ǵ8W"qFn,H~(axnV$4Od09m}~[#޾2 2eYy]~/eYg"?gٿe| jB&z佲>v"`U <;sg]tlY@z(0x_~Rp?f]iZK:P˅hQ @1qR-J(2*eő$ba112`CN #[MK9E֪k]72ADJ$ f2,T01UW3NUuQT?,Nn}pM(+׳뎧f;&~s67ټ.\}bo߃CU44Wԓ$_!G2=r'kԲ

3ח(rBQ ̅D'/"|W8%j03eC<s6{N8k=rvT' ,` Kqqt,,ф>xLk,j @,y$TQt!UݓoC0KE@iȋ1)n9g_Zs=&f3y6*}Td@PJ @#&3ս9uqņ K(XTMq7_a!Cas~O?f6b5"CF @J dd Y!iQXX@4kR0g4`d PK`b ͱb0*HY_nT>?y?]k'4yfgqfMAJ 5{oߞ@7 G5012g[FyL%0zsB>JVLLcIieSC0w>vtxtȄ2 ss*] ]* p)Ir BBkD-ihlrԸUb VHOOM" "XȈ,$ hsVM330l2܁2]k - 1 X" R+1aF2i Pc)a{#$ ,( ,E@aw*Ԛ&ɻ!ꀞ&ґΝHM$p ᗯOC'K~[u*I5 "F%3ezeՔTZ\%2AҪ%*瀚q^MUy'??PJ?N "+ Mn>t)nۈ9Ŏ ! n2#ʮd(>B")@E20hFG6ld}҅ibX-N%uHUvV9.%N5%a'9 .l Q3o(2.s @xrָX{ֈ AD25WF3Y[8cnv [ DE&ȁ$5!6qDjktq0, <(?Gf ,6fxreWA ^nC%м{|al-eoF 0K@H@rYrdh gs[9A g+m9uBNP@iP7(AڠmM)C?o 3SN$K:HXCa,k7d*Ϊ.=1 X1:3#SI{4g:0V8S81Aޮn{۴M]Y;;É$&fgxr>?ߺmehgrlܟ Gq;;xX-=gU;ͤr;[$z:zBhqwBbp(ac7,_ԅrSK8W(ZTܦݶo4Wek]kSbdnaIB&e 4# 'h3KZ07(H,ix6g3԰nQRVQa=_OeqM:Ns\9/ !"1hѲ03PhHuۙ]lK4NзW$y6ZMɪ0BI!zsQtTE5TE;/אB$$$-7c#1>385Aߛ D¾}x$<>rʲy ݦ)- %4L t1-0I\9d^j\}9F*wFvɨ%KǴ$yÇG|UVg} u?+۴[M <*@abgmRO4QPHj3۸?V慰!"S SOvKP9k3 Q1\)iLb%VK0Dd1dB2C)L @$%2iZ Ң*^f̘ePқ1(Rc8HI#3ύz$|wU^;!_?Jt "~ cm< ϑ V{mqN*mq.MKZ/$C99+?p߿(ԹwڮjۇP&Nh|g ,Cw7hn|f}~Z-hvn"CG-]٪%*]!jDf$yoZjjIU_#00"8۷b`g >x* 'QO::0 ПgWA7 ,k0bU˹JӢus;% ehȰxP.ttb UrȎ"]jVR w5w3k*]ł6fff`-6ЄE0 $UjJ&* \4PjZւ)Q )‚Ihepͷlw7kM(uz֮"ъuX39@W-C\P@U4֨0l^MR@l E.@ ( V [ bTg5U^CQ#B *BZΘ+60&7zs!\ 8W:ˌdpl,:xyVt1H%:DWK@a`3Ҳ3$ 8QDְK IF&%fm bhh8@Þ9]' Cb'QI:DUWraHPߴ&j0fm- xLl2;mQ 1&J`3f2]Ԍ6/48L8x3tsgN):.qcET¢9Vm릨][|l2;m-gg8M+I]áHgN:LxS<Ԭ}WvK&`ՉlBG8dxo!@.~z!j+=|c=zC(zHrwܜH`ƙ0CI]41,iFy2ʻ4Zm7dPucyB/A7~o(2 ]XBn/ vN3IO)b)$LxOaɩqN8jcN' ]؇~R9=xF;V<uÁ{dba][q`, f,!Y 5IW+%3TI,NzkGF"fɚ9NgIfn$,>9A5W=ӡ+ G :4'H+H0Ҧ ,XE@1Hhnyd^R" 92$@}gybIj,Nn͛@4L:xp; Wuumu̫3\V1 бF'Si2`/Buըh'pQeMWz· hzL:l뾚)/P =l2LfUUnݓ #DW &~hu'T=LS5 : H+dQ.",5 aU4XˌטnawY !'U9^bL%a&h%vNJri]K~-{|3wY:P: PPH6>0X P $RByU) nO8(I9|Q~7KocQو;&ɹ'Cݳ9YiZpᬫNqcpn1y`1=A\w&@vY>h? ~4~`8z&n6 3(W#OXp q+(csN7LvuIWCaUƐ _]~Qj=ow ]DB{'ۇBc$DԖ,,c,5@ u-b)ا9q6Ubni0rb j Kmƹh-*^*4$Q<G9<ŭvTOA{5xGY2̦x-:JHKB"ImUI؇'yF}ÿ꧞~ wW}]}2o<ٓ~T ^NzhHap7fhrw+l4qnL;Z+7‘7:!٠Dx4f=\C\(WZņ3chcQҸ!ڶj,T,dr2$G =nD,7da a€dVI$$g|փ(\| r|'D0ZE@OSI=>ؽB^ x/3]Lnz[dݻ,?Nx.6B#=*H /L^JWuOh5Qm# 4|o.&Q806 (a-*(]GɧBFlER:h\4ic*:a?2\_4lz,7><@`lHM ƀշ}_g|>^yu ;-U ݅1QB2G"Y¬N s2 &j ]!8J!C %}E`ɮM`B UL*b?;< 7 Vl$q;SLu.ACT7xBɜh,{n+d%B&WafƸ}Ň\8J+ك(].%䢄Qed(D E:8xd#$'LKyqZJ*}e 5N[VAc%͓; _21|zjG NhΕ!弶[h&_qaMAv@dR@E0А)%@h3kѡwW{Ue\?WB*DvG0o 5SAl%T>P/A9+ҕ3^x ]aaX^yd 5F)h@3 % K#F)6 &_HZ=ܕAȆ&ǩ FMXTD@d˩_m8`Qn&⪜<Ì:jJUUx[ ھ~M{w_kv\|]|4b0ϲ}a-ͫQqΩHR!?X}vaˊU Ȍ'yXsϠ>!$]z6H̘ILa?iJ?i&}_kk[\Ư^Q*3֪70B,)@n?;YM!LO OiF<J@>ڊ d ɵTSd uɀЏsχ,p %LaB0T!ȉ'"QQ 2r H0t8iR̡PH@XA  0$@Q=,("," 9Z6^(C ƽx 2 0${22 a(&7/aBc18D$BHnےL̶T3@Nr,:9a;u̶nȝ e{p.;HLMwdz+ dց_ 7e7H Nk(.Rj:*:ѢayCF!2pFI.›^MxOQN:!o}gG۴s9 ߟ ϳwL2%e^^O?##s={vWyd\F&SC}?OEW^Wn'}yd0HIH(`,D,XXV  A*@P ` P b:P, B 0kJ0U|oi@$ΊE BB,,V,Db+D@ :X U$$@d D @@B+QA@R$[Ah (X 1`RZ,TY 1mUVB,IdI-hQUT %mR2n$ !bFFB,Hbj@>w~>WD>(j tuyywZHw  frWrI)U4GHVYoA]uB!hYM45fiSPb!BhJ̭ED~s3e*I#q iPi!B +bGq"MBffffff#eP!B *& 9 L;(>ey\qYeYeYeдK-F/;,R䲾*A\LT}J(j8R} eXI$TPؾ$fffjEBڤ$H)QEUN eP!BB"UXI%*/ !d#2 huTʈ|>owow׿ϸ#tDUUUU*WD4K<]{&i0fffg4`ȿlvl #8S}P2I"2#$UH332"5q3335O4^ 4&7B؛}`hX;WfUbzdֱbŚ"3(ETI,&$zզdmWDE~-j,X`lR֭ZlQbթYX آgih%y٭%C9 4 WzJիʳjikڵZզeg&{6Y" Q`&3333Z{QE4M4TVyƯ`%c)Tfffgjw?%ֵjm]nׯMr刺/^ ^|n5nkv}?OAbA`*X w 0I$d#0FW*رbŇ3Qf[6lٳfVcb>QXEEA,D3vY333TQ,K*YS %&3V* *USӢM2G$TC 2"%"-3"3f3333iiUA,%*"$)!B!D)O .$r*]@% E* #qĩwS"2" G1앶%J%*9l( 5.:LߚYdT LTjYejz+RyI4K,=iڣXH~I$©$QH̭q] Ugy>yW@,cf{ʥIQRII*2)+K=ifT. &\<9_9$M[6ut˗W_.|H,r(~(Lh !Zl "< IelK,,Mݍ it@r)z (DED~Zi(xxV(QZV8Qfy*U;R$1bD/ERGF˜ \QqJb(!vAr"(nuW)(R5ꎮYV`l)UFK6h{aDpziGZx'H K|*whx<񙙙9@!&$дBI#@ifd,iG**D͵*Yg@js3333333333:r C Mjբibj(@ I+Jge.!BB)i`XUЉ,de2B̬,,Z9+bIqEj6$*(zUUUUUP|>sϟ={ntZ Fffft*ieyIP! d6ٙ)Jr(%RʩdQҚMh&3-U4RpD}㷗-:ry K}^ vV\yn./_r\0D@&M !UU?zs]5]\݆[wf\aaZµJ;t:nݪ>I'ŒII0;O{$1d`,LŒII0I&|c[WTꪛZ*OŇ ҪN߿Mb$ Y$$7̀b$HLŒII0I&|̤UI/{/5/V*_?HK_7pku)[ft'"C؈1E AX`JOJ# UQ,+T MB$J|'Zcikj o|c8 t2V!)(xB)4#Wgr(^ZvKK|7N6Yo#j($7!?5=Β.s\ LòMG<ܚ##󺮦ײ\rS,a ?¬wp{Ziusؽ~}Fvsh|Yy2e[,QGяϢxC rm^`3٭6hf/sTo?z,/kZmmmͪ~_'|{?8~:C2!gis|b 1sG][z/gUn7^mhUw^zs[a*r!s׵1r!{ߜ5ߟsϿg9Ϝ]^7nP;{nޕlg]p9glxd 9Zֳ~HL8n޷";jg>5qz6(^u[2#0E# d"D, ``D `FHHAs\z-_ʪ**I'X1`X, $"AOTP~da)U0Mu`2 e\ɐ v;m{%J=N e[,'(fK `t(a`X, `  `X!Պb @Ā !"‘`h!d d ,  H0a X, °X20H0X, `FI ` , `XH$"E|0["*_zVY砊T⨠88qUS[[+T="e|XH|}ei\_K@S__` (UD$Y$PRK Dl Qr%4*QEH  `sessioninfo/R/dependent-packages.R0000644000176200001440000000476214152377737016710 0ustar liggesusers dependent_packages <- function(pkgs, dependencies) { ideps <- interpret_dependencies(dependencies) pkgs <- find_deps(pkgs, utils::installed.packages(), ideps[[1]], ideps[[2]]) desc <- lapply(pkgs, pkg_desc) loaded_pkgs <- pkgs %in% setdiff(loadedNamespaces(), "base") ondiskversion <- vapply( desc, function(x) x$Version %||% NA_character_, character(1)) loadedversion <- rep(NA_character_, length(pkgs)) loadedversion[loaded_pkgs] <- vapply(pkgs[loaded_pkgs], getNamespaceVersion, "") loadedpath <- rep(NA_character_, length(pkgs)) loadedpath[loaded_pkgs] <- vapply(pkgs[loaded_pkgs], getNamespaceInfo, "", which = "path") res <- data.frame( package = pkgs, ondiskversion = ondiskversion, loadedversion = loadedversion, path = vapply(desc, pkg_path_disk, character(1)), loadedpath = loadedpath, attached = paste0("package:", pkgs) %in% search(), stringsAsFactors = FALSE, row.names = NULL ) res <- res[match(sort_ci(res$package), res$package), ] row.names(res) <- NULL res } pkg_path_disk <- function(desc) { if (is.null(desc)) { NA_character_ } else { system.file(package = desc$Package, lib.loc = .libPaths()) } } find_deps <- function(pkgs, available = utils::available.packages(), top_dep = c(dep_types_hard(), "Suggests"), rec_dep = dep_types_hard(), include_pkgs = TRUE) { if (length(pkgs) == 0 || identical(top_dep, FALSE)) return(character()) if (length(top_dep) > 0) { top <- tools::package_dependencies(pkgs, db = available, which = top_dep) top_flat <- unlist(top, use.names = FALSE) } else { top_flat <- character() } if (length(rec_dep) != 0 && length(top_flat) > 0) { rec <- tools::package_dependencies( top_flat, db = available, which = rec_dep, recursive = TRUE) rec_flat <- unlist(rec, use.names = FALSE) } else { rec_flat <- character() } unique(c(if (include_pkgs) pkgs, top_flat, rec_flat)) } dep_types_hard <- function() c("Depends", "Imports", "LinkingTo") dep_types_soft <- function() c("Suggests", "Enhances") dep_types <- function() c(dep_types_hard(), dep_types_soft()) is_na_scalar <- function(x) length(x) == 1 && is.na(x) interpret_dependencies <- function(dp) { hard <- dep_types_hard() if (isTRUE(dp)) { list(c(hard, "Suggests"), hard) } else if (identical(dp, FALSE)) { list(character(), character()) } else if (is_na_scalar(dp)) { list(hard, hard) } else { list(dp, dp) } } sessioninfo/R/utils.R0000644000176200001440000000154214152401270014273 0ustar liggesusers `%||%` <- function(l, r) if (is.null(l)) r else l sort_ci <- function(x) { old <- Sys.getlocale("LC_COLLATE") on.exit(Sys.setlocale("LC_COLLATE", old), add = TRUE) Sys.setlocale("LC_COLLATE", "C") x[order(tolower(x), x)] } is_string <- function(x) { is.character(x) && length(x) == 1 && !is.na(x) } is_flag <- function(x) { is.logical(x) && length(x) == 1 && !is.na(x) } order_by_name <- function(x) { if (!length(x)) { x } else if (is.null(names(x))) { stop("Cannot order by name, no names") } else { x[order(names(x))] } } drop_null <- function(x) { x[! vapply(x, is.null, logical(1))] } last <- function(x) { x[length(x)] } empty <- function(x) { grepl("^\\s*$", x) } str_trim <- function(x, width) { stopifnot(width >= 2) if (nchar(x) <= width) { x } else { paste0(substr(x, 1, width - 1), "~") } } sessioninfo/R/platform-info.R0000644000176200001440000000566214152377737015743 0ustar liggesusers #' Information about the current platform #' #' @return A list with elements: #' * `version`: the R version string. #' * `os`: the OS name in human readable format, see [os_name()]. #' * `system`: CPU, and machine readable OS name, separated by a comma. #' * `ui`: the user interface, e.g. `Rgui`, `RTerm`, etc. see `GUI` #' in [base::.Platform]. #' * `language`: The current language setting. The `LANGUAGE` environment #' variable, if set, or `(EN)` if unset. #' * `collate`: Collation rule, from the current locale. #' * `ctype`: Native character encoding, from the current locale. #' * `tz`: The current time zone. #' * `date`: The current date. #' * `rstudio`: RStudio format string, only added in RStudio. #' * `pandoc`: pandoc version and path #' #' @seealso Similar functions and objects in the base packages: #' [base::R.version.string], [utils::sessionInfo()], [base::version], #' [base::.Platform], [base::Sys.getlocale()], [base::Sys.timezone()]. #' #' @export #' @examplesIf FALSE #' platform_info() platform_info <- function() { as_platform_info(drop_null(list( version = R.version.string, os = os_name(), system = version$system, ui = .Platform$GUI, language = Sys.getenv("LANGUAGE", "(EN)"), collate = Sys.getlocale("LC_COLLATE"), ctype = Sys.getlocale("LC_CTYPE"), tz = Sys.timezone(), date = format(Sys.Date()), rstudio = get_rstudio_version(), pandoc = get_pandoc_version() ))) } get_rstudio_version <- function() { tryCatch({ ver <- get("RStudio.Version", "tools:rstudio")() paste0( ver$long_version %||% ver$version, if (!is.null(ver$release_name)) paste0(" ", ver$release_name), " (", ver$mode, ")" ) }, error = function(e) NULL) } get_pandoc_version <- function() { if (isNamespaceLoaded("rmarkdown")) { ver <- rmarkdown::find_pandoc() if (is.null(ver$dir)) { "NA (via rmarkdown)" } else { paste0(ver$version, " @ ", ver$dir, "/ (via rmarkdown)") } } else { path <- Sys.which("pandoc") if (path == "") { "NA" } else { ver <- parse_pandoc_version(path) paste0(ver, " @ ", path) } } } parse_pandoc_version <- function(path) { tryCatch({ out <- system2(path, "--version", stdout = TRUE)[1] last(strsplit(out, " ", fixed = TRUE)[[1]]) }, error = function(e) "NA") } #' @export format.platform_info <- function(x, ...) { df <- data.frame( setting = names(x), value = unlist(x), stringsAsFactors = FALSE ) format_df(df) } #' @export print.platform_info <- function(x, ...) { cat(format(x, ...), sep = "\n") } #' @export as.character.platform_info <- function(x, ...) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) format(x, ...) } #' @export c.platform_info <- function(...) { as_platform_info(NextMethod()) } as_platform_info <- function(x) { stopifnot(is.list(x)) class(x) <- c("platform_info", "list") x } sessioninfo/R/printing.R0000644000176200001440000000323614152377737015013 0ustar liggesusers #' @importFrom cli symbol rule <- function (..., pad = NULL, double = FALSE) { if (is.null(pad)) pad <- if (double) symbol$double_line else symbol$line title <- if (length(list(...))) paste0(" ", ..., " ") else "" width <- max(cli::console_width() - cli::ansi_nchar(title, "width") - 3, 0) rule <- paste(pad, title, paste(rep(pad, width), collapse = ""), sep = "") cli::style_bold(cli::col_cyan(rule)) } dash <- function(n = 2) { paste(rep(symbol$line, n), collapse = "") } cat_ln <- function(..., sep = "") { cat(..., "\n", sep = sep) } col_align <- function(x, align = c("left", "center", "right")) { x <- encodeString(x) mw <- max(cli::ansi_nchar(x, "width")) cli::ansi_align(x, align = align, width = mw) } format_column <- function(name, x) { col_align(c(name, x)) } format_df <- function(x, highlighters = NULL) { cols <- mapply( names(x), x, FUN = format_column, USE.NAMES = FALSE, SIMPLIFY = FALSE ) cols <- lapply(cols, function(x) { if (length(x) > 0) x[1] <- cli::col_grey(cli::style_italic(x[1])) x }) for (idx in seq_along(highlighters)) { colname <- names(highlighters)[idx] colnum <- match(colname, names(x)) if (is.na(colnum)) next cols[[colnum]][-1] <- highlighters[[idx]](cols[[colnum]][-1]) } # remove trailing space, to avoid superfluous wrapping cli::ansi_trimws(do.call("paste", c("", cols)), "right") } highlight_version <- function(x) { ver <- tryCatch(package_version(trimws(x)), error = function(err) NULL) if (is.null(ver)) return(x) large <- vapply(ver, function(x) any(unlist(x) >= 1234), logical(1)) x[large] <- cli::style_bold(cli::col_magenta(x[large])) x } sessioninfo/R/clipboard.R0000644000176200001440000000131114152377737015110 0ustar liggesusers get_os <- function() { if (.Platform$OS.type == "windows") { "win" } else if (Sys.info()["sysname"] == "Darwin") { "mac" } else { "unix" } } clipboard_read <- function() { os <- get_os() switch( os, win = utils::readClipboard(), mac = clipboard_read_mac(), clipboard_read_x11() ) } clipboard_read_mac <- function() { on.exit(try(close(con), silent = TRUE), add = TRUE) con <- pipe("pbpaste") scan(con, what = "", sep = "\n", blank.lines.skip = FALSE, quiet = TRUE) } clipboard_read_x11 <- function() { on.exit(try(close(con), silent = TRUE), add = TRUE) con <- file("clipboard") scan(con, what = "", sep = "\n", blank.lines.skip = FALSE, quiet = TRUE) } sessioninfo/R/rematch2.R0000644000176200001440000000172014152377737014662 0ustar liggesusers re_match <- function(text, pattern, perl = TRUE, ...) { stopifnot(is.character(pattern), length(pattern) == 1, !is.na(pattern)) text <- as.character(text) match <- regexpr(pattern, text, perl = perl, ...) start <- as.vector(match) length <- attr(match, "match.length") end <- start + length - 1L matchstr <- substring(text, start, end) matchstr[ start == -1 ] <- NA_character_ empty <- data.frame(stringsAsFactors = FALSE, .text = text)[, numeric()] res <- list(match = !is.na(matchstr), groups = empty) if (!is.null(attr(match, "capture.start"))) { gstart <- attr(match, "capture.start") glength <- attr(match, "capture.length") gend <- gstart + glength - 1L groupstr <- substring(text, gstart, gend) groupstr[ gstart == -1 ] <- NA_character_ dim(groupstr) <- dim(gstart) res$groups <- cbind(groupstr, res$groups, stringsAsFactors = FALSE) names(res$groups) <- attr(match, "capture.names") } res } sessioninfo/R/external-info.R0000644000176200001440000000452314152377737015734 0ustar liggesusers #' Information about related software #' #' @details #' Note that calling this function will attempt to load the tcltk and #' grDevices packages. #' #' @return A list with elements: #' * `cairo`: The cairo version string. #' * `libpng`: The png version string. #' * `jpeg`: The jpeg version string. #' * `tiff`: The tiff library and version string used. #' * `tcl`: The tcl version string. #' * `curl`: The curl version string. #' * `zlib`: The zlib version string. #' * `bzlib`: The zlib version string. #' * `xz`: The zlib version string. #' * `PCRE`: The Perl Compatible Regular Expressions (PCRE) version string. #' * `ICU`: The International Components for Unicode (ICU) version string. #' * `TRE`: The TRE version string. #' * `iconv`: The iconv version string. #' * `readline`: The readline version string. #' * `BLAS`: The path with the implementation of BLAS in use. #' * `LAPACK`: The path with the implementation of LAPACK in use. #' #' #' @seealso Similar functions and objects in the base packages: #' [utils::sessionInfo()], [base::extSoftVersion], [tcltk::tclVersion()] #' [base::La_library], [base::La_version()], [base::libcurlVersion()]. #' #' @export #' @examplesIf FALSE #' external_info() external_info <- function() { ex <- c(get_grsoft_version(), tcl = get_tcl_version(), curl = libcurlVersion(), extSoftVersion()) ex["lapack"] <- get_la_library() ex["lapack_version"] <- get_la_version() names(ex) <- gsub("^lib", "", names(ex)) structure(as.list(ex), class = c("external_info", "list")) } get_tcl_version <- function() { tryCatch( suppressWarnings(tcltk::tclVersion()), error = function(err) "" ) } get_grsoft_version <- function() { grDevices::grSoftVersion() } get_la_library <- function() { tryCatch(base::La_library(), error = function(err) NA_character_) } get_la_version <- function() { tryCatch(base::La_version(), error = function(err) NA_character_) } #' @export format.external_info <- function(x, ...) { df <- data.frame( setting = names(x), value = unlist(x), stringsAsFactors = FALSE ) format_df(df) } #' @export print.external_info <- function(x, ...) { cat(format(x, ...), sep = "\n") } #' @export as.character.external_info <- function(x, ...) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) format(x, ...) } sessioninfo/R/package-info.R0000644000176200001440000002346214152770761015502 0ustar liggesusers #' Information about the currently loaded packages, or about a chosen set #' #' @param pkgs Which packages to show. It may be: #' * `NULL` or `"loaded"`: show all loaded packages, #' * `"attached"`: show all attached packages, #' * `"installed"`: show all installed packages, #' * a character vector of package names. Their (hard) dependencies are #' also shown by default, see the `dependencies` argument. #' @param include_base Include base packages in summary? By default this is #' false since base packages should always match the R version. #' @param dependencies Whether to include the (recursive) dependencies #' as well. See the `dependencies` argument of [utils::install.packages()]. #' @return A data frame with columns: #' * `package`: package name. #' * `ondiskversion`: package version (on the disk, which is sometimes #' not the same as the loaded version). #' * `loadedversion`: package version. This is the version of the loaded #' namespace if `pkgs` is `NULL`, and it is the version of the package #' on disk otherwise. The two of them are almost always the same, #' though. #' * `path`: path to the package on disk. #' * `loadedpath`: the path the package was originally loaded from. #' * `attached`: logical, whether the package is attached to the search #' path. #' * `is_base`: logical, whether the package is a base package. #' * `date`: the date the package was installed or built, in UTC. #' * `source`: where the package was installed from. E.g. #' `CRAN`, `GitHub`, `local` (from the local machine), etc. #' * `md5ok`: Whether MD5 hashes for package DLL files match, on Windows. #' `NA` on other platforms. #' * `library`: factor, which package library the package was loaded from. #' For loaded packages, this is (the factor representation of) #' `loadedpath`, for others `path`. #' #' See [session_info()] for the description of the *printed* columns #' by `package_info` (as opposed to the *returned* columns). #' #' @export #' @examplesIf FALSE #' package_info() #' package_info("sessioninfo") package_info <- function( pkgs = c("loaded", "attached", "installed")[1], include_base = FALSE, dependencies = NA) { if (is.null(pkgs)) pkgs <- "loaded" if (identical(pkgs, "!loaded") || identical(pkgs, "loaded")) { pkgs <- loaded_packages() } else if (identical(pkgs, "!attached") || identical(pkgs, "attached")) { pkgs <- attached_packages() } else if (identical(pkgs, "!installed") || identical(pkgs, "installed")) { pkgs <- installed_packages() } else { pkgs <- dependent_packages(pkgs, dependencies) } desc <- lapply(pkgs$package, pkg_desc, lib.loc = .libPaths()) pkgs$is_base <- vapply( desc, function(x) identical(x$Priority, "base"), logical(1) ) pkgs$date <- vapply(desc, pkg_date, character(1)) pkgs$source <- vapply(desc, pkg_source, character(1)) pkgs$md5ok <- vapply(desc, pkg_md5ok_dlls, logical(1)) libpath <- pkg_lib_paths() path <- ifelse(is.na(pkgs$loadedpath), pkgs$path, pkgs$loadedpath) pkgs$library <- factor(dirname(path), levels = libpath) if (!include_base) pkgs <- pkgs[! pkgs$is_base, ] rownames(pkgs) <- pkgs$package class(pkgs) <- c("packages_info", "data.frame") pkgs } pkg_desc <- function(package, lib.loc = NULL) { desc <- suppressWarnings( utils::packageDescription(package, lib.loc = lib.loc)) if (inherits(desc, "packageDescription")) desc else NULL } pkg_lib_paths <- function() { normalizePath(.libPaths(), winslash = "/") } pkg_date <- function (desc) { if (!is.null(desc$`Date/Publication`)) { date <- desc$`Date/Publication` } else if (!is.null(desc$Built)) { built <- strsplit(desc$Built, "; ")[[1]] date <- built[3] } else { date <- NA_character_ } as.character(as.Date(strptime(date, "%Y-%m-%d"))) } pkg_source <- function(desc) { if (is.null(desc)) { NA_character_ } else if (!is.null(desc$GithubSHA1)) { str <- paste0("Github (", desc$GithubUsername, "/", desc$GithubRepo, "@", desc$GithubSHA1, ")") } else if (!is.null(desc$RemoteType) && desc$RemoteType == "standard") { if (!is.null(desc$Repository) && desc$Repository == "CRAN") { pkg_source_cran(desc) } else if (!is.null(desc$Repository)) { str_trim(desc$Repository, 10) } else if (!is.null(desc$biocViews) && desc$biocViews != "") { "Bioconductor" } else { "Custom" } } else if (!is.null(desc$RemoteType) && desc$RemoteType != "cran") { # want to generate these: # remoteType (username/repo@commit) # remoteType (username/repo) # remoteType (@commit) # remoteType remote_type <- desc$RemoteType # RemoteUsername and RemoteRepo should always be present together if (!is.null(desc$RemoteUsername) && (!is.null(desc$RemoteRepo))) { user_repo <- paste0(desc$RemoteUsername, "/", desc$RemoteRepo) } else if (!is.null(desc$RemoteUrl)) { user_repo <- desc$RemoteUrl } else { user_repo <- NULL } if (!is.null(desc$RemoteSha)) { sha <- paste0("@", desc$RemoteSha) } else { sha <- NULL } # in order to fulfill the expectation of formatting, we paste the user_repo # and sha together if (!is.null(user_repo) || !is.null(sha)) { user_repo_and_sha <- paste0(" (", user_repo, sha, ")") } else { user_repo_and_sha <- NULL } str <- paste0(remote_type, user_repo_and_sha) } else if (!is.null(desc$Repository)) { pkg_source_cran(desc) } else if (!is.null(desc$biocViews) && desc$biocViews != "") { "Bioconductor" } else if (isNamespaceLoaded(desc$Package) && !is.null(asNamespace(desc$Package)$.__DEVTOOLS__)) { "load_all()" } else { "local" } } pkg_source_cran <- function(desc) { repo <- desc$Repository if (!is.null(desc$Built)) { built <- strsplit(desc$Built, "; ")[[1]] ver <- sub("$R ", "", built[1]) repo <- paste0(repo, " (", ver, ")") } repo } pkg_md5ok_dlls <- function(desc) { if (is.null(desc)) return(NA) if (.Platform$OS.type != "windows") return(NA) pkgdir <- dirname(dirname(attr(desc, "file"))) if (!file.exists(file.path(pkgdir, "libs"))) return(TRUE) stored <- pkg_md5_stored(pkgdir) if (is.null(stored)) return(NA) disk <- pkg_md5_disk(pkgdir) identical(stored, disk) } pkg_md5_stored <- function(pkgdir) { md5file <- file.path(pkgdir, "MD5") md5 <- tryCatch( suppressWarnings(readLines(md5file)), error = function(e) NULL) if (is.null(md5)) return(NULL) hash <- sub(" .*$", "", md5) filename <- sub("^[^ ]* \\*", "", md5) dll <- grep("[dD][lL][lL]$", filename) order_by_name(structure(hash[dll], names = tolower(filename[dll]))) } pkg_md5_disk <- function(pkgdir) { old <- getwd() on.exit(setwd(old), add = TRUE) setwd(pkgdir) dll_files <- file.path( "libs", dir("libs", pattern = "[dD][lL][lL]$", recursive = TRUE)) md5_files <- tools::md5sum(dll_files) order_by_name(structure(unname(md5_files), names = tolower(dll_files))) } abbrev_long_sha <- function(x) { sub("([0-9a-f]{7})[0-9a-f]{33}", "\\1", x) } #' @export format.packages_info <- function(x, ...) { unloaded <- is.na(x$loadedversion) flib <- function(x) ifelse(is.na(x), "?", as.integer(x)) px <- data.frame( package = x$package, "*" = ifelse(x$attached, "*", ""), version = ifelse(unloaded, x$ondiskversion, x$loadedversion), "date (UTC)" = x$date, lib = paste0("[", flib(x$library), "]"), source = abbrev_long_sha(x$source), stringsAsFactors = FALSE, check.names = FALSE ) badloaded <- package_version(x$loadedversion, strict = FALSE) != package_version(x$ondiskversion, strict = FALSE) badloaded <- !is.na(badloaded) & badloaded px$source <- ifelse( badloaded, paste0(px$source, " (on disk ", x$ondiskversion, ")"), px$source ) badmd5 <- !is.na(x$md5ok) & !x$md5ok badpath <- !is.na(x$loadedpath) & x$loadedpath != x$path baddel <- is.na(x$ondiskversion) badpath[baddel] <- FALSE if (any(badloaded) || any(badmd5) || any(badpath) || any(baddel)) { prob <- paste0( ifelse(badloaded, "V", ""), ifelse(badpath, "P", ""), ifelse(badmd5, "D", ""), ifelse(baddel, "R", "")) px <- cbind("!" = prob, px) } dng <- function(x) cli::bg_red(cli::col_white(x)) highlighters <- list( "!" = function(x) { ifelse(empty(x), x, dng(x)) }, version = function(x) { highlight_version(x) }, "date (UTC)" = function(x) { cli::col_grey(x) }, lib = function(x) { cli::col_grey(x) }, source = function(x) { common <- grepl("^(Bioconductor|CRAN)", x) x[!common] <- cli::style_bold(cli::col_magenta(x[!common])) x[common] <- cli::col_grey(x[common]) x } ) fmt <- c(format_df(px, highlighters = highlighters), "") lapply( seq_along(levels(x$library)), function(i) { fmt <<- c(fmt, cli::col_grey(paste0(" [", i, "] ", levels(x$library)[i]))) } ) if ("!" %in% names(px)) fmt <- c(fmt, "") if (any(badloaded)) { fmt <- c(fmt, paste0(" ", dng("V"), " ", dash(2), " Loaded and on-disk version mismatch.")) } if (any(badpath)) { fmt <- c(fmt, paste0(" ", dng("P"), " ", dash(2), " Loaded and on-disk path mismatch.")) } if (any(badmd5)) { fmt <- c(fmt, paste0(" ", dng("D"), " ", dash(2), " DLL MD5 mismatch, broken installation.")) } if (any(baddel)) { fmt <- c(fmt, paste0(" ", dng("R"), " ", dash(2), " Package was removed from disk.")) } fmt } #' @export print.packages_info <- function(x, ...) { cat(format(x, ...), sep = "\n") } #' @export as.character.packages_info <- function(x, ...) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) format(x, ...) } sessioninfo/R/osname.R0000644000176200001440000000107014152377737014435 0ustar liggesusers #' Human readable name of the current operating system #' #' For example Windows 8.1 instead of Windows version 6.3.9600. #' On macOS it includes the code names, on Linux it includes the #' distribution names and codenames if appropriate. #' #' It uses [utils::sessionInfo()], but simplifies its output a bit #' on Windows, to make it more concise. #' #' @return A character scalar. #' #' @export os_name <- function() { x <- suppressWarnings(utils::sessionInfo("base")$running) if (is.null(x)) return(NA_character_) x <- gsub("Service Pack", "SP", x) x } sessioninfo/R/loaded-packages.R0000644000176200001440000000343114152377737016162 0ustar liggesusers #' @importFrom utils packageVersion loaded_packages <- function() { get_package_info(loadedNamespaces()) } attached_packages <- function() { packages <- intersect( loadedNamespaces(), sub("^package:", "", search()) ) get_package_info(packages) } installed_packages <- function() { pkgs <- rownames(utils::installed.packages(noCache = TRUE)) dependent_packages(pkgs, dependencies = FALSE) } get_package_info <- function(packages) { ## 'base' is special, because getNamespaceInfo does not work on it. ## Luckily, the path for 'base' is just system.file() spackageVersion <- function(pkg) { ## Error may happen if the package was loaded, and then removed from ## the disk. In this case we'll have NA tryCatch( as.character(packageVersion(pkg, lib.loc = .libPaths())), error = function(e) NA_character_) } packages <- setdiff(packages, "base") loadedversion <- vapply(packages, getNamespaceVersion, "") ondiskversion <- vapply(packages, spackageVersion, "") path <- vapply( packages, function(p) system.file(package = p, lib.loc = .libPaths()), character(1)) ## If we can't fine the package on disk, have NA instead of "" path[path == ""] <- NA_character_ loadedpath <- vapply(packages, getNamespaceInfo, "", which = "path") attached <- paste0("package:", packages) %in% search() res <- data.frame( package = c(packages, "base"), ondiskversion = c(ondiskversion, spackageVersion("base")), loadedversion = c(loadedversion, getNamespaceVersion("base")), path = c(path, system.file()), loadedpath = c(loadedpath, NA_character_), attached = c(attached, TRUE), stringsAsFactors = FALSE, row.names = NULL ) res <- res[match(sort_ci(res$package), res$package), ] row.names(res) <- NULL res } sessioninfo/R/python-info.R0000644000176200001440000000256414152377737015436 0ustar liggesusers should_show_python <- function(pkgs) { "reticulate" %in% pkgs || (isNamespaceLoaded("reticulate") && reticulate::py_available(initialize = FALSE)) } #' Python configuration #' #' @return #' Returns a [reticulate::py_config] object, which also has the #' `python_info` class. It is a named list of values. #' #' If reticulate is not installed or Python is not configured, #' then it return a `python_info` object that is a character vector, and #' it does not have a `py_config` class. #' #' @export #' @examplesIf FALSE #' python_info() #' session_info(info = "all") python_info <- function() { conf <- if (isNamespaceLoaded("reticulate") && reticulate::py_available(initialize = FALSE)) { tryCatch( reticulate::py_config(), error = function(err) { c("`reticulate::py_config()` failed with error:", conditionMessage(err)) } ) } else { "Python is not available" } class(conf) <- unique(c("python_info", class(conf), "list")) conf } #' @export format.python_info <- function(x, ...) { x <- NextMethod(x, ...) paste0(" ", unlist(strsplit(x, "\n", fixed = TRUE))) } #' @export as.character.python_info <- function(x, ...) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) format(x, ...) } #' @export print.python_info <- function(x, ...) { cat(format(x, ...), sep = "\n") } sessioninfo/R/compare.R0000644000176200001440000002417714152377737014616 0ustar liggesusers #' Compare session information from two sources #' #' @param old,new A `session_info` object (the return value of #' [session_info()]), or a pointer to [session_info()] output. See details #' below. #' @param ... Passed to any new [session_info()] calls. #' #' @details #' Various way to specify `old` and `new`: #' * A `session_info` object. #' * `"local"` runs [session_info()] in the current #' session, and uses its output. #' * `"clipboard"` takes the session info from the system clipboard. #' If the clipboard contains a URL, it is followed to download the #' session info. #' * A URL starting with `http://` or `https://`. `session_diff` searches #' the HTML (or text) page for the session info header to find the session #' info. #' #' @export #' @examplesIf FALSE #' session_diff() session_diff <- function(old = "local", new = "clipboard", ...) { oldname <- get_symbol_name(substitute(old)) newname <- get_symbol_name(substitute(new)) old <- get_session_info(old, oldname %||% "old", ...) new <- get_session_info(new, newname %||% "new", ...) ret <- list( old = old, new = new, diff = session_diff_text(old$text, new$text) ) class(ret) <- c("session_diff", "list") ret } #' @export format.session_diff <- function(x, ...) { c( cli::style_bold(paste0("--- ", substr(x$old$name, 1, 78))), cli::style_bold(paste0("+++ ", substr(x$new$name, 1, 78))), format(x$diff, context = Inf) ) } #' @export print.session_diff <- function(x, ...) { writeLines(format(x, ...)) } get_session_info <- function(src, name = NULL, ...) { si <- if (is_string(src) == 1 && src == "local") { get_session_info_local(...) } else if (is_string(src) == 1 && src == "clipboard") { get_session_info_clipboard() } else if (is_string(src) && grepl("https?://", src)) { get_session_info_url(src) } else { get_session_info_literal(src) } if (is.null(si$name)) si$name <- name si } get_session_info_local <- function(...) { si <- session_info(...) old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) list(arg = "local", si = si, text = format(si)) } get_session_info_clipboard <- function() { cnt <- clipboard_read() if (is_string(cnt) && cnt == "clipboard") { si <- list(arg = "clipboard", si = cnt, text = cnt) } else { si <- get_session_info(cnt) } si$arg <- "" si } get_session_info_url <- function(url) { tmp <- tempfile("session-diff-") on.exit(unlink(tmp), add = TRUE) suppressWarnings(utils::download.file(url, tmp, quiet = TRUE, mode = "wb")) html <- readLines(url, warn = FALSE, encoding = "UTF-8") find_session_info_in_html(url, html) } find_session_info_in_html <- function(url, lines) { purl <- parse_url(url) re_start <- "[-=\u2500\u2550][ ]Session info[ ]" cand <- grep(re_start, lines) if (length(cand) == 0) stop("Cannot find session info at '", url, "'.") # check if the URL has an anchor and that the anchor exists in HTML # if yes, then we "skip" there if (purl$anchor != "") { anch <- which( grepl(paste0(" id=\"", purl$anchor, "\""), lines, fixed = TRUE) | grepl(paste0(" id='", purl$anchor, "'"), lines, fixed = TRUE) | grepl(paste0(" id = \"", purl$anchor, "\""), lines, fixed = TRUE) | grepl(paste0(" id = '", purl$anchor, "'"), lines, fixed = TRUE) )[1] if (!is.na(anch) && any(anch < cand)) { lines <- lines[anch:length(lines)] cand <- grep(re_start, lines) } else { url <- sub(paste0("#", purl$anchor), "", url) } } lines <- lines[cand[1]:length(lines)] lines[1] <- sub(paste0("^.*(", re_start, ")"), "\\1", lines[1]) grepl_end <- function(lines) { grepl("^(#>)?[ ]*\\[[0-9]\\] ", lines) | grepl("^(#>)?[ ]*[-\u2500]+$", lines) } end <- which(grepl_end(lines))[1] if (is.na(end)) stop("Cannot parse session info from '", url, "'.") while (end < length(lines) && grepl_end(lines[end + 1])) { end <- end + 1 } si <- get_session_info_literal(lines[1:end]) si$arg <- url si$name <- url si } parse_url <- function (url) { re_url <- paste0( "^(?[a-zA-Z0-9]+)://", "(?:(?[^@/:]+)(?::(?[^@/]+))?@)?", "(?[^/]+)", "(?[^#]*)", "#?(?.*)$" ) re_match(url, re_url)$groups } get_session_info_literal <- function(si) { if (inherits(si, "session_info")) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) list(arg = si, si = si, text = format(si)) } else if (is.character(si)) { # in case it has ANSI sequences text <- cli::ansi_strip(si) # Might be a single string text <- unlist(strsplitx(text, "\n", fixed = TRUE)) # reprex has the knitr output prefix, remove it # order is important here text <- sub("^#>[ ]?", "", text) text <- sub("^#[>#]?[ ]?", "", text) check_session_info(text) list(arg = si, si = si, text = text) } else { stop("Could not interpret a `", class(si), "` as a session info.") } } # strsplit("", "\n") -> character(), but it should be the empty string, # so we fix this. strsplitx <- function(...) { lapply(strsplit(...), paste0, "") } check_session_info <- function(x) { if (!any(grepl("[-=\u2500\u2550] Session info", x))) { warning("This does not look like a session info: '", beginning(x), "'.") } } beginning <- function(x) { x123 <- utils::head(unlist(strsplit(x, "\n", fixed = TRUE)), 3) trimws(substr(paste0(x123, sep = "\n"), 1, 100)) } session_diff_text <- function(old, new) { old <- enc2utf8(old) new <- enc2utf8(new) old <- diff_drop_empty(old) new <- diff_drop_empty(new) old <- diff_no_date(old) new <- diff_no_date(new) min <- diff_min_line(c(old, new)) old <- diff_fix_lines(old, min) new <- diff_fix_lines(new, min) # expand thinner package info to match the wider one # do not error, in case we cannot parse sessioninfo output suppressWarnings(tryCatch({ exp <- expand_diff_text(old, new) old <- exp$old new <- exp$new }, error = function(e) NULL)) old2 <- gsub("\\s+", " ", old) new2 <- gsub("\\s+", " ", new) diff <- cli::diff_chr(old2, new2) diff$old <- old diff$new <- new diff } # drop leading and trailing empty lines diff_drop_empty <- function(x) { len <- length(x) if (len == 0) return(x) empty <- rle(grepl("^\\s*$", x)) pre <- if (empty$values[1]) { 1:empty$lengths[1] } post <- if (utils::tail(empty$values, 1)) { (len - utils::tail(empty$lengths, 1) + 1):len } del <- as.integer(c(pre, post)) if (length(del)) x <- x[-del] x } # Drop the first `date` line diff_no_date <- function(x) { date <- grep("^[ ]*date[ ]+[0-9][0-9][0-9][0-9]-", x) if (length(date) > 0) { x <- x[-date[1]] } x } # Calculate the minimum width of the header lines diff_min_line <- function(x) { lines <- c( grep("[-\u2500][-\u2500][-\u2500]$", x), grep("[=\u2550][=\u2550][=\u2550]$", x) ) min(c(80, cli::utf8_nchar(x[lines], "width"))) } diff_fix_lines <- function(x, w) { slines <- grepl("[-\u2500]+$", x) dlines <- grepl("[=\u2550]+$", x) x[slines] <- gsub("[-\u2500]", cli::symbol$line, x[slines]) x[dlines] <- gsub("[=\u2550]", cli::symbol$double_line, x[dlines]) x[slines] <- substr(x[slines], 1, w) x[dlines] <- substr(x[dlines], 1, w) x } expand_diff_text <- function(old, new) { opkgs <- parse_pkgs(old) npkgs <- parse_pkgs(new) if (is.null(opkgs) || is.null(opkgs)) return(list(old = old, new = new)) # Add the "!" column if needed if ("!" %in% names(opkgs$pkgs) || "!" %in% names(npkgs$pkgs)) { if (! "!" %in% names(opkgs$pkgs)) { opkgs$pkgs <- cbind("!" = "", opkgs$pkgs, stringsAsFactors = FALSE) } if (! "!" %in% names(npkgs$pkgs)) { npkgs$pkgs <- cbind("!" = "", npkgs$pkgs, stringsAsFactors = FALSE) } } # If the column names differ, we keep it as is onms <- names(opkgs$pkgs) nnms <- names(npkgs$pkgs) if (length(onms) != length(nnms) || any(onms != nnms)) { return(list(old = old, new = new)) } cmn <- rbind(opkgs$pkgs, npkgs$pkgs) oldopts <- options(cli.num_colors = 1) on.exit(options(oldopts), add = TRUE) fmt <- format_df(cmn) oend <- opkgs$end - opkgs$begin + 1L nend <- oend + npkgs$end - npkgs$begin fmt_old <- c(fmt[1], fmt[2:oend]) fmt_new <- c(fmt[1], fmt[(oend+1):(nend)]) old <- insert_instead(old, opkgs$begin, opkgs$end, fmt_old) new <- insert_instead(new, npkgs$begin, npkgs$end, fmt_new) list(old = old, new = new) } insert_instead <- function(orig, from, to, new) { pre <- if (from > 1) orig[1:(from-1)] pst <- if (to < length(orig)) orig[(to+1):length(orig)] c(pre, new, pst) } parse_pkgs <- function(lines) { begin <- grep("^[-\u2500] Packages ", lines) + 1 # back out if no Packages header if (length(begin) != 1 || length(begin) > length(lines)) return(NULL) # now find the end end <- begin + grep( "^\\s*[!a-zA-Z]", lines[begin:length(lines)], invert = TRUE, perl = TRUE )[1] - 2 if (is.na(end)) end <- length(lines) pkgs <- parse_pkgs_section(lines[begin:end]) list(begin = begin, end = end, pkgs = pkgs) } parse_pkgs_section <- function(lines) { lines[1] <- sub(" date ", " date (UTC) ", fixed = TRUE, lines[1]) hdr <- sub("date (UTC)", "date-(UTC)", fixed = TRUE, lines[1]) wth <- find_word_lengths(hdr) wth[length(wth)] <- max(nchar(lines)) df <- utils::read.fwf(textConnection(lines), widths = wth) df[] <- lapply(df, trimws) names(df) <- as.character(df[1,]) df <- df[-1, , drop = FALSE] rownames(df) <- NULL df } find_word_lengths <- function(x) { # add a dummy word to the end for simplicity tmp <- paste0(gsub("[^\\s]", "X", x, perl = TRUE), " X") # word & ws lengths, but first absorb leading space into the first word ltr <- strsplit(tmp, "")[[1]] rl <- rle(ltr) if (ltr[1] == " ") { rl$lengths[2] <- rl$lengths[2] + rl$lengths[1] rl$lengths <- rl$lengths[-1] rl$values <- rl$values[-1] } # positions of "X" and " " parts pos <- cumsum(c(1, rl$lengths)) # lengths of words, this drops the dummy word wpos <- which(rl$values == "X") pos[wpos[-1]] - pos[wpos[-length(wpos)]] } get_symbol_name <- function(x) { if (is.symbol(x)) { as.character(x) } else if (is_string(x)) { x } } sessioninfo/R/session-info.R0000644000176200001440000001074414153361604015562 0ustar liggesusers #' Print session information #' #' This is [utils::sessionInfo()] re-written from scratch to both exclude #' data that's rarely useful (e.g., the full collate string or base packages #' loaded) and include stuff you'd like to know (e.g., where a package was #' installed from). #' #' @details #' Columns in the *printed* package list: #' * `package`: package name #' * `*`: whether the package is attached to the search path #' * `version`: package version. If the version is marked with `(!)` that #' means that the loaded and the on-disk version of the package are #' different. #' * `date`: when the package was built, if this information is available. #' This is the `Date/Publication` or the `Built` field from #' `DESCRIPTION`. (These are usually added automatically by R.) #' Sometimes this data is not available, then it is `NA`. #' * `source`: where the package was built or installed from, if available. #' Examples: `CRAN (R 3.3.2)`, `Github (r-lib/pkgbuild@8aab60b)`, #' `Bioconductor`, `local`. #' #' See [package_info()] for the list of columns in the data frame that #' is *returned* (as opposed to *printed*). #' #' @inheritParams package_info #' @param info What information to show, it can be `"auto"` to choose #' automatically, `"all"` to show everything, or a character vector #' with elements from: #' * `"platform"`: show platform information via [platform_info()], #' * `"packages"`: show package information via [package_info()], #' * `"python"`: show Python configuration via [python_info()], #' * `"external"`: show information about external software, via #' [external_info()]. #' @param to_file Whether to print the session information to a file. #' If `TRUE` the name of the file will be `session-info.txt`, but #' `to_file` may also be a string to specify the file name. #' #' @return #' A `session_info` object. #' #' If `to_file` is not `FALSE` then it is #' returned invisibly. (To print it to both a file and to the screen, #' use `(session_info(to_file = TRUE))`.) #' #' @export #' @examplesIf FALSE #' session_info() #' session_info("sessioninfo") session_info <- function( pkgs = c("loaded", "attached", "installed")[1], include_base = FALSE, info = c("auto", "all", "platform", "packages", "python", "external"), dependencies = NA, to_file = FALSE) { if (missing(info)) info <- "auto" choices <- c("platform", "packages", "python", "external") if (info != "auto" && info != "all") { info <- match.arg(info, choices, several.ok = TRUE) } if ("all" %in% info) { info <- choices } else if ("auto" %in% info) { info <- c( "platform", "packages", if (should_show_python(pkgs)) "python" ) } stopifnot(is_flag(to_file) || is_string(to_file)) if (is_flag(to_file) && to_file) to_file <- "session-info.txt" si <- structure( drop_null(list( platform = if ("platform" %in% info) platform_info(), packages = if ("packages" %in% info) { package_info( pkgs, include_base = include_base, dependencies = dependencies ) }, external = if ("external" %in% info) external_info(), python = if ("python" %in% info) python_info() )), class = c("session_info", "list") ) if (is_string(to_file)) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) writeLines(format(si), to_file) invisible(si) } else { si } } #' @export format.session_info <- function(x, ...) { has_platform <- !is.null(x$platform) c(if (!"platform" %in% names(x)) { rule("Session info", double = TRUE) }, if ("platform" %in% names(x)) { c(rule(paste("Session info")), format(x$platform), "" ) }, if ("packages" %in% names(x)) { c(rule("Packages"), format(x$packages), "") }, if ("external" %in% names(x)) { c(rule("External software"), format(x$external), "") }, if ("python" %in% names(x)) { c(rule("Python configuration"), format(x$python), "") }, rule() ) } #' @export as.character.session_info <- function(x, ...) { old <- options(cli.num_colors = 1) on.exit(options(old), add = TRUE) format(x, ...) } has_emoji <- function () { if (isTRUE(opt <- getOption("sessioninfo.emoji"))) { TRUE } else if (identical(opt, FALSE)) { FALSE } else if (!cli::is_utf8_output()) { FALSE } else { Sys.info()[["sysname"]] == "Darwin" } } #' @export print.session_info <- function(x, ...) { cat(format(x), sep = "\n") } sessioninfo/NEWS.md0000644000176200001440000001026214153372172013715 0ustar liggesusers # 1.2.2 * This version does not add an emoji hash to the output. * The `source` column of the output data frame of `package_info()` (also part of `session_info()`), now contains the full SHA for packages installed from GitHub, instead of only the first seven characters. This makes it easier to use the SHA programmatically. Note that this does not affect formatting and printing, which still use the abbreviated SHA. (@muschellij2, #61). * RStudio Package Manager (RSPM) and other repository sources are now shown in the `source` column, if they set the `Repository` field in `DESCRIPTION`. # 1.2.1 * `package_info()` and `session_info()` now do not fail if the version number of an installed package is invalid. * Better aliases for the list of attached, loaded and installed packages in `package_inf()` and `session_info()`. # 1.2.0 * New function `external_info()`, information about external software. It can be also requested with the new `info` argument of `session_info()` (@llrs). * New function `python_info()`, information about Python configuration. It is automatically included in `session_info()` if the reticulate package is loaded and Python is available. You can also request it manually via the new `info` argument of `session_info()` (#33). * The output of `session_info()` now has an emoji hash, consisting of three emojis. This allows quick comparison of two session infos (#26). * All `*_info()` functions use ANSI colors on systems that support them. In particular, it highlights unusual package versions and sources, and possible package problems (#3). * New `session_diff()` function, to compare two session infos from various sources (#6). * `session_info()` has a new argument named `info`, to select which parts of the session information should be printed. * `session_info()` now has a `to_file` argument, to write the output to a file (#30). * `session_inf()` has a `dependencies` argument now, and passes it to `package_info()`. * `package_info()` and `session_info()` can now list the attached or installed packages, see the `pkgs` argument in the manual for details (#42). * `platform_info()` and `session_info()` now include the Windows build number in the output (#40). * sessioninfo now never wraps the output if the screen is too narrow (#31). * All `*_info()` functions have a `format()` S3 method now. * `platform_info()` and `session_info()` now include the RStudio version if the R session is in RStudio (#29). * The `source` column of the package list is now more informative. # 1.1.1 * `package_info()` and `session_info()` now detect locally installed packages correctly if they have an empty `biocViews` field in `DESCRIPTION (@llrs, #25) * `package_info()` and `session_info()` now handle the case when a loaded package was removed from the disk. # 1.1.0 * `package_info()` now has a `dependencies` argument, to filter the type of dependent packages in the output (#22). * `session_info()` and `package_info()` now show the library search path, and also which library each package was loaded from. They also warn if the on-disk version of the package has a different path than the loaded version (#9, #20). * `package_info()`'s `ondiskversion` entry is now correct. * `session_info()` and `package_info()` now verify the MD5 hashes of DLL files on Windows, and warns for micmatches, as these are usually broken packages (#12, #16). * We use now the cli package, instead of clisymbols, and this fixes printing bugs in LaTeX documents (#14). * `session_info()` and `platform_info()` now include the `LC_CTYPE` locale category (@patperry, #11) * `session_info()` and `package_info()` now print source of the CRAN packages in uppercase, always, even if they were installed by devtools. * `session_info()` and `platform_info()` now handle the case when `utils::sessionInfo()$running` is `NULL` (@HenrikBengtsson, #7). * `session_info()` and `package_info()` now only list loaded versions for namespaces which are already loaded. This only makes a difference if the `pkgs` argument is given (#4). * Do not consult the `max.print` option, for platform and package info (@jennybc, #13). # 1.0.0 First public release. sessioninfo/MD50000644000176200001440000000647214153374352013141 0ustar liggesusers4de58a4c8ba4cf275b3c6e2bdb7c8f9e *DESCRIPTION c1a316fbe0914a8550965ad64113bb38 *NAMESPACE 7036cbf831ce4482537ac5296224edeb *NEWS.md cc07f49e618b81dd45bccb8bcd366019 *R/clipboard.R a7f2ee188bd33b24daa377b06047b440 *R/compare.R 94bd6140788030074319ff1c3c08bad3 *R/dependent-packages.R 872982992113b732cacf4476af221dd6 *R/external-info.R 7bdd14fbb1151bad94895d78b936d32c *R/loaded-packages.R 7a250a529661d3f47169f5e670946d2e *R/osname.R 2ca572682db6ead691bcef299c56e931 *R/package-info.R c11f0f7253128318b438ff3cd44c2508 *R/platform-info.R a500c1a3d23c5caf1dabc8e2fcecae6a *R/printing.R fe51563c6b6575d0d5196d6cde098133 *R/python-info.R 260e9f54b6f663b907494ad53dd14d53 *R/rematch2.R b550e29bac96ae73bc4b451afd35b263 *R/session-info.R 0f2234321806b6aebc927281c55c6e76 *R/sysdata.rda 9e23d84a70cca80be5c417e2745552fa *R/utils.R 57640d2ee6f4544d7050a0673e5b10f0 *README.md d9e5097113b41a5f415deda6b9b17832 *man/external_info.Rd 46c3a8eed9461d759ef19397193f52a2 *man/figures/session-info2.svg f013297d5c2f3006735392a759a84b9e *man/os_name.Rd 8e43efe349c360f925526d478a90d645 *man/package_info.Rd af284b52558ec10d45166c9ec1f8c923 *man/platform_info.Rd 08b11a60cc2c6189d7249ea36595cd54 *man/python_info.Rd 9513781d5b75ee0a21a0f02fbd7c5e58 *man/session_diff.Rd 2f429bc09be5886e5c5d79eac777d0d0 *man/session_info.Rd 0e823279172bfb7590ddf30053becad9 *tests/testthat.R 47fc217e5a616725a486302c3632f671 *tests/testthat/_snaps/diff.md d1570db3da339a5bb3db7c85673f984f *tests/testthat/fixtures/MD5 ed4e99dfc45e8190839ec97ee3bbd655 *tests/testthat/fixtures/biobase.rda 23aa7627516d2e036556771d4e444e84 *tests/testthat/fixtures/descs.rda 2ec46780c0a6b9b42f84b87fec7aac43 *tests/testthat/fixtures/devtools-deps.rda c538f1d48dabb29bde6847a1aa0f11db *tests/testthat/fixtures/devtools-info-unix.rda 4142c8cc868e97273cd00ccd7168bf0d *tests/testthat/fixtures/devtools-info-windows.rda b0297cc88f9e44fb164a4d74e5f7c650 *tests/testthat/fixtures/devtools.rda bcef3a0e2f95c7ee4e5dce665d0ce603 *tests/testthat/fixtures/fsdfgwetdhsdfhq4yqh_0.0.0.9000.tar.gz af3e2fe7bb2a58d80104b73b70539bf5 *tests/testthat/fixtures/gh.html.gz e33873feb91bc7e55254cb0163048920 *tests/testthat/fixtures/installed.rda 7515f53060f9724e47c093dba5487141 *tests/testthat/fixtures/lines1.txt 1abcab5ec2911f7e305053e64bf17605 *tests/testthat/fixtures/lines2.txt 264c91bc5e6e1490b167849ee1f78d04 *tests/testthat/fixtures/lines3.txt 14bab53560a4f2f79d0f3c5b99e0d868 *tests/testthat/fixtures/lines4.txt 19bee1c35412de7d79c770fd0c3b03dd *tests/testthat/fixtures/memoise.rda 8b73286945f1227d87894c240d55debf *tests/testthat/fixtures/no-remote-repo.rda 2b97d22ff72bfb169197214a58f0dc0e *tests/testthat/fixtures/no-sha.rda e7a38f6ef9d4804f81221fabd41ec27b *tests/testthat/test-dependent-packages.R 755bd174e447411f582642a95b232362 *tests/testthat/test-diff.R adc988c381a23fd634e6d5dbde4f0a71 *tests/testthat/test-loaded-packages.R 8f17943cf5b6008973d719ee39528728 *tests/testthat/test-os-name.R 9dc5e8c248b2e294ef26a59756e6f96b *tests/testthat/test-package-info.R 6fc2a8c25e7e200142d5b60d10b8611f *tests/testthat/test-platform-info.R ef86c54a0d4694229521540c9a6ef4a0 *tests/testthat/test-printing.R 9d33f770f648b4018c9abc010a770a5f *tests/testthat/test-session-info.R e6919f3534f256386cf7205981e3e713 *tests/testthat/test-utils.R 1fba4c15191c361814e05b1ca074725b *tests/testthat/test-warnings.R bfd31e2e45480fe56637ff10b18db692 *tools/bad-emoji.R