From 8f56e45600545b02c7f4d90d36c9a8cc77624765 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Fri, 1 May 2026 08:23:46 -0700 Subject: [PATCH 1/7] optionals with new_union default to NULL --- R/00_S7_properties.R | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/R/00_S7_properties.R b/R/00_S7_properties.R index 1b3bcc5..4491b3d 100644 --- a/R/00_S7_properties.R +++ b/R/00_S7_properties.R @@ -50,8 +50,7 @@ character_scalar <- new_property( #' @author EDG #' @export optional_character_scalar <- new_property( - class = new_union(class_character, NULL), - default = NULL, + class = new_union(NULL, class_character), validator = function(value) { if ( !is.null(value) && @@ -91,8 +90,7 @@ double_scalar <- new_property( #' @author EDG #' @export optional_double_scalar <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if (!is.null(value) && (length(value) != 1L || is.na(value))) { return("must be NULL or a double scalar") @@ -129,8 +127,7 @@ integer_scalar <- new_property( #' @author EDG #' @export optional_integer_scalar <- new_property( - class = new_union(class_integer, NULL), - default = NULL, + class = new_union(NULL, class_integer), validator = function(value) { if (!is.null(value) && (length(value) != 1L || is.na(value))) { return("must be NULL or an integer scalar (e.g. 1L)") @@ -166,8 +163,7 @@ pos_integer_scalar <- new_property( #' @author EDG #' @export optional_pos_integer_scalar <- new_property( - class = new_union(class_integer, NULL), - default = NULL, + class = new_union(NULL, class_integer), validator = function(value) { if ( !is.null(value) && (length(value) != 1L || is.na(value) || value <= 0L) @@ -206,8 +202,7 @@ logical_scalar <- new_property( #' @author EDG #' @export optional_logical_scalar <- new_property( - class = new_union(class_logical, NULL), - default = NULL, + class = new_union(NULL, class_logical), validator = function(value) { if (!is.null(value) && (length(value) != 1L || is.na(value))) { return("must be NULL or a logical scalar (TRUE or FALSE)") @@ -244,8 +239,7 @@ prob_scalar <- new_property( #' @author EDG #' @export optional_prob_scalar <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if ( !is.null(value) && @@ -284,8 +278,7 @@ unit_open_scalar <- new_property( #' @author EDG #' @export optional_unit_open_scalar <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if ( !is.null(value) && @@ -326,8 +319,7 @@ pos_double_scalar <- new_property( #' @author EDG #' @export optional_pos_double_scalar <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if ( !is.null(value) && @@ -366,8 +358,7 @@ nonneg_double_scalar <- new_property( #' @author EDG #' @export optional_nonneg_double_scalar <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if ( !is.null(value) && @@ -414,8 +405,7 @@ prob_vector <- new_property( #' @author EDG #' @export optional_prob_vector <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if (is.null(value)) { return(NULL) @@ -468,8 +458,7 @@ unit_open_vector <- new_property( #' @author EDG #' @export optional_unit_open_vector <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if (is.null(value)) { return(NULL) @@ -522,8 +511,7 @@ pos_double_vector <- new_property( #' @author EDG #' @export optional_pos_double_vector <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if (is.null(value)) { return(NULL) @@ -576,8 +564,7 @@ nonneg_double_vector <- new_property( #' @author EDG #' @export optional_nonneg_double_vector <- new_property( - class = new_union(class_double, NULL), - default = NULL, + class = new_union(NULL, class_double), validator = function(value) { if (is.null(value)) { return(NULL) @@ -651,7 +638,7 @@ bounded_double_property <- function( new_property( class = cls, validator = function(value) { - if (is.null(value)) { + if (nullable && is.null(value)) { return(NULL) } if (length(value) != 1L || is.na(value) || !is.finite(value)) { @@ -686,7 +673,7 @@ enum <- function(values, default = NULL, nullable = FALSE) { new_property( class = cls, validator = function(value) { - if (is.null(value)) { + if (nullable && is.null(value)) { return(NULL) } if (length(value) != 1L || is.na(value)) { From 5ac5638cd68de6ba733765cfb130c49a7de26354 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Fri, 1 May 2026 08:23:49 -0700 Subject: [PATCH 2/7] add specs --- .Rbuildignore | 1 + .gitignore | 1 + 2 files changed, 2 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index bc6f5c2..1cfd486 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,6 +1,7 @@ ^__dev$ ^\.github$ ^.*\.code-workspace$ +^specs$ ^AGENTS\.md$ ^CLAUDE\.md$ ^Makefile$ diff --git a/.gitignore b/.gitignore index 06031de..f22600b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Dev __dev/ Makefile +specs/ # macOS .DS_Store From 0a1ec0f9276130b01a2a4b2ce1e9aabb137ca0de Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Fri, 1 May 2026 09:22:06 -0700 Subject: [PATCH 3/7] default to NULL --- R/00_S7_properties.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/00_S7_properties.R b/R/00_S7_properties.R index 4491b3d..d0f6965 100644 --- a/R/00_S7_properties.R +++ b/R/00_S7_properties.R @@ -633,7 +633,7 @@ bounded_double_property <- function( function(v) v <= upper } - cls <- if (nullable) new_union(class_double, NULL) else class_double + cls <- if (nullable) new_union(NULL, class_double) else class_double new_property( class = cls, @@ -669,7 +669,7 @@ bounded_double_property <- function( #' @examples #' type_prop <- enum(c("string", "number", "boolean"), default = "string") enum <- function(values, default = NULL, nullable = FALSE) { - cls <- if (nullable) new_union(class_character, NULL) else class_character + cls <- if (nullable) new_union(NULL, class_character) else class_character new_property( class = cls, validator = function(value) { @@ -714,5 +714,5 @@ optional <- function(type) { "{.var type} must be an S7 base class or S7 class." ) } - S7::new_union(type, NULL) + S7::new_union(NULL, type) } From f83948c6dbf067c58199c24877f6ee17e66e4d07 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Sun, 3 May 2026 20:35:49 -0700 Subject: [PATCH 4/7] ignore revdep --- .Rbuildignore | 1 + .gitignore | 1 + 2 files changed, 2 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index 1cfd486..fbe1c0b 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,6 +1,7 @@ ^__dev$ ^\.github$ ^.*\.code-workspace$ +^revdep$ ^specs$ ^AGENTS\.md$ ^CLAUDE\.md$ diff --git a/.gitignore b/.gitignore index f22600b..2abb4bc 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ specs/ # R *.Rcheck/ *.tar.gz +revdep/ # Agents .claude/ From 64f692e73e6f0950d3699c0609f21de365de5bf7 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Wed, 6 May 2026 03:19:23 -0700 Subject: [PATCH 5/7] ignore cran-comments.md --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2abb4bc..f3b523d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ specs/ *.Rcheck/ *.tar.gz revdep/ +cran-comments.md # Agents .claude/ From 429ad9e69256d7594a653588c3279a050c3d2433 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Wed, 6 May 2026 03:19:30 -0700 Subject: [PATCH 6/7] add rhub.yaml --- .github/workflows/rhub.yaml | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 .github/workflows/rhub.yaml diff --git a/.github/workflows/rhub.yaml b/.github/workflows/rhub.yaml new file mode 100644 index 0000000..74ec7b0 --- /dev/null +++ b/.github/workflows/rhub.yaml @@ -0,0 +1,95 @@ +# R-hub's generic GitHub Actions workflow file. It's canonical location is at +# https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml +# You can update this file to a newer version using the rhub2 package: +# +# rhub::rhub_setup() +# +# It is unlikely that you need to modify this file manually. + +name: R-hub +run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" + +on: + workflow_dispatch: + inputs: + config: + description: 'A comma separated list of R-hub platforms to use.' + type: string + default: 'linux,windows,macos' + name: + description: 'Run name. You can leave this empty now.' + type: string + id: + description: 'Unique ID. You can leave this empty now.' + type: string + +jobs: + + setup: + runs-on: ubuntu-latest + outputs: + containers: ${{ steps.rhub-setup.outputs.containers }} + platforms: ${{ steps.rhub-setup.outputs.platforms }} + + steps: + # NO NEED TO CHECKOUT HERE + - uses: r-hub/actions/setup@v1 + with: + config: ${{ github.event.inputs.config }} + id: rhub-setup + + linux-containers: + needs: setup + if: ${{ needs.setup.outputs.containers != '[]' }} + runs-on: ubuntu-latest + name: ${{ matrix.config.label }} + strategy: + fail-fast: false + matrix: + config: ${{ fromJson(needs.setup.outputs.containers) }} + container: + image: ${{ matrix.config.container }} + + steps: + - uses: r-hub/actions/checkout@v1 + - uses: r-hub/actions/platform-info@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/setup-deps@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/run-check@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + + other-platforms: + needs: setup + if: ${{ needs.setup.outputs.platforms != '[]' }} + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.label }} + strategy: + fail-fast: false + matrix: + config: ${{ fromJson(needs.setup.outputs.platforms) }} + + steps: + - uses: r-hub/actions/checkout@v1 + - uses: r-hub/actions/setup-r@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} + - uses: r-hub/actions/platform-info@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/setup-deps@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} + - uses: r-hub/actions/run-check@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} From edbcdd63b26d50fcfe3570ec1a79e28c55663757 Mon Sep 17 00:00:00 2001 From: Stathis Gennatas Date: Wed, 6 May 2026 03:20:51 -0700 Subject: [PATCH 7/7] ignore cran-comments.md --- .Rbuildignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index fbe1c0b..3a59263 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,4 +6,5 @@ ^AGENTS\.md$ ^CLAUDE\.md$ ^Makefile$ -^SKILL\.md$ \ No newline at end of file +^SKILL\.md$ +^cran-comments\.md$ \ No newline at end of file