Skip to content

Commit

Permalink
Merge pull request #4 from parmsam/sam-dev
Browse files Browse the repository at this point in the history
Simplify R-CMD-check workflow
  • Loading branch information
parmsam authored Apr 12, 2024
2 parents aa91082 + 7d63030 commit 7a62779
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 240 deletions.
227 changes: 24 additions & 203 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
@@ -1,229 +1,50 @@
# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
on:
workflow_call:
inputs:
extra-packages:
type: string
default: ""
required: false
cache-version:
type: string
default: "2"
required: false
pandoc-version:
type: string
default: "3.x"
required: false
extra-check-args:
type: string
# default: '"--run-donttest", "--no-manual", "--as-cran"'
default: "NULL"
required: false
macOS:
type: string
default: "macOS-latest"
required: false
windows:
type: string
default: "windows-latest"
required: false
ubuntu:
type: string
required: false
# To test more versions, they must be separated by a space. Ex: `"ubuntu-18.04 ubuntu-20.04`
default: "ubuntu-20.04"
minimum-r-version:
type: string
required: false
default: ""
force-windows-src:
type: boolean
required: false
default: false
rtools-35:
type: boolean
default: true
required: false
rtools-40:
type: boolean
default: true
required: false
push:
branches: [main, master]
pull_request:
branches: [main, master]

name: R-CMD-check

jobs:
setup:
name: setup
runs-on: ubuntu-latest
outputs:
config: ${{ steps.config.outputs.config }}
steps:
# - name: devel
# id: devel
# uses: r-lib/actions/setup-r@v2
# with:
# r-version: devel
# install-r: false

- name: release
id: release
uses: r-lib/actions/setup-r@v2
with:
r-version: release
install-r: false

- name: oldrel-1
id: oldrel-1
uses: r-lib/actions/setup-r@v2
with:
r-version: oldrel-1
install-r: false

- name: oldrel-2
id: oldrel-2
uses: r-lib/actions/setup-r@v2
with:
r-version: oldrel-2
install-r: false

- name: oldrel-3
id: oldrel-3
uses: r-lib/actions/setup-r@v2
with:
r-version: oldrel-3
install-r: false

- name: oldrel-4
id: oldrel-4
uses: r-lib/actions/setup-r@v2
with:
r-version: oldrel-4
install-r: false

- name: Checkout GitHub repo
uses: rstudio/shiny-workflows/.github/internal/checkout@v1

