Skip to content

WIP: Parsing sessioninfo from the clipboard #66

@krlmlr

Description

@krlmlr

Useful for:

  • understanding GHA successes/failures
  • comparing sessioninfo in a reprex

Needs a bit more work:

  • align platform and package entries so that they can be compared side by side
  • different comparison options: everything, only packages and versions
  • convert - to . in version numbers
  • tests

Happy to maintain it in the longer term if we decide that it's useful.

library(rlang)
library(tibble)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

requireNamespace("waldo")
#> Loading required namespace: waldo

info <- sessioninfo::session_info()
text <- capture.output(print(info))

# text <- clipr::read_clip()

text <- unlist(strsplit(text, "\n"))
text <- grep("^ +$", text, value = TRUE, invert = TRUE)

marker1 <- grep("Session info ────+", text)
if (length(marker1) != 1) {
  abort("Marker not found: Session info")
}
if (length(marker1) > 1) {
  warn("Found more than one marker: Session info")
  marker1 <- marker1[[1]]
}
if (marker1 > 1) {
  warn(paste0("Stripping ", marker1 - 1, " lines ahead of input."))
}

marker2 <- grep("─ Packages ────+", text)
if (length(marker2) != 1) {
  abort("Marker not found: Packages")
}
if (length(marker2) > 1) {
  warn("Found more than one marker: Packages")
  marker2 <- marker2[[1]]
}
if (marker2 < marker1) {
  abort("Bad marker order: Packages before Session info")
}

marker3 <- grep("^ +[[]1[]] ", text)

if (length(marker3) > 1) {
  warn("Found more than one marker: Libraries")
  marker3 <- marker3[[1]]
}

marker4 <- grep("──────+", text)
marker4 <- marker4[marker4 > marker2]

if (length(marker4) != 1) {
  abort("Marker not found: End")
}
if (length(marker4) > 1) {
  warn("Found more than one marker: End")
  marker4 <- marker4[[1]]
}

if (length(marker3) != 1) {
  marker3 <- marker4
}

platform_text <- text[seq2(marker1 + 1, marker2 - 1)]
packages_text <- text[seq2(marker2 + 1, marker3 - 1)]
libraries_text <- text[seq2(marker3, marker4 - 1)]

# FIXME: Treat version mismatch
stopifnot(!grepl("mismatch", libraries_text))

platform_match <- rematch2::re_match(platform_text[-1], "^ +(?<name>[^ ]+) +(?<value>.*)$")[1:2]

platform <- structure(
  as.list(tibble::deframe(platform_match)),
  class = c("platform_info", "list")
)
waldo::compare(platform, info$platform)
#> ✓ No differences

libraries_match <- rematch2::re_match(libraries_text, "^ +[[](?<library>[0-9]+)[]] (?<path>.*)$")[1:2]
stopifnot(as.integer(libraries_match$library) == seq_len(nrow(libraries_match)))
libraries_path <- libraries_match$path

packages_match <-
  rematch2::re_match(
    packages_text[-1],
    "^ +(?<package>[^ ]+) +(?<attached>.) (?<ondiskversion>[0-9][^ ]*) +(?<date>[0-9].*) [[](?<library>[0-9]+)[]] (?<source>.*)$"
  ) %>%
  filter(!is.na(package)) %>%
  mutate(attached = (attached != " ")) %>%
  mutate(library = factor(libraries_path[as.integer(library)], levels = libraries_path)) %>%
  transmute(
    package,
    ondiskversion,
    loadedversion = ondiskversion,
    path = paste0(as.character(library), "/", package),
    loadedpath = path,
    attached,
    is_base = package %in% rownames(installed.packages(priority = "base")),
    date,
    source,
    md5ok = NA,
    library,
    rowname = package
  )

packages <- structure(column_to_rownames(packages_match), class = c("packages_info", "data.frame"))

parsed_info <- structure(
  list(
    platform = platform,
    packages = packages
  ),
  # FIXME: Should we really explicitly inherit from "list" here?
  class = c("session_info", "list")
)

waldo::compare(info, parsed_info)
#> old$packages vs new$packages
#>                                                                                   source
#>   old$packages[30, ]                                                      CRAN (R 4.1.1)
#>   old$packages[31, ]                                                      CRAN (R 4.1.1)
#>   old$packages[32, ]                                                      CRAN (R 4.1.0)
#> - old$packages[33, ] Github (r-lib/sessioninfo@59e1b11a022bac38ea316e4c52f20dfdb72f1b4e)
#> + new$packages[33, ]                                  Github (r-lib/sessioninfo@59e1b11)
#>   old$packages[34, ]                                                      CRAN (R 4.1.1)
#>   old$packages[35, ]                                                      CRAN (R 4.1.0)
#>   old$packages[36, ]                                                      CRAN (R 4.1.1)
#> 
#> old$packages$source[30:36] vs new$packages$source[30:36]
#>   "CRAN (R 4.1.1)"
#>   "CRAN (R 4.1.1)"
#>   "CRAN (R 4.1.0)"
#> - "Github (r-lib/sessioninfo@59e1b11a022bac38ea316e4c52f20dfdb72f1b4e)"
#> + "Github (r-lib/sessioninfo@59e1b11)"
#>   "CRAN (R 4.1.1)"
#>   "CRAN (R 4.1.0)"
#>   "CRAN (R 4.1.1)"

# loaded_info <- readRDS("info.rds")
#
# #all_pkgs <- sort(unique(c(parsed_info$packages$package, loaded_info$packages$package)))
# all_pkgs <- parsed_info$packages$package
#
# parsed_versions <- parsed_info$packages[match(all_pkgs, parsed_info$packages$package), ][c("package", "ondiskversion")]
# loaded_versions <- loaded_info$packages[match(all_pkgs, loaded_info$packages$package), ][c("package", "ondiskversion")]
#
# waldo::compare(parsed_versions, loaded_versions, max_diffs = Inf)

Created on 2021-12-22 by the reprex package (v2.0.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featurea feature request or enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions