1#! /usr/bin/env Rscript
2
3setup_app <- function() {
4  theme <- list(
5    "url" = list(color = "blue"),
6    ".pkg" = list(color = "orange"))
7  start_app(theme = theme, output = "stdout")
8}
9
10load_packages <- function() {
11  tryCatch({
12    library(cliapp)
13    library(pkgsearch)
14    library(docopt)
15    library(prettyunits)
16    error = function(e) {
17      cli_alert_danger(
18            "The {.pkg pkgsearch}, {.pkg prettyunits} and {.pkg docopt} packages are needed!")
19      q(save = "no", status = 1)
20    }
21  })
22}
23
24search <- function(terms, from = 1, size = 5) {
25  load_packages()
26  setup_app()
27  term <- paste(encodeString(quote = '"', terms), collapse = " ")
28  result <- do_query(term, from = from, size = size)
29  format_result(result, from = from, size = size)
30  invisible()
31}
32
33`%||%` <- function(l, r) if (is.null(l)) r else l
34
35do_query <- function(query, from, size) {
36  cli_alert_info("Searching...")
37  pkg_search(query, from = from, size = size)
38}
39
40format_result <- function(obj, from, size) {
41  meta <- attr(obj, "metadata")
42  if (!meta$total) {
43    cli_alert_danger("No results :(")
44    return()
45  }
46
47  cli_alert_success("Found {meta$total} packages in {pretty_ms(meta$took)}")
48  cli_text()
49  cli_div(theme = list(ul = list("list-style-type" = "")))
50  cli_ol()
51
52  lapply(seq_len(nrow(obj)), function(i) format_hit(obj[i,]))
53}
54
55format_hit <- function(hit) {
56  ago <- vague_dt(Sys.time() - hit$date)
57  cli_li()
58  cli_text("{.pkg {hit$package}} {hit$version}  --
59          {.emph {hit$title}}")
60  cli_par()
61  cli_text(hit$description)
62  cli_text("{.emph {ago} by {hit$maintainer_name}}")
63}
64
65parse_arguments <- function() {
66  "Usage:
67    cransearch.R [-h | --help] [ -f from ] [ -n size ] <term>...
68
69Options:
70    -h --help  Print this help message
71    -f first   First hit to include
72    -n size    Number of hits to include
73
74Seach for CRAN packages on r-pkg.org
75  " -> doc
76  docopt(doc)
77}
78
79if (is.null(sys.calls())) {
80  load_packages()
81  opts <- parse_arguments()
82  search(opts$term,
83         from = as.numeric(opts$f %||% 1),
84         size = as.numeric(opts$n %||% 5))
85}
86