From 0bbede781f462221c81eea164851a82c462b93b0 Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:04:05 -0400 Subject: [PATCH 1/6] air format . --- R/arg.R | 57 ++++++++--------- R/class-args.R | 45 +++++++------ R/class-command-args.R | 9 ++- R/command-args.R | 81 +++++++++++++----------- R/super-arg.R | 4 +- R/utils.R | 2 - tests/spelling.R | 10 ++- tests/testthat/test-class-command-args.R | 19 +++--- 8 files changed, 117 insertions(+), 110 deletions(-) diff --git a/R/arg.R b/R/arg.R index 31c4f91..5eaf1e0 100644 --- a/R/arg.R +++ b/R/arg.R @@ -1,4 +1,3 @@ - #' New command argument #' #' Make a new [scribeArg] object @@ -13,25 +12,25 @@ #' @family scribe #' @export new_arg <- function( - aliases = "", - action = arg_actions(), - default = NULL, - convert = scribe_convert(), - n = NA_integer_, - info = NULL, - options = list(), - stop = c("none", "hard", "soft"), - execute = invisible + aliases = "", + action = arg_actions(), + default = NULL, + convert = scribe_convert(), + n = NA_integer_, + info = NULL, + options = list(), + stop = c("none", "hard", "soft"), + execute = invisible ) { scribeArg$new( aliases = aliases, - action = action, + action = action, default = default, convert = convert, - n = n, - info = info, + n = n, + info = info, options = options, - stop = stop, + stop = stop, execute = execute ) } @@ -78,19 +77,19 @@ scribe_version_arg <- function() { # nolint next: cyclocomp_linter. arg_initialize <- function( - self, - aliases = "", - action = arg_actions(), - default = NULL, - convert = scribe_convert(), - n = NA_integer_, - info = NA_character_, - options = list(), - stop = c("none", "hard", "soft"), - execute = invisible + self, + aliases = "", + action = arg_actions(), + default = NULL, + convert = scribe_convert(), + n = NA_integer_, + info = NA_character_, + options = list(), + stop = c("none", "hard", "soft"), + execute = invisible ) { - action <- match.arg(action, arg_actions()) - info <- info %||% NA_character_ + action <- match.arg(action, arg_actions()) + info <- info %||% NA_character_ options <- options %||% list() if (action == "default") { @@ -314,7 +313,7 @@ arg_get_help <- function(self) { list = { left <- paste( to_string(self$get_aliases(), sep = ", "), - sprintf("[%s]", if (self$n == 1) "ARG" else sprintf("..%i", self$n)) + sprintf("[%s]", if (self$n == 1) "ARG" else sprintf("..%i", self$n)) ) right <- self$info @@ -374,7 +373,7 @@ arg_get_name <- function(self, clean = TRUE) { nm } -arg_get_action <- function(self) { +arg_get_action <- function(self) { self$action %||% character() } @@ -508,7 +507,7 @@ is_arg <- function(x) { methods::is(x, "scribeArg") } -ARG_PAT <- "^-[a-z]$|^---?[a-z]+$|^--?[a-z](+[-]?[a-z]+)+$" # nolint: object_name_linter, line_length_linter. +ARG_PAT <- "^-[a-z]$|^---?[a-z]+$|^--?[a-z](+[-]?[a-z]+)+$" # nolint: object_name_linter, line_length_linter. arg_actions <- function() { c("default", "list", "flag", "dots") diff --git a/R/class-args.R b/R/class-args.R index f6a58b9..c5ce92f 100644 --- a/R/class-args.R +++ b/R/class-args.R @@ -1,4 +1,3 @@ - #' {scribe} argument #' #' ReferenceClass object for managing arguments @@ -75,32 +74,32 @@ # nolint next: object_name_linter. scribeArg <- methods::setRefClass( "scribeArg", - fields = list( - aliases = "character", - action = "character", - default = "ANY", - convert = "ANY", - n = "integer", - info = "character", - options = "list", + fields = list( + aliases = "character", + action = "character", + default = "ANY", + convert = "ANY", + n = "integer", + info = "character", + options = "list", positional = "logical", - resolved = "logical", - value = "ANY", - stop = "character", - execute = "function" + resolved = "logical", + value = "ANY", + stop = "character", + execute = "function" ) ) scribeArg$methods( initialize = function( aliases = "", - action = arg_actions(), + action = arg_actions(), default = NULL, convert = scribe_convert(), - n = NA_integer_, - info = NA_character_, + n = NA_integer_, + info = NA_character_, options = list(), - stop = c("none", "hard", "soft"), + stop = c("none", "hard", "soft"), execute = invisible ) { " @@ -109,15 +108,15 @@ scribeArg$methods( See \\strong{fields} for parameter information. " arg_initialize( - self = .self, + self = .self, aliases = aliases, - action = action, + action = action, default = default, convert = convert, - n = n, - info = info, + n = n, + info = info, options = options, - stop = stop, + stop = stop, execute = execute ) }, @@ -186,7 +185,7 @@ scribeSuperArg$methods( } arg_initialize( - self = .self, + self = .self, aliases = aliases, ... ) diff --git a/R/class-command-args.R b/R/class-command-args.R index a3da5d2..e1fe0b9 100644 --- a/R/class-command-args.R +++ b/R/class-command-args.R @@ -1,4 +1,3 @@ - #' {scribe} command arguments #' #' Reference class object for managing command line arguments. @@ -205,13 +204,13 @@ scribeCommandArgs$methods( add_argument = function( ..., - action = arg_actions(), + action = arg_actions(), default = NULL, convert = scribe_convert(), - n = NA_integer_, - info = NULL, + n = NA_integer_, + info = NULL, options = list(), - stop = c("none", "hard", "soft"), + stop = c("none", "hard", "soft"), execute = invisible ) { "Add a \\link{scribeArg} to \\code{args} diff --git a/R/command-args.R b/R/command-args.R index abf829c..2f4e598 100644 --- a/R/command-args.R +++ b/R/command-args.R @@ -1,4 +1,3 @@ - #' Command line arguments #' #' Make a new [scribeCommandArgs] object @@ -21,10 +20,10 @@ #' @family scribe #' @export command_args <- function( - x = NULL, - include = getOption("scribe.include", c("help", "version", NA_character_)), - string = NULL, - super = include + x = NULL, + include = getOption("scribe.include", c("help", "version", NA_character_)), + string = NULL, + super = include ) { if (is.null(string)) { if (is.null(x)) { @@ -46,10 +45,10 @@ command_args <- function( # wrappers ---------------------------------------------------------------- ca_initialize <- function( - self, - input = "", - include = c("help", "version", NA_character_), - supers = include + self, + input = "", + include = c("help", "version", NA_character_), + supers = include ) { # default values self$initFields( @@ -85,10 +84,14 @@ ca_initialize <- function( self$add_argument(scribe_version_arg()) } - self$field("supers", c( - if ("help" %in% supers) scribe_help_super(), - if ("version" %in% supers) scribe_version_super() - ) %||% list()) + self$field( + "supers", + c( + if ("help" %in% supers) scribe_help_super(), + if ("version" %in% supers) scribe_version_super() + ) %||% + list() + ) self$field("input", as.character(input) %||% character()) self$field("working", self$input) @@ -182,7 +185,7 @@ ca_resolve <- function(self) { # reset if not unsuccessful on.exit( - expr = if (!self$resolved) { + expr = if (!self$resolved) { self$field("working", self$get_input()) self$field("stop", "none") }, @@ -220,10 +223,13 @@ ca_resolve <- function(self) { arg_parse_value(arg, self) } - self$field("values", structure( - lapply(args, function(arg) arg$get_value()), - names = vapply(args, function(arg) arg$get_name(), NA_character_) - )) + self$field( + "values", + structure( + lapply(args, function(arg) arg$get_value()), + names = vapply(args, function(arg) arg$get_name(), NA_character_) + ) + ) if (length(ca_get_working(self)) && self$stop == "none") { warning( @@ -263,10 +269,10 @@ ca_set_input <- function(self, value) { } ca_get_values <- function( - self, - empty = FALSE, - super = FALSE, - included = FALSE + self, + empty = FALSE, + super = FALSE, + included = FALSE ) { values <- self$values @@ -320,16 +326,16 @@ ca_get_args <- function(self, included = TRUE, super = FALSE) { } ca_add_argument <- function( - self, - ..., - action = arg_actions(), - default = NULL, - convert = scribe_convert(), - n = NA_integer_, - info = NULL, - options = list(), - stop = c("none", "hard", "soft"), - execute = invisible + self, + ..., + action = arg_actions(), + default = NULL, + convert = scribe_convert(), + n = NA_integer_, + info = NULL, + options = list(), + stop = c("none", "hard", "soft"), + execute = invisible ) { if (is_arg(..1)) { arg <- ..1 @@ -342,20 +348,21 @@ ca_add_argument <- function( warning( "Aliases should be passed without names.\n", "Check that you have not passed a bad field name:\n", - " names: ", to_string(nms[bad], sep = ", "), + " names: ", + to_string(nms[bad], sep = ", "), call. = FALSE ) } arg <- new_arg( aliases = aliases, - action = action, + action = action, default = default, convert = convert, - n = as.integer(n), - info = info, + n = as.integer(n), + info = info, options = options, - stop = stop, + stop = stop, execute = execute ) } diff --git a/R/super-arg.R b/R/super-arg.R index c8e5f25..7d24bfd 100644 --- a/R/super-arg.R +++ b/R/super-arg.R @@ -13,7 +13,9 @@ scribe_help_super <- function() { execute = function(self, ca) { if (isTRUE(self$get_value())) { cat( - "{scribe} v", format(scribe_version()), "\n", + "{scribe} v", + format(scribe_version()), + "\n", "For more information, see https://jmbarbone.github.io/scribe/\n", sep = "" ) diff --git a/R/utils.R b/R/utils.R index 258bc37..9ed006b 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,5 +1,3 @@ - - `%||%` <- function(x, y) { # slightly different here if (is_empty(x)) y else x diff --git a/tests/spelling.R b/tests/spelling.R index 6713838..c597a12 100644 --- a/tests/spelling.R +++ b/tests/spelling.R @@ -1,3 +1,7 @@ -if(requireNamespace('spelling', quietly = TRUE)) - spelling::spell_check_test(vignettes = TRUE, error = FALSE, - skip_on_cran = TRUE) +if (requireNamespace('spelling', quietly = TRUE)) { + spelling::spell_check_test( + vignettes = TRUE, + error = FALSE, + skip_on_cran = TRUE + ) +} diff --git a/tests/testthat/test-class-command-args.R b/tests/testthat/test-class-command-args.R index 07d073f..925e424 100644 --- a/tests/testthat/test-class-command-args.R +++ b/tests/testthat/test-class-command-args.R @@ -22,7 +22,7 @@ test_that("command_args() handles defaults", { foo <- function(x = character()) { ca <- command_args(x) ca$add_argument("-a", "--alpha", default = 1L) - ca$add_argument("-b", "--beta", default = 1L) + ca$add_argument("-b", "--beta", default = 1L) ca$parse() } @@ -204,7 +204,6 @@ test_that("$get_values(empty)", { test_that("args are returned in original order [#25]", { ca <- command_args( c("-b", "one", "-c", "two", "-a", "three", "foo", "bar"), - ) ca$add_argument("...") ca$add_argument("-a", default = "zero") @@ -217,18 +216,18 @@ test_that("args are returned in original order [#25]", { test_that("default values", { ca <- command_args(c("1", "2.0", "3", "4.0")) - ca$add_argument("one", default = 0L) - ca$add_argument("two", default = 0) + ca$add_argument("one", default = 0L) + ca$add_argument("two", default = 0) ca$add_argument("three", default = 0) - ca$add_argument("four", default = 0L) - ca$add_argument("five", default = 0) + ca$add_argument("four", default = 0L) + ca$add_argument("five", default = 0) obj <- ca$parse() exp <- list( - one = 1L, - two = 2, + one = 1L, + two = 2, three = 3, - four = 4L, - five = 0 + four = 4L, + five = 0 ) expect_identical(obj, exp) From 8c287d4670bed4a1e471d635361fd7cf0be9bb4c Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:04:08 -0400 Subject: [PATCH 2/6] Update class-command-args.md --- tests/testthat/_snaps/class-command-args.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/_snaps/class-command-args.md b/tests/testthat/_snaps/class-command-args.md index b1d69d0..912d7fd 100644 --- a/tests/testthat/_snaps/class-command-args.md +++ b/tests/testthat/_snaps/class-command-args.md @@ -194,7 +194,7 @@ Code command_args("---help")$parse() Output - {scribe} v0.3.0.9002 + {scribe} v0.3.0.9003 For more information, see https://jmbarbone.github.io/scribe/ named list() @@ -203,6 +203,6 @@ Code command_args("---version")$parse() Output - 0.3.0.9002 + 0.3.0.9003 named list() From 6ce1969e66d52c750c00ea66a2dd022dcce4d26d Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:04:14 -0400 Subject: [PATCH 3/6] quietly loads --- tests/testthat/scripts/help.R | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/testthat/scripts/help.R b/tests/testthat/scripts/help.R index 21b8160..74f22f3 100755 --- a/tests/testthat/scripts/help.R +++ b/tests/testthat/scripts/help.R @@ -1,9 +1,12 @@ #!/usr/bin/Rscript --vanilla -if (!require( - scribe, - lib.loc = Sys.getenv("R_LIBS_SCRIBE", "~/R/scribe-library") -)) { +if ( + !require( + scribe, + lib.loc = Sys.getenv("R_LIBS_SCRIBE", "~/R/scribe-library"), + quietly = TRUE + ) +) { warning("expected {scribe} to be installed at R_LIBS_SCRIBE") library(scribe) } From 8ed338833df5dd9db27bbea3bc5445bf261dd576 Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:04:21 -0400 Subject: [PATCH 4/6] updates test --- tests/testthat/test-scripts.R | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-scripts.R b/tests/testthat/test-scripts.R index 6966609..c7ef681 100644 --- a/tests/testthat/test-scripts.R +++ b/tests/testthat/test-scripts.R @@ -23,13 +23,19 @@ test_that("help works", { " -b, --bar [ARG] ", NULL ) - expect_identical(obj, exp) + expect_identical( + trimws(obj), + trimws(exp), + info = sprintf( + "Maybe try: pak::pak(lib = \"%s\")", + Sys.getenv("R_LIBS_SCRIBE", "~/R/scribe-library") + ) + ) }) test_that("help works", { skip_on_cran() skip_on_ci() - obj <- system2(path, "--version", stdout = TRUE) - exp <- utils::capture.output(print_scribe_version()) - expect_identical(obj, exp) + obj <- system2(path, "---version", stdout = TRUE) + expect_identical(obj, format(scribe_version())) }) From 2e843ae938188601536bf6074ad066120ec67152 Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:04:27 -0400 Subject: [PATCH 5/6] bumps version --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 17e1641..a1dc09a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: scribe Title: Command Argument Parsing -Version: 0.3.0.9002 +Version: 0.3.0.9003 Authors@R: person( given = "Jordan Mark", @@ -16,7 +16,7 @@ License: MIT + file LICENSE Encoding: UTF-8 Language: en-US Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.3 Depends: R (>= 3.6) Imports: From 0a4b826a3a894fd1df14925fb9336135a30770d2 Mon Sep 17 00:00:00 2001 From: Jordan Mark Barbone Date: Sun, 19 Apr 2026 22:08:25 -0400 Subject: [PATCH 6/6] updates actions --- .github/workflows/R-CMD-check.yaml | 8 +++++--- .github/workflows/lint.yaml | 7 ++++--- .github/workflows/pkgdown.yaml | 11 +++++++---- .github/workflows/test-coverage.yaml | 28 ++++++++++++++++++++-------- README.Rmd | 1 + README.md | 6 ++++-- 6 files changed, 41 insertions(+), 20 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index a3ac618..562fe0f 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -4,9 +4,10 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] -name: R-CMD-check +name: R-CMD-check.yaml + +permissions: read-all jobs: R-CMD-check: @@ -29,7 +30,7 @@ jobs: R_KEEP_PKG_SOURCE: yes steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-pandoc@v2 @@ -47,3 +48,4 @@ jobs: - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true + build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index f4c4ef2..e87d167 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -4,9 +4,10 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] -name: lint +name: lint.yaml + +permissions: read-all jobs: lint: @@ -14,7 +15,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 087f0b0..bfc9f4d 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -4,12 +4,13 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] release: types: [published] workflow_dispatch: -name: pkgdown +name: pkgdown.yaml + +permissions: read-all jobs: pkgdown: @@ -19,8 +20,10 @@ jobs: group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-pandoc@v2 @@ -39,7 +42,7 @@ jobs: - name: Deploy to GitHub pages 🚀 if: github.event_name != 'pull_request' - uses: JamesIves/github-pages-deploy-action@v4.4.1 + uses: JamesIves/github-pages-deploy-action@v4.5.0 with: clean: false branch: gh-pages diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 2c5bb50..0ab748d 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -4,9 +4,10 @@ on: push: branches: [main, master] pull_request: - branches: [main, master] -name: test-coverage +name: test-coverage.yaml + +permissions: read-all jobs: test-coverage: @@ -15,7 +16,7 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: @@ -23,28 +24,39 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::covr + extra-packages: any::covr, any::xml2 needs: coverage - name: Test coverage run: | - covr::codecov( + cov <- covr::package_coverage( quiet = FALSE, clean = FALSE, - install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") ) + print(cov) + covr::to_cobertura(cov) shell: Rscript {0} + - uses: codecov/codecov-action@v5 + with: + # Fail if error if not on PR, or if on PR and token is given + fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} + files: ./cobertura.xml + plugins: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: Show testthat output if: always() run: | ## -------------------------------------------------------------------- - find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true shell: bash - name: Upload test results if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-test-failures path: ${{ runner.temp }}/package diff --git a/README.Rmd b/README.Rmd index da4231f..7b26bfd 100644 --- a/README.Rmd +++ b/README.Rmd @@ -21,6 +21,7 @@ knitr::opts_chunk$set( [![R-CMD-check](https://github.com/jmbarbone/scribe/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/jmbarbone/scribe/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/jmbarbone/scribe/branch/main/graph/badge.svg)](https://app.codecov.io/gh/jmbarbone/scribe?branch=main) +[![Codecov test coverage](https://codecov.io/gh/jmbarbone/scribe/graph/badge.svg)](https://app.codecov.io/gh/jmbarbone/scribe) The goal of scribe is to provide a detailed argument parser for `Rscript`. diff --git a/README.md b/README.md index a75199f..e565fdd 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ [![R-CMD-check](https://github.com/jmbarbone/scribe/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/jmbarbone/scribe/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/jmbarbone/scribe/branch/main/graph/badge.svg)](https://app.codecov.io/gh/jmbarbone/scribe?branch=main) +[![Codecov test +coverage](https://codecov.io/gh/jmbarbone/scribe/graph/badge.svg)](https://app.codecov.io/gh/jmbarbone/scribe) The goal of scribe is to provide a detailed argument parser for @@ -68,7 +70,7 @@ ca$parse() #> [1] TRUE #> #> $... -#> integer(0) +#> [1] 1 1 1 # use functions for more control ca <- command_args(c("verbose", "12-9-2022", "12-10-2022")) @@ -79,7 +81,7 @@ ca$parse() #> [1] TRUE #> #> $... -#> Date of length 0 +#> [1] "2022-12-09" "2022-12-10" ``` You’ll probably use `{scribe}` within small scripts that can be called