# R is a pre-installed software
- name: Config
id: config
shell: Rscript {0}
run: |
mac <- "${{ inputs.macOS }}"
windows <- "${{ inputs.windows }}"
ubuntu <- strsplit("${{ inputs.ubuntu }}", "[[:space:],]+")[[1]]
has_src <- dir.exists("src")
min_r_ver <- "${{ inputs.minimum-r-version }}"
test_on_rtools35 <- identical("${{ inputs.rtools-35 }}", "true")
test_on_rtools40 <- identical("${{ inputs.rtools-40 }}", "true")
force_windows_src <- identical("${{ inputs.force-windows-src }}", "true")
if (force_windows_src) has_src <- TRUE
rver <- list(
# devel = "${{ steps.devel.outputs.installed-r-version }}",
# When R 4.3 was released, R version 4.4.0 was not recognized.
# However, `"devel"` is recognized within `r-lib/actions/setup-r`.
devel = "devel",
release = "${{ steps.release.outputs.installed-r-version }}",
oldrel1 = "${{ steps.oldrel-1.outputs.installed-r-version }}",
oldrel2 = "${{ steps.oldrel-2.outputs.installed-r-version }}",
oldrel3 = "${{ steps.oldrel-3.outputs.installed-r-version }}",
oldrel4 = "${{ steps.oldrel-4.outputs.installed-r-version }}"
)
job <- function(os, r, ...) {
list(os = os, r = r, ...)
}
is_valid_os <- function(os, r_ver = "") {
if (identical(os, "false")) return(FALSE)
if (identical(os, "")) return(FALSE)
if (any(nchar(c(r_ver, min_r_ver)) == 0)) return(TRUE)
if (identical(r_ver, "devel")) return(TRUE)
r_ver >= min_r_ver
}
config <- c(
list(
if (is_valid_os(mac, rver$release)) job(mac, rver$release),
if (has_src && is_valid_os(windows, "devel")) job(windows, "devel", "rtools-version" = "44"),
if (is_valid_os(windows, rver$release)) job(windows, rver$release, "rtools-version" = "43"),
if (has_src && is_valid_os(windows, "4.2")) job(windows, "4.2", "rtools-version" = "42"),
if (has_src && test_on_rtools40 && is_valid_os(windows, "4.1")) job(windows, "4.1"),
if (has_src && test_on_rtools35 && is_valid_os(windows, "3.6")) job(windows, "3.6"),
if (is_valid_os(ubuntu, rver$devel)) job(ubuntu[[1]], rver$devel, "http-user-agent" = "release")
),
if (is_valid_os(ubuntu))
unlist(recursive = FALSE, lapply(ubuntu, function(ubuntu_) {
list(
if (is_valid_os(ubuntu_, rver$release)) job(ubuntu_, rver$release),
if (is_valid_os(ubuntu_, rver$oldrel1)) job(ubuntu_, rver$oldrel1),
if (is_valid_os(ubuntu_, rver$oldrel2)) job(ubuntu_, rver$oldrel2),
if (is_valid_os(ubuntu_, rver$oldrel3)) job(ubuntu_, rver$oldrel3),
if (is_valid_os(ubuntu_, rver$oldrel4)) job(ubuntu_, rver$oldrel4)
)
}))
)
## Drop NULLs
config <- config[!vapply(config, is.null, logical(1))]
## Convert to JSON manually to save 10s installing `jsonlite`
join_and_wrap <- function(x, start, end, sep = ",") {
paste0(start, paste0(x, collapse = sep), end)
}
entries_json <- vapply(config, character(1), FUN = function(entry) {
join_and_wrap(
paste0("\"", names(entry), "\":\"", unname(entry), "\""),
"{", "}"
)
})
config_json <- join_and_wrap(entries_json, "[", "]")
cat("Config:\n", config_json, "\n", sep = "")
cat("config=", config_json, "\n", file = Sys.getenv("GITHUB_OUTPUT"), sep = "", append = TRUE)
R-CMD-check:
runs-on: ${{ matrix.config.os }}

name: ${{ matrix.config.os }} (${{ matrix.config.r }})

