---
title: "Getting Started with checktor"
vignette: >
  %\VignetteIndexEntry{Getting Started with checktor}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
knitr:
  opts_chunk:
    collapse: true
    comment: '#>'
---

```{r}
#| label: setup
#| include: false
library(checktor)
```

## The gap checktor fills

`R CMD check` answers one question well: does this package build and run? It is
silent on the question that actually decides your submission: will a CRAN
volunteer, reading by hand, send it back? Those are different questions, and the
space between them is where afternoons disappear. A title that isn't in title
case. A missing `\value{}` tag. A stray `T` where you meant `TRUE`.

`checktor` is the specialist your build refers you to before that appointment.
It runs the extra-CRAN checks that live in the Repository Policy and reviewers'
long memories but nowhere in the standard toolchain, and, true to the name, it
gives you a checkup, a diagnosis, and a prescription.

## Installation

`checktor` lives on GitHub for now; once it reaches CRAN you will be able to
`install.packages("checktor")`. Until then, install the development version:

```{r eval=FALSE}
# install.packages("pak")
pak::pak("coatless-rpkg/checktor")
```

## A first checkup

`checktor()` examines a package directory. So we can watch it work without
maiming your own package, we will point it at a throwaway package built around
one deliberately bad file:

```{r}
pkg <- example_diagnose_scenario("code_examples/tf_usage_bad.R",
                                 show_content = FALSE)

results <- checktor(pkg, verbose = FALSE, progress = FALSE)
results
```

That is the bedside summary: which of the five categories (code, DESCRIPTION,
documentation, general, and CRAN policy) need attention, and an overall verdict.
On your own package the call is just `checktor()`. For the full catalogue of
what each category checks, see the
[function reference](https://r-pkg.thecoatlessprofessor.com/checktor/reference/index.html).

## Reading the results as data

The printed report is for humans. When you want to *compute* on the findings,
filter them, count them, fold them into a report of your own, reach for the
accessors. They return plain data frames, so you never spelunk through nested
lists.

```{r}
summary(results)   # one row per category
```

```{r}
issues(results)    # one row per issue, with file and line
```

`tidy(results)` gives one row per check, passed or not, and `as.data.frame()` is
its alias. Three predicates answer the yes/no questions directly:

```{r}
is_healthy(results)
n_issues(results)
failed_checks(results)
```

Each accessor also works on a single category, as in `issues(results$code_issues)`,
or on a single check.

## The one-line gate

For scripts and pre-submission checklists, `checkup()` collapses the whole
diagnosis to a single verdict, `TRUE` when the package is clean:

```{r}
checkup(pkg)
```

It is built to be the last word in a shell one-liner; the
[checktor in Continuous Integration](checktor-in-ci.html) vignette puts it in
charge of a GitHub Actions build.

## From diagnosis to treatment

A diagnosis you cannot act on is just bad news. `prescribe()` turns each finding
into a concrete remedy:

```{r eval=FALSE}
prescribe(results)
```

`health_report()` writes the whole consultation to a file, as Markdown, HTML, or
plain text, to keep alongside your `cran-comments.md`:

```{r eval=FALSE}
health_report(results, file = "package-health.md")
health_report(results, file = "package-health.html", format = "html")
```

## Examining one system at a time

Each category runs on its own, which helps when you are fixing one thing and
would rather not hear about the others:

```{r eval=FALSE}
diagnose_code_issues()           # just the R sources
diagnose_description_issues()    # just DESCRIPTION
diagnose_documentation_issues()  # just the .Rd files
diagnose_general_issues()        # size, URLs
diagnose_policy_violations()     # CRAN policy
```

## Turning down the volume

`checktor()` is chatty by design. In a script, quiet it once and every later
call inherits the setting:

```{r eval=FALSE}
configure_doctor(verbose_default = FALSE, progress_default = FALSE)

# or per call
results <- checktor(verbose = FALSE, progress = FALSE)
```

## Where it fits

Run `checktor` in the gap between writing code and `R CMD check`:

```{r eval=FALSE}
devtools::document()
devtools::test()

results <- checktor()  # the extra-CRAN checkup
prescribe(results)     # apply the remedies

devtools::check()      # the standard checks
```

## Conclusion

`checktor` is a checkup, not a cure-all. It complements `R CMD check` and
[`lintr`](https://lintr.r-lib.org) rather than replacing either, and it cannot
replace your judgment about whether a package is worth submitting. What it does
do is the one thing those tools do not: it remembers the hand-enforced CRAN
rules so you do not have to. Run the three together, treat the printed report as
the conversation and the accessors as the data, and a reviewer should find
nothing left to say. That is the entire point.

## See also

- [checktor in Continuous Integration](checktor-in-ci.html): put `checkup()` in
  charge of a GitHub Actions build as a quality gate.
- [Writing Your Own Checks](writing-checks.html): add project-specific checks
  against the parsed syntax tree.
- [Function reference](https://r-pkg.thecoatlessprofessor.com/checktor/reference/index.html):
  the full catalogue of diagnostics.