needs: [setup]
strategy:
fail-fast: false
matrix:
config: ${{ fromJSON(needs.setup.outputs.config) }}
config:
- {os: macos-latest, r: 'release'}
- {os: windows-latest, r: 'release'}
- {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
- {os: ubuntu-latest, r: 'release'}
- {os: ubuntu-latest, r: 'oldrel-1'}

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
R_KEEP_PKG_SOURCE: yes

steps:
- name: Checkout GitHub repo
uses: rstudio/shiny-workflows/.github/internal/checkout@v1
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-pandoc@v2

- name: Install R, system dependencies, and package dependencies
uses: rstudio/shiny-workflows/setup-r-package@v1
- uses: r-lib/actions/setup-r@v2
with:
rtools-version: ${{ matrix.config.rtools-version }}
pandoc-version: ${{ inputs.pandoc-version }}
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
cache-version: ${{ inputs.cache-version }}
needs: check
extra-packages: |
any::rcmdcheck
${{ inputs.extra-packages }}
use-public-rspm: true

- name: Check package
uses: r-lib/actions/check-r-package@v2
timeout-minutes: 30
- uses: r-lib/actions/setup-r-dependencies@v2
with:
check-dir: '"check"' # matches directory below
args: 'c(${{ inputs.extra-check-args }}, "--no-manual", "--as-cran")'
extra-packages: any::rcmdcheck
needs: check

- name: "Show `testthat` output"
if: always()
run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true
shell: bash
- name: "Show install logs"
if: always()
run: find check -name '00install.out' -exec cat '{}' \; || true
shell: bash
- name: "Upload 'Check package' results"
if: failure()
uses: actions/upload-artifact@main
- uses: r-lib/actions/check-r-package@v2
with:
name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results
path: "check"
upload-snapshots: true
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
7 changes: 5 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Package: lzstringr
Package: lzstring
Type: Package
Title: An R wrapper of lzstring C++ library
Version: 0.1.0
Author: Sam Parmar
Maintainer: Sam Parmar <[email protected]>
Description: An R wrapper of LZ-based compression algorithm implemented in C++
Description: This package provides an R interface to the lz-string C++ library,
enabling LZ-based compression and decompression of strings directly within
R. This can be particularly useful for reducing the memory footprint of
large strings or for transmitting compressed data.
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
YEAR: 2024
COPYRIGHT HOLDER: lzstringr authors
COPYRIGHT HOLDER: lzstring authors
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License

Copyright (c) 2024 lzstringr authors
Copyright (c) 2024 lzstring authors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export(compressToBase64)
export(compressToEncodedURIComponent)
export(decompressFromBase64)
export(decompressFromEncodedURIComponent)
useDynLib(lzstringr, .registration = TRUE)
useDynLib(lzstring, .registration = TRUE)
8 changes: 4 additions & 4 deletions R/cpp11.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Generated by cpp11: do not edit by hand

compressToEncodedURIComponent_ <- function(bytes) {
.Call(`_lzstringr_compressToEncodedURIComponent_`, bytes)
.Call(`_lzstring_compressToEncodedURIComponent_`, bytes)
}

decompressFromEncodedURIComponent_ <- function(bytes) {
.Call(`_lzstringr_decompressFromEncodedURIComponent_`, bytes)
.Call(`_lzstring_decompressFromEncodedURIComponent_`, bytes)
}

compressToBase64_ <- function(bytes) {
.Call(`_lzstringr_compressToBase64_`, bytes)
.Call(`_lzstring_compressToBase64_`, bytes)
}

decompressFromBase64_ <- function(bytes) {
.Call(`_lzstringr_decompressFromBase64_`, bytes)
.Call(`_lzstring_decompressFromBase64_`, bytes)
}
35 changes: 32 additions & 3 deletions R/lzstringr-package.R
Original file line number Diff line number Diff line change
@@ -1,21 +1,50 @@
## usethis namespace: start
#' @useDynLib lzstringr, .registration = TRUE
#' @useDynLib lzstring, .registration = TRUE
## usethis namespace: end
NULL

decode_utf16_surrogate <- function(values) {
# Initialize an empty character vector to store decoded characters
decoded_chars <- character()
# Function to decode surrogate pairs
decode_surrogates <- function(high, low) {
# Calculate the Unicode code point from surrogate values
# Formula: 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00)
code_point <- 0x10000 + (high - 0xD800) * 0x400 + (low - 0xDC00)
# Convert the Unicode code point to a character
intToUtf8(code_point)
}
i <- 1
while (i <= length(values)) {
if (values[i] < 0xD800 || values[i] > 0xDBFF) { # Not a high surrogate
# Direct conversion for regular characters (like space)
decoded_chars <- c(decoded_chars, intToUtf8(values[i]))
i <- i + 1
} else {
# Decode surrogate pairs
decoded_chars <- c(decoded_chars, decode_surrogates(values[i], values[i + 1]))
i <- i + 2
}
}
# Combine into a single string
paste(decoded_chars, collapse = "")
}

safe_compress <- function(string, f) {
string <- enc2utf8(string)
string <- iconv(string, from="UTF-8", to="UTF-16", toRaw=TRUE)[[1]]
result <- f(string)
chr_result <- rawToChar(as.raw(result))
chr_result <- decode_utf16_surrogate(result)
Encoding(chr_result) <- "UTF-8"
chr_result
}

safe_decompress <- function(string, f) {
string <- enc2utf8(string)
string <- iconv(string, from="UTF-8", to="UTF-16", toRaw=TRUE)[[1]]
result <- f(string)
chr_result <- intToUtf8(result)
chr_result <- decode_utf16_surrogate(result)
Encoding(chr_result) <- "UTF-8"
chr_result
}

Expand Down
Loading

0 comments on commit 7a62779

Please sign in to comment